From 0e8c4fb381ef4d41ceb948fc408f4b52ab5f545d Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 19 Nov 2024 16:30:04 +0100 Subject: [PATCH 001/634] WIP class skeleton --- .../html-api/class-wp-css-selector.php | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/wp-includes/html-api/class-wp-css-selector.php diff --git a/src/wp-includes/html-api/class-wp-css-selector.php b/src/wp-includes/html-api/class-wp-css-selector.php new file mode 100644 index 0000000000000..7ec6b5a69ced2 --- /dev/null +++ b/src/wp-includes/html-api/class-wp-css-selector.php @@ -0,0 +1,31 @@ + Date: Wed, 20 Nov 2024 16:57:19 +0100 Subject: [PATCH 002/634] Document class --- .../html-api/class-wp-css-selector.php | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/html-api/class-wp-css-selector.php b/src/wp-includes/html-api/class-wp-css-selector.php index 7ec6b5a69ced2..1684aefef2024 100644 --- a/src/wp-includes/html-api/class-wp-css-selector.php +++ b/src/wp-includes/html-api/class-wp-css-selector.php @@ -12,20 +12,47 @@ * * This class is designed for internal use by the HTML processor. * + * This class is instantiated via the `WP_CSS_Selector::from_selector( string $selector )` method. + * It accepts a CSS selector string and returns an instance of itself or `null` if the selector + * is invalid or unsupported. + * + * A subset of the CSS selector grammar is supported. The grammar is defined in the CSS Syntax + * specification, which is available at https://www.w3.org/TR/css-syntax-3/. + * + * Supported selector syntax: + * - Type selectors (tag names, e.g. `div`) + * - Class selectors (e.g. `.class-name`) + * - ID selectors (e.g. `#unique-id`) + * - Attribute selectors (e.g. `[attribute-name]` or `[attribute-name="value"]`) + * - The following combinators: + * - descendant (e.g. `.parent .descendant`) + * - child (`.parent > .child`) + * - Comma-separated selector lists (e.g. `.selector-1, .selector-2`) + * + * Unsupported selector syntax: + * - The following combinators: + * - Next sibling (`.sibling + .sibling`) + * - Subsequent sibling (`.sibling ~ .sibling`) + * - Pseudo-element selectors (e.g. `::before`) + * - Pseudo-class selectors (e.g. `:hover` or `:nth-child(2)`) + * * @since TBD * * @access private * + * @see https://www.w3.org/TR/css-syntax-3/#consume-a-token * @see https://www.w3.org/tr/selectors/#parse-selector + * */ class WP_CSS_Selector { private function __construct() {} /** - * @return static + * @return static|null */ public static function from_selector( string $selector ) { $res = new static(); return $res; } + } From 40222d30200afdf998586cb127c35c880bfe7df8 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 21 Nov 2024 11:57:28 +0100 Subject: [PATCH 003/634] Do not support namespaced selectors --- src/wp-includes/html-api/class-wp-css-selector.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wp-includes/html-api/class-wp-css-selector.php b/src/wp-includes/html-api/class-wp-css-selector.php index 1684aefef2024..fb8934bec06f4 100644 --- a/src/wp-includes/html-api/class-wp-css-selector.php +++ b/src/wp-includes/html-api/class-wp-css-selector.php @@ -35,6 +35,7 @@ * - Subsequent sibling (`.sibling ~ .sibling`) * - Pseudo-element selectors (e.g. `::before`) * - Pseudo-class selectors (e.g. `:hover` or `:nth-child(2)`) + * - Namespace prefixes that need to be resolved (e.g. `svg|title` or `[xlink|href]`) * * @since TBD * From 60926421295e58229637891c853ab50f0920ae23 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 22 Nov 2024 16:04:42 +0100 Subject: [PATCH 004/634] Flesh out stuff --- .../html-api/class-wp-css-selector.php | 59 ----- .../html-api/class-wp-css-selectors.php | 248 ++++++++++++++++++ 2 files changed, 248 insertions(+), 59 deletions(-) delete mode 100644 src/wp-includes/html-api/class-wp-css-selector.php create mode 100644 src/wp-includes/html-api/class-wp-css-selectors.php diff --git a/src/wp-includes/html-api/class-wp-css-selector.php b/src/wp-includes/html-api/class-wp-css-selector.php deleted file mode 100644 index fb8934bec06f4..0000000000000 --- a/src/wp-includes/html-api/class-wp-css-selector.php +++ /dev/null @@ -1,59 +0,0 @@ - .child`) - * - Comma-separated selector lists (e.g. `.selector-1, .selector-2`) - * - * Unsupported selector syntax: - * - The following combinators: - * - Next sibling (`.sibling + .sibling`) - * - Subsequent sibling (`.sibling ~ .sibling`) - * - Pseudo-element selectors (e.g. `::before`) - * - Pseudo-class selectors (e.g. `:hover` or `:nth-child(2)`) - * - Namespace prefixes that need to be resolved (e.g. `svg|title` or `[xlink|href]`) - * - * @since TBD - * - * @access private - * - * @see https://www.w3.org/TR/css-syntax-3/#consume-a-token - * @see https://www.w3.org/tr/selectors/#parse-selector - * - */ -class WP_CSS_Selector { - private function __construct() {} - - /** - * @return static|null - */ - public static function from_selector( string $selector ) { - $res = new static(); - return $res; - } - -} diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php new file mode 100644 index 0000000000000..acc5db02752c3 --- /dev/null +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -0,0 +1,248 @@ + .child`) + * + * Unsupported selector syntax: + * - Pseudo-element selectors (e.g. `::before`) + * - Pseudo-class selectors (e.g. `:hover` or `:nth-child(2)`) + * - Namespace prefixes (e.g. `svg|title` or `[xlink|href]`) + * - The following combinators: + * - Next sibling (`.sibling + .sibling`) + * - Subsequent sibling (`.sibling ~ .sibling`) + * + * @since TBD + * + * @access private + * + * @see https://www.w3.org/TR/css-syntax-3/#consume-a-token + * @see https://www.w3.org/tr/selectors/#parse-selector + * @see https://www.w3.org/TR/selectors-api2/ + * @see https://www.w3.org/TR/selectors-4/ + * + */ +class WP_CSS_Selectors { + + /** + * Takes a CSS selectors string and returns an instance of itself or `null` if the selector + * is invalid or unsupported. + * + * @since TBD + * + * @param string $selectors CSS selectors string. + * @return static|null + */ + public static function from_selectors( string $selectors ) { + $res = new static(); + return $res; + } + + /** + * Returns a list of selectors. + * + * @since TBD + * + * @return WP_CSS_Selector[] + */ + private static function parse( string $input ) { + // > A selector string is a list of one or more complex selectors ([SELECTORS4], section 3.1) that may be surrounded by whitespace and matches the dom_selectors_group production. + $input = trim( $input, " \t\r\n\r" ); + + if ( '' === $input ) { + null; + } + + /* + * > The input stream consists of the filtered code points pushed into it as the input byte stream is decoded. + * > + * > To filter code points from a stream of (unfiltered) code points input: + * > Replace any U+000D CARRIAGE RETURN (CR) code points, U+000C FORM FEED (FF) code points, or pairs of U+000D CARRIAGE RETURN (CR) followed by U+000A LINE FEED (LF) in input by a single U+000A LINE FEED (LF) code point. + * > Replace any U+0000 NULL or surrogate code points in input with U+FFFD REPLACEMENT CHARACTER (�). + * + * https://www.w3.org/TR/css-syntax-3/#input-preprocessing + */ + $input = str_replace( array( "\r\n" ), "\n", $input ); + $input = str_replace( array( "\r", "\f" ), "\n", $input ); + $input = str_replace( "\0", "\u{FFFD}", $input ); + + $at = 0; + $length = strlen( $input ); + $selectors = array(); + + $at = strspn( $input, "\n\t ", $at ); + while ( $at < $length ) { + } + } +} + +interface IWP_CSS_Selector_Parser { + public static function parse( string $input, string $offset, ?int $consumed_bytes = null ): ?self; +} + +abstract class WP_CSS_Selector_Parser implements IWP_CSS_Selector_Parser { + public static function parse_whitespace( string $input, string &$offset ): bool { + $length = strspn( $input, " \t\r\n\f", $offset ); + $advanced = $length > 0; + $offset += $length; + return $advanced; + } + + /* + * Utiltities + * ========== + * + * The following functions do not consume any input. + */ + + /** + * > 4.3.8. Check if two code points are a valid escape + * > This section describes how to check if two code points are a valid escape. The algorithm described here can be called explicitly with two code points, or can be called with the input stream itself. In the latter case, the two code points in question are the current input code point and the next input code point, in that order. + * > + * > Note: This algorithm will not consume any additional code point. + * > + * > If the first code point is not U+005C REVERSE SOLIDUS (\), return false. + * > + * > Otherwise, if the second code point is a newline, return false. + * > + * > Otherwise, return true. + * + * https://www.w3.org/TR/css-syntax-3/#starts-with-a-valid-escape + * + * @todo this does not check whether the second codepoint is valid. + */ + public static function next_two_are_valid_escape( string $input, string $offset ): bool { + if ( $offset + 1 >= strlen( $input ) ) { + return false; + } + return '\\' === $input[ $offset ] && "\n" !== $input[ $offset + 1 ]; + } + + /** + * > ident-start code point + * > A letter, a non-ASCII code point, or U+005F LOW LINE (_). + * > uppercase letter + * > A code point between U+0041 LATIN CAPITAL LETTER A (A) and U+005A LATIN CAPITAL LETTER Z (Z) inclusive. + * > lowercase letter + * > A code point between U+0061 LATIN SMALL LETTER A (a) and U+007A LATIN SMALL LETTER Z (z) inclusive. + * > letter + * > An uppercase letter or a lowercase letter. + * > non-ASCII code point + * > A code point with a value equal to or greater than U+0080 . + */ + public static function is_ident_start_codepoint( string $input, string $offset ): bool { + if ( $offset >= strlen( $input ) ) { + return false; + } + + return ( + '_' === $input[ $offset ] || + ( 'a' <= $input[ $offset ] && $input[ $offset ] <= 'z' ) || + ( 'A' <= $input[ $offset ] && $input[ $offset ] <= 'Z' ) || + $input[ $offset ] <= '\x7F' + ); + } + + /** + * > ident code point + * > An ident-start code point, a digit, or U+002D HYPHEN-MINUS (-). + * > digit + * > A code point between U+0030 DIGIT ZERO (0) and U+0039 DIGIT NINE (9) inclusive. + */ + public static function is_ident_codepoint( string $input, string $offset ): bool { + return '-' === $input[ $offset ] || + ( '0' <= $input[ $offset ] && $input[ $offset ] <= '9' ) || + self::is_ident_start_codepoint( $input, $offset ); + } + + /** + * > 4.3.9. Check if three code points would start an ident sequence + * > This section describes how to check if three code points would start an ident sequence. The algorithm described here can be called explicitly with three code points, or can be called with the input stream itself. In the latter case, the three code points in question are the current input code point and the next two input code points, in that order. + * > + * > Note: This algorithm will not consume any additional code points. + * > + * > Look at the first code point: + * > + * > U+002D HYPHEN-MINUS + * > If the second code point is an ident-start code point or a U+002D HYPHEN-MINUS, or the second and third code points are a valid escape, return true. Otherwise, return false. + * > ident-start code point + * > Return true. + * > U+005C REVERSE SOLIDUS (\) + * > If the first and second code points are a valid escape, return true. Otherwise, return false. + * > anything else + * > Return false. + * + * https://www.w3.org/TR/css-syntax-3/#would-start-an-identifier + */ + public static function check_if_three_code_points_would_start_an_ident_sequence( string $input, string $offset ): bool { + if ( $offset >= strlen( $input ) ) { + return false; + } + + // > U+005C REVERSE SOLIDUS (\) + if ( '\\' === $input[ $offset ] ) { + return self::next_two_are_valid_escape( $input, $offset ); + } + + // > U+002D HYPHEN-MINUS + if ( '-' === $input[ $offset ] ) { + $after_initial_hyphen_minus_offset = $offset + 1; + if ( $offset >= strlen( $input ) ) { + return false; + } + + // > If the second code point is… U+002D HYPHEN-MINUS… return true + if ( '-' === $input[ $after_initial_hyphen_minus_offset ] ) { + return true; + } + + // > If the second and third code points are a valid escape, return true. + if ( self::next_two_are_valid_escape( $input, $after_initial_hyphen_minus_offset ) ) { + return true; + } + + // > If the second code point is an ident-start code point… return true. + if ( self::is_ident_start_codepoint( $input, $after_initial_hyphen_minus_offset ) ) { + return true; + } + + // > Otherwise, return false. + return false; + } + + // > ident-start code point + // > Return true. + // > anything else + // > Return false. + return self::is_ident_start_codepoint( $input, $offset ); + } +} From 3e3b2b200696d9e5f51c29f86f8ec48a20df1bf4 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 22 Nov 2024 17:06:20 +0100 Subject: [PATCH 005/634] Starting to actually parse --- .../html-api/class-wp-css-selectors.php | 213 ++++++++++++++++-- 1 file changed, 199 insertions(+), 14 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index acc5db02752c3..53417a0f1967c 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -52,6 +52,11 @@ * */ class WP_CSS_Selectors { + private $selectors; + + private function __construct( array $selectors ) { + $this->selectors = $selectors; + } /** * Takes a CSS selectors string and returns an instance of itself or `null` if the selector @@ -60,11 +65,10 @@ class WP_CSS_Selectors { * @since TBD * * @param string $selectors CSS selectors string. - * @return static|null + * @return self|null */ - public static function from_selectors( string $selectors ) { - $res = new static(); - return $res; + public static function from_selectors( string $selectors ): ?self { + return self::parse( $selectors ); } /** @@ -72,7 +76,7 @@ public static function from_selectors( string $selectors ) { * * @since TBD * - * @return WP_CSS_Selector[] + * @return WP_CSS_Selectors|null */ private static function parse( string $input ) { // > A selector string is a list of one or more complex selectors ([SELECTORS4], section 3.1) that may be surrounded by whitespace and matches the dom_selectors_group production. @@ -95,28 +99,209 @@ private static function parse( string $input ) { $input = str_replace( array( "\r", "\f" ), "\n", $input ); $input = str_replace( "\0", "\u{FFFD}", $input ); - $at = 0; $length = strlen( $input ); $selectors = array(); - $at = strspn( $input, "\n\t ", $at ); - while ( $at < $length ) { + $offset = 0; + + while ( $offset < $length ) { + $sel = WP_CSS_ID_Selector::parse( $input, $offset ); + if ( $sel ) { + $selectors[] = $sel; + } + } + if ( count( $selectors ) ) { + return new WP_CSS_Selectors( $selectors ); + } + return null; + } +} + +final class WP_CSS_ID_Selector extends WP_CSS_Selector_Parser { + /** @var string */ + public $ident; + + private function __construct( string $ident ) { + $this->ident = $ident; + } + + public static function parse( string $input, string &$offset ): ?self { + $ident = self::parse_hash_token( $input, $offset ); + if ( null === $ident ) { + return null; } + return new self( $ident ); } } interface IWP_CSS_Selector_Parser { - public static function parse( string $input, string $offset, ?int $consumed_bytes = null ): ?self; + /** + * @return static|null + */ + public static function parse( string $input, string &$offset ); } abstract class WP_CSS_Selector_Parser implements IWP_CSS_Selector_Parser { - public static function parse_whitespace( string $input, string &$offset ): bool { + const UTF8_MAX_CODEPOINT_VALUE = 0x10FFFF; + + protected static function parse_whitespace( string $input, string &$offset ): bool { $length = strspn( $input, " \t\r\n\f", $offset ); $advanced = $length > 0; $offset += $length; return $advanced; } + /** + * Tokenization of hash tokens + * + * > U+0023 NUMBER SIGN (#) + * > If the next input code point is an ident code point or the next two input code points are a valid escape, then: + * > 1. Create a . + * > 2. If the next 3 input code points would start an ident sequence, set the + * > ’s type flag to "id". + * > 3. Consume an ident sequence, and set the ’s value to the + * > returned string. + * > 4. Return the . + * > Otherwise, return a with its value set to the current input code point. + * + * This implementation is not interested in the , a '#' delim token is not relevant for selectors. + */ + protected static function parse_hash_token( string $input, string &$offset ): ?string { + if ( $offset + 1 >= strlen( $input ) || '#' !== $input[ $offset ] ) { + return null; + } + + $offset_after_hash = $offset + 1; + if ( self::check_if_three_code_points_would_start_an_ident_sequence( $input, $offset_after_hash ) ) { + $offset = $offset_after_hash; + return self::parse_ident( $input, $offset ); + } + return null; + } + + /** + * Parse an ident token + * + * CAUTION: This method is _not_ for parsing and ID selector! + * + * > 4.3.11. Consume an ident sequence + * > This section describes how to consume an ident sequence from a stream of code points. It returns a string containing the largest name that can be formed from adjacent code points in the stream, starting from the first. + * > + * > Note: This algorithm does not do the verification of the first few code points that are necessary to ensure the returned code points would constitute an . If that is the intended use, ensure that the stream starts with an ident sequence before calling this algorithm. + * > + * > Let result initially be an empty string. + * > + * > Repeatedly consume the next input code point from the stream: + * > + * > ident code point + * > Append the code point to result. + * > the stream starts with a valid escape + * > Consume an escaped code point. Append the returned code point to result. + * > anything else + * > Reconsume the current input code point. Return result. + * + * https://www.w3.org/TR/css-syntax-3/#consume-name + */ + protected static function parse_ident( string $input, string &$offset ): ?string { + if ( ! self::check_if_three_code_points_would_start_an_ident_sequence( $input, $offset ) ) { + return null; + } + + $ident = ''; + + while ( $offset < strlen( $input ) ) { + if ( self::next_two_are_valid_escape( $input, $offset ) ) { + $ident .= self::consume_escaped_codepoint( $input, $offset ); + continue; + } elseif ( self::is_ident_codepoint( $input, $offset ) ) { + // @todo this should append and advance the correct number of bytes. + $ident .= $input[ $offset ]; + $offset += 1; + continue; + } + break; + } + + return $ident; + } + + /** + * Consume an escaped code point. + * + * > 4.3.7. Consume an escaped code point + * > This section describes how to consume an escaped code point. It assumes that the U+005C + * > REVERSE SOLIDUS (\) has already been consumed and that the next input code point has + * > already been verified to be part of a valid escape. It will return a code point. + * > + * > Consume the next input code point. + * > + * > hex digit + * > Consume as many hex digits as possible, but no more than 5. Note that this means 1-6 + * > hex digits have been consumed in total. If the next input code point is whitespace, + * > consume it as well. Interpret the hex digits as a hexadecimal number. If this number is + * > zero, or is for a surrogate, or is greater than the maximum allowed code point, return + * > U+FFFD REPLACEMENT CHARACTER (�). Otherwise, return the code point with that value. + * > EOF + * > This is a parse error. Return U+FFFD REPLACEMENT CHARACTER (�). + * > anything else + * > Return the current input code point. + */ + protected static function consume_escaped_codepoint( $input, &$offset ): ?string { + $char = $input[ $offset ]; + if ( + ( '0' <= $char && $char <= '9' ) || + ( 'a' <= $char && $char <= 'f' ) || + ( 'A' <= $char && $char <= 'F' ) + ) { + $hex_end_offset = $offset + 1; + while ( + strlen( $input ) > $hex_end_offset && + $hex_end_offset - $offset < 6 && + ( + ( '0' <= $char && $char <= '9' ) || + ( 'a' <= $char && $char <= 'f' ) || + ( 'A' <= $char && $char <= 'F' ) + ) + ) { + $hex_end_offset += 1; + } + + $codepoint_value = hexdec( substr( $input, $offset, $hex_end_offset - $offset ) ); + + // > A surrogate is a leading surrogate or a trailing surrogate. + // > A leading surrogate is a code point that is in the range U+D800 to U+DBFF, inclusive. + // > A trailing surrogate is a code point that is in the range U+DC00 to U+DFFF, inclusive. + // The surrogate ranges are adjacent, so the complete range is 0xD800..=0xDFFF, + // inclusive. + $codepoint_char = ( + 0 === $codepoint_value || + $codepoint_value > self::UTF8_MAX_CODEPOINT_VALUE || + ( 0xD800 <= $codepoint_value || $codepoint_value <= 0xDFFF ) + ) ? + "\u{FFFD}" : + mb_chr( $codepoint_value, 'UTF-8' ); + + $offset = $hex_end_offset; + + // If the next input code point is whitespace, consume it as well. + if ( + strlen( $input ) > $offset && + ( + "\n" === $input[ $offset ] || + "\t" === $input[ $offset ] || + ' ' === $input[ $offset ] + ) + ) { + ++$offset; + } + return $codepoint_char; + } + + $codepoint_char = mb_substr( $input, $offset, 1, 'UTF-8' ); + $offset += strlen( $codepoint_char ); + return $codepoint_char; + } + /* * Utiltities * ========== @@ -140,7 +325,7 @@ public static function parse_whitespace( string $input, string &$offset ): bool * * @todo this does not check whether the second codepoint is valid. */ - public static function next_two_are_valid_escape( string $input, string $offset ): bool { + protected static function next_two_are_valid_escape( string $input, string $offset ): bool { if ( $offset + 1 >= strlen( $input ) ) { return false; } @@ -159,7 +344,7 @@ public static function next_two_are_valid_escape( string $input, string $offset * > non-ASCII code point * > A code point with a value equal to or greater than U+0080 . */ - public static function is_ident_start_codepoint( string $input, string $offset ): bool { + protected static function is_ident_start_codepoint( string $input, string $offset ): bool { if ( $offset >= strlen( $input ) ) { return false; } @@ -178,7 +363,7 @@ public static function is_ident_start_codepoint( string $input, string $offset ) * > digit * > A code point between U+0030 DIGIT ZERO (0) and U+0039 DIGIT NINE (9) inclusive. */ - public static function is_ident_codepoint( string $input, string $offset ): bool { + protected static function is_ident_codepoint( string $input, string $offset ): bool { return '-' === $input[ $offset ] || ( '0' <= $input[ $offset ] && $input[ $offset ] <= '9' ) || self::is_ident_start_codepoint( $input, $offset ); @@ -203,7 +388,7 @@ public static function is_ident_codepoint( string $input, string $offset ): bool * * https://www.w3.org/TR/css-syntax-3/#would-start-an-identifier */ - public static function check_if_three_code_points_would_start_an_ident_sequence( string $input, string $offset ): bool { + protected static function check_if_three_code_points_would_start_an_ident_sequence( string $input, string $offset ): bool { if ( $offset >= strlen( $input ) ) { return false; } From 967557fb01f0e016d63fa2b391d351aec90090bc Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 22 Nov 2024 17:41:16 +0100 Subject: [PATCH 006/634] Add ident tests --- .../phpunit/tests/html-api/wpCssSelectors.php | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 tests/phpunit/tests/html-api/wpCssSelectors.php diff --git a/tests/phpunit/tests/html-api/wpCssSelectors.php b/tests/phpunit/tests/html-api/wpCssSelectors.php new file mode 100644 index 0000000000000..2857603360e79 --- /dev/null +++ b/tests/phpunit/tests/html-api/wpCssSelectors.php @@ -0,0 +1,50 @@ +assertSame( $ident, $result ); + $this->assertSame( substr( $input, $offset ), $rest ); + } +} From 2ec1db32af13f1248935ee5e8bb2d634430afc31 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 22 Nov 2024 17:41:42 +0100 Subject: [PATCH 007/634] Fix ident non-ascii bug --- src/wp-includes/html-api/class-wp-css-selectors.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 53417a0f1967c..547a51293bb11 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -353,7 +353,7 @@ protected static function is_ident_start_codepoint( string $input, string $offse '_' === $input[ $offset ] || ( 'a' <= $input[ $offset ] && $input[ $offset ] <= 'z' ) || ( 'A' <= $input[ $offset ] && $input[ $offset ] <= 'Z' ) || - $input[ $offset ] <= '\x7F' + $input[ $offset ] > '\x7F' ); } From ee2c7cefa987ef4cb208447aad489a700ab7f91f Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 22 Nov 2024 17:42:12 +0100 Subject: [PATCH 008/634] Use class after defined --- .../html-api/class-wp-css-selectors.php | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 547a51293bb11..55396c8851294 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -117,23 +117,6 @@ private static function parse( string $input ) { } } -final class WP_CSS_ID_Selector extends WP_CSS_Selector_Parser { - /** @var string */ - public $ident; - - private function __construct( string $ident ) { - $this->ident = $ident; - } - - public static function parse( string $input, string &$offset ): ?self { - $ident = self::parse_hash_token( $input, $offset ); - if ( null === $ident ) { - return null; - } - return new self( $ident ); - } -} - interface IWP_CSS_Selector_Parser { /** * @return static|null @@ -431,3 +414,20 @@ protected static function check_if_three_code_points_would_start_an_ident_sequen return self::is_ident_start_codepoint( $input, $offset ); } } + +final class WP_CSS_ID_Selector extends WP_CSS_Selector_Parser { + /** @var string */ + public $ident; + + private function __construct( string $ident ) { + $this->ident = $ident; + } + + public static function parse( string $input, string &$offset ): ?self { + $ident = self::parse_hash_token( $input, $offset ); + if ( null === $ident ) { + return null; + } + return new self( $ident ); + } +} From 0f708ba4892a50249d0c2267640acf2a256beb21 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 22 Nov 2024 18:01:07 +0100 Subject: [PATCH 009/634] Fix some char stuff --- .../html-api/class-wp-css-selectors.php | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 55396c8851294..408d25395febb 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -194,6 +194,8 @@ protected static function parse_ident( string $input, string &$offset ): ?string while ( $offset < strlen( $input ) ) { if ( self::next_two_are_valid_escape( $input, $offset ) ) { + // Move past the `\` character. + ++$offset; $ident .= self::consume_escaped_codepoint( $input, $offset ); continue; } elseif ( self::is_ident_codepoint( $input, $offset ) ) { @@ -230,20 +232,19 @@ protected static function parse_ident( string $input, string &$offset ): ?string * > Return the current input code point. */ protected static function consume_escaped_codepoint( $input, &$offset ): ?string { - $char = $input[ $offset ]; if ( - ( '0' <= $char && $char <= '9' ) || - ( 'a' <= $char && $char <= 'f' ) || - ( 'A' <= $char && $char <= 'F' ) + ( '0' <= $input[ $offset ] && $input[ $offset ] <= '9' ) || + ( 'a' <= $input[ $offset ] && $input[ $offset ] <= 'f' ) || + ( 'A' <= $input[ $offset ] && $input[ $offset ] <= 'F' ) ) { $hex_end_offset = $offset + 1; while ( strlen( $input ) > $hex_end_offset && $hex_end_offset - $offset < 6 && ( - ( '0' <= $char && $char <= '9' ) || - ( 'a' <= $char && $char <= 'f' ) || - ( 'A' <= $char && $char <= 'F' ) + ( '0' <= $input[ $hex_end_offset ] && $input[ $hex_end_offset ] <= '9' ) || + ( 'a' <= $input[ $hex_end_offset ] && $input[ $hex_end_offset ] <= 'f' ) || + ( 'A' <= $input[ $hex_end_offset ] && $input[ $hex_end_offset ] <= 'F' ) ) ) { $hex_end_offset += 1; @@ -259,7 +260,7 @@ protected static function consume_escaped_codepoint( $input, &$offset ): ?string $codepoint_char = ( 0 === $codepoint_value || $codepoint_value > self::UTF8_MAX_CODEPOINT_VALUE || - ( 0xD800 <= $codepoint_value || $codepoint_value <= 0xDFFF ) + ( 0xD800 <= $codepoint_value && $codepoint_value <= 0xDFFF ) ) ? "\u{FFFD}" : mb_chr( $codepoint_value, 'UTF-8' ); From 3cb455d41f7923d4b4be9fec3b7cf3f72686dfdc Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 22 Nov 2024 18:01:17 +0100 Subject: [PATCH 010/634] Improve tests --- .../phpunit/tests/html-api/wpCssSelectors.php | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpCssSelectors.php b/tests/phpunit/tests/html-api/wpCssSelectors.php index 2857603360e79..a55463ec7122e 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectors.php +++ b/tests/phpunit/tests/html-api/wpCssSelectors.php @@ -15,19 +15,20 @@ class Tests_HtmlApi_WpCssSelectors extends WP_UnitTestCase { public static function data_valid_idents() { return array( - array( '_-foo123#xyz', '_-foo123', '#xyz' ), - array( '😍foo123.xyz', '😍foo123', '.xyz' ), - array( '\\xyz', 'xyz', '' ), - array( '\\ x', ' x', '' ), - array( '\\😍', '😍', '' ), - array( '\\abcd', 'ꯍ', '' ), + 'trailing #' => array( '_-foo123#xyz', '_-foo123', '#xyz' ), + 'trailing .' => array( '😍foo123.xyz', '😍foo123', '.xyz' ), + 'trailing " "' => array( '😍foo123 more', '😍foo123', ' more' ), + 'escaped ASCII character' => array( '\\xyz', 'xyz', '' ), + 'escaped space' => array( '\\ x', ' x', '' ), + 'escaped emoji' => array( '\\😍', '😍', '' ), + 'hex unicode codepoint' => array( '\\abcd', 'ꯍ', '' ), - array( "\\31\t23", '123', '' ), - array( "\\31\n23", '123', '' ), - array( "\\31 23", '123', '' ), - array( '\\9', "\t", '' ), - array( '\\61 bc', 'abc', '' ), - array( '\\000061bc', 'abc', '' ), + 'hex tab-suffixed 1' => array( "\\31\t23", '123', '' ), + 'hex newline-suffixed 1' => array( "\\31\n23", '123', '' ), + 'hex space-suffixed 1' => array( "\\31 23", '123', '' ), + 'hex tab' => array( '\\9', "\t", '' ), + 'hex a' => array( '\\61 bc', 'abc', '' ), + 'hex a max escape length' => array( '\\000061bc', 'abc', '' ), ); } @@ -44,7 +45,7 @@ public static function test( string $input, &$offset ) { $offset = 0; $ident = $c::test( $input, $offset ); - $this->assertSame( $ident, $result ); - $this->assertSame( substr( $input, $offset ), $rest ); + $this->assertSame( $ident, $result, 'Ident did not match.' ); + $this->assertSame( substr( $input, $offset ), $rest, 'Offset was not updated correctly.' ); } } From 5609e509ef589afbe23654fe629ce85fc06ad7ec Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 22 Nov 2024 19:53:10 +0100 Subject: [PATCH 011/634] Housekeeping --- src/wp-includes/html-api/class-wp-css-selectors.php | 4 +--- tests/phpunit/tests/html-api/wpCssSelectors.php | 7 ++++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 408d25395febb..f9c85f9b48a3c 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -1,14 +1,12 @@ array( '_-foo123#xyz', '_-foo123', '#xyz' ), @@ -33,6 +36,8 @@ public static function data_valid_idents() { } /** + * @ticket TBD + * * @dataProvider data_valid_idents */ public function test_valid_idents( string $input, string $result, string $rest ) { From 4f25bc21f907369c899ea2c8c07e7461bdb731e3 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 22 Nov 2024 19:56:30 +0100 Subject: [PATCH 012/634] Require new file in WP --- src/wp-settings.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wp-settings.php b/src/wp-settings.php index 635f6de248dd5..6c799d5c95140 100644 --- a/src/wp-settings.php +++ b/src/wp-settings.php @@ -265,6 +265,7 @@ require ABSPATH . WPINC . '/html-api/class-wp-html-stack-event.php'; require ABSPATH . WPINC . '/html-api/class-wp-html-processor-state.php'; require ABSPATH . WPINC . '/html-api/class-wp-html-processor.php'; +require ABSPATH . WPINC . '/html-api/class-wp-css-selectors.php'; require ABSPATH . WPINC . '/class-wp-http.php'; require ABSPATH . WPINC . '/class-wp-http-streams.php'; require ABSPATH . WPINC . '/class-wp-http-curl.php'; From 943293f2f840988546c84d17d59dfe4d37e05448 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 22 Nov 2024 20:14:21 +0100 Subject: [PATCH 013/634] Fix offset type --- .../html-api/class-wp-css-selectors.php | 18 +++++++++--------- .../phpunit/tests/html-api/wpCssSelectors.php | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index f9c85f9b48a3c..897cf4b59d752 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -119,13 +119,13 @@ interface IWP_CSS_Selector_Parser { /** * @return static|null */ - public static function parse( string $input, string &$offset ); + public static function parse( string $input, int &$offset ); } abstract class WP_CSS_Selector_Parser implements IWP_CSS_Selector_Parser { const UTF8_MAX_CODEPOINT_VALUE = 0x10FFFF; - protected static function parse_whitespace( string $input, string &$offset ): bool { + protected static function parse_whitespace( string $input, int &$offset ): bool { $length = strspn( $input, " \t\r\n\f", $offset ); $advanced = $length > 0; $offset += $length; @@ -147,7 +147,7 @@ protected static function parse_whitespace( string $input, string &$offset ): bo * * This implementation is not interested in the , a '#' delim token is not relevant for selectors. */ - protected static function parse_hash_token( string $input, string &$offset ): ?string { + protected static function parse_hash_token( string $input, int &$offset ): ?string { if ( $offset + 1 >= strlen( $input ) || '#' !== $input[ $offset ] ) { return null; } @@ -183,7 +183,7 @@ protected static function parse_hash_token( string $input, string &$offset ): ?s * * https://www.w3.org/TR/css-syntax-3/#consume-name */ - protected static function parse_ident( string $input, string &$offset ): ?string { + protected static function parse_ident( string $input, int &$offset ): ?string { if ( ! self::check_if_three_code_points_would_start_an_ident_sequence( $input, $offset ) ) { return null; } @@ -307,7 +307,7 @@ protected static function consume_escaped_codepoint( $input, &$offset ): ?string * * @todo this does not check whether the second codepoint is valid. */ - protected static function next_two_are_valid_escape( string $input, string $offset ): bool { + protected static function next_two_are_valid_escape( string $input, int $offset ): bool { if ( $offset + 1 >= strlen( $input ) ) { return false; } @@ -326,7 +326,7 @@ protected static function next_two_are_valid_escape( string $input, string $offs * > non-ASCII code point * > A code point with a value equal to or greater than U+0080 . */ - protected static function is_ident_start_codepoint( string $input, string $offset ): bool { + protected static function is_ident_start_codepoint( string $input, int $offset ): bool { if ( $offset >= strlen( $input ) ) { return false; } @@ -345,7 +345,7 @@ protected static function is_ident_start_codepoint( string $input, string $offse * > digit * > A code point between U+0030 DIGIT ZERO (0) and U+0039 DIGIT NINE (9) inclusive. */ - protected static function is_ident_codepoint( string $input, string $offset ): bool { + protected static function is_ident_codepoint( string $input, int $offset ): bool { return '-' === $input[ $offset ] || ( '0' <= $input[ $offset ] && $input[ $offset ] <= '9' ) || self::is_ident_start_codepoint( $input, $offset ); @@ -370,7 +370,7 @@ protected static function is_ident_codepoint( string $input, string $offset ): b * * https://www.w3.org/TR/css-syntax-3/#would-start-an-identifier */ - protected static function check_if_three_code_points_would_start_an_ident_sequence( string $input, string $offset ): bool { + protected static function check_if_three_code_points_would_start_an_ident_sequence( string $input, int $offset ): bool { if ( $offset >= strlen( $input ) ) { return false; } @@ -422,7 +422,7 @@ private function __construct( string $ident ) { $this->ident = $ident; } - public static function parse( string $input, string &$offset ): ?self { + public static function parse( string $input, int &$offset ): ?self { $ident = self::parse_hash_token( $input, $offset ); if ( null === $ident ) { return null; diff --git a/tests/phpunit/tests/html-api/wpCssSelectors.php b/tests/phpunit/tests/html-api/wpCssSelectors.php index 39d68efcd8f4a..e0dd09c929d09 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectors.php +++ b/tests/phpunit/tests/html-api/wpCssSelectors.php @@ -42,7 +42,7 @@ public static function data_valid_idents() { */ public function test_valid_idents( string $input, string $result, string $rest ) { $c = new class() extends WP_CSS_Selector_Parser { - public static function parse( string $input, string &$offset ) {} + public static function parse( string $input, int &$offset ) {} public static function test( string $input, &$offset ) { return self::parse_ident( $input, $offset ); } From 24c9744657023179a33f786a6a7b4d0242534783 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 22 Nov 2024 20:14:48 +0100 Subject: [PATCH 014/634] Add more tests and invalid tests --- .../phpunit/tests/html-api/wpCssSelectors.php | 66 +++++++++++++++---- 1 file changed, 53 insertions(+), 13 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpCssSelectors.php b/tests/phpunit/tests/html-api/wpCssSelectors.php index e0dd09c929d09..d12fcc42c8e60 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectors.php +++ b/tests/phpunit/tests/html-api/wpCssSelectors.php @@ -18,20 +18,41 @@ class Tests_HtmlApi_WpCssSelectors extends WP_UnitTestCase { */ public static function data_valid_idents() { return array( - 'trailing #' => array( '_-foo123#xyz', '_-foo123', '#xyz' ), - 'trailing .' => array( '😍foo123.xyz', '😍foo123', '.xyz' ), - 'trailing " "' => array( '😍foo123 more', '😍foo123', ' more' ), - 'escaped ASCII character' => array( '\\xyz', 'xyz', '' ), - 'escaped space' => array( '\\ x', ' x', '' ), - 'escaped emoji' => array( '\\😍', '😍', '' ), - 'hex unicode codepoint' => array( '\\abcd', 'ꯍ', '' ), + 'trailing #' => array( '_-foo123#xyz', '_-foo123', '#xyz' ), + 'trailing .' => array( '😍foo123.xyz', '😍foo123', '.xyz' ), + 'trailing " "' => array( '😍foo123 more', '😍foo123', ' more' ), + 'escaped ASCII character' => array( '\\xyz', 'xyz', '' ), + 'escaped space' => array( '\\ x', ' x', '' ), + 'escaped emoji' => array( '\\😍', '😍', '' ), + 'hex unicode codepoint' => array( '\\abcd', 'ꯍ', '' ), - 'hex tab-suffixed 1' => array( "\\31\t23", '123', '' ), - 'hex newline-suffixed 1' => array( "\\31\n23", '123', '' ), - 'hex space-suffixed 1' => array( "\\31 23", '123', '' ), - 'hex tab' => array( '\\9', "\t", '' ), - 'hex a' => array( '\\61 bc', 'abc', '' ), - 'hex a max escape length' => array( '\\000061bc', 'abc', '' ), + 'hex tab-suffixed 1' => array( "\\31\t23", '123', '' ), + 'hex newline-suffixed 1' => array( "\\31\n23", '123', '' ), + 'hex space-suffixed 1' => array( "\\31 23", '123', '' ), + 'hex tab' => array( '\\9', "\t", '' ), + 'hex a' => array( '\\61 bc', 'abc', '' ), + 'hex a max escape length' => array( '\\000061bc', 'abc', '' ), + + 'out of range replacement min' => array( '\\110000 ', "\u{fffd}", '' ), + 'out of range replacement max' => array( '\\ffffff ', "\u{fffd}", '' ), + 'leading surrogate min replacement' => array( '\\d800 ', "\u{fffd}", '' ), + 'leading surrogate max replacement' => array( '\\dbff ', "\u{fffd}", '' ), + 'trailing surrogate min replacement' => array( '\\dc00 ', "\u{fffd}", '' ), + 'trailing surrogate max replacement' => array( '\\dfff ', "\u{fffd}", '' ), + ); + } + + /** + * Data provider. + */ + public static function data_invalid_idents() { + return array( + 'bad start >' => array( '>' ), + 'bad start [' => array( '[' ), + 'bad start #' => array( '#' ), + 'bad start " "' => array( ' ' ), + 'bad start -' => array( '-' ), + 'bad start 1' => array( '-' ), ); } @@ -53,4 +74,23 @@ public static function test( string $input, &$offset ) { $this->assertSame( $ident, $result, 'Ident did not match.' ); $this->assertSame( substr( $input, $offset ), $rest, 'Offset was not updated correctly.' ); } + + /** + * @ticket TBD + * + * @dataProvider data_invalid_idents + */ + public function test_invalid_idents( string $input ) { + $c = new class() extends WP_CSS_Selector_Parser { + public static function parse( string $input, int &$offset ) {} + public static function test( string $input, int &$offset ) { + return self::parse_ident( $input, $offset ); + } + }; + + $offset = 0; + $result = $c::test( $input, $offset ); + $this->assertNull( $result, 'Ident did not match.' ); + $this->assertSame( 0, $offset, 'Offset was incorrectly adjusted.' ); + } } From a7c10b9e12aeed9263a69b46eeb011e59092ed07 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 22 Nov 2024 20:15:03 +0100 Subject: [PATCH 015/634] Fix wrong offset var usage --- src/wp-includes/html-api/class-wp-css-selectors.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 897cf4b59d752..8afb3928e07de 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -383,7 +383,7 @@ protected static function check_if_three_code_points_would_start_an_ident_sequen // > U+002D HYPHEN-MINUS if ( '-' === $input[ $offset ] ) { $after_initial_hyphen_minus_offset = $offset + 1; - if ( $offset >= strlen( $input ) ) { + if ( $after_initial_hyphen_minus_offset >= strlen( $input ) ) { return false; } From dd718b7093dfa3510d6b7476b39510013f759797 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 22 Nov 2024 20:17:15 +0100 Subject: [PATCH 016/634] comment tweak --- src/wp-includes/html-api/class-wp-css-selectors.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 8afb3928e07de..64020bcc0c607 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -392,7 +392,7 @@ protected static function check_if_three_code_points_would_start_an_ident_sequen return true; } - // > If the second and third code points are a valid escape, return true. + // > If the second and third code points are a valid escape… return true. if ( self::next_two_are_valid_escape( $input, $after_initial_hyphen_minus_offset ) ) { return true; } From 5884aca6e807002d6474c37e291b3dde5c59778d Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 22 Nov 2024 20:53:50 +0100 Subject: [PATCH 017/634] Implement codepoint escape with strspn --- .../html-api/class-wp-css-selectors.php | 24 ++++--------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 64020bcc0c607..56c31911d95b8 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -230,25 +230,9 @@ protected static function parse_ident( string $input, int &$offset ): ?string { * > Return the current input code point. */ protected static function consume_escaped_codepoint( $input, &$offset ): ?string { - if ( - ( '0' <= $input[ $offset ] && $input[ $offset ] <= '9' ) || - ( 'a' <= $input[ $offset ] && $input[ $offset ] <= 'f' ) || - ( 'A' <= $input[ $offset ] && $input[ $offset ] <= 'F' ) - ) { - $hex_end_offset = $offset + 1; - while ( - strlen( $input ) > $hex_end_offset && - $hex_end_offset - $offset < 6 && - ( - ( '0' <= $input[ $hex_end_offset ] && $input[ $hex_end_offset ] <= '9' ) || - ( 'a' <= $input[ $hex_end_offset ] && $input[ $hex_end_offset ] <= 'f' ) || - ( 'A' <= $input[ $hex_end_offset ] && $input[ $hex_end_offset ] <= 'F' ) - ) - ) { - $hex_end_offset += 1; - } - - $codepoint_value = hexdec( substr( $input, $offset, $hex_end_offset - $offset ) ); + $hex_length = strspn( $input, '0123456789abcdefABCDEF', $offset, 6 ); + if ( $hex_length > 0 ) { + $codepoint_value = hexdec( substr( $input, $offset, $hex_length ) ); // > A surrogate is a leading surrogate or a trailing surrogate. // > A leading surrogate is a code point that is in the range U+D800 to U+DBFF, inclusive. @@ -263,7 +247,7 @@ protected static function consume_escaped_codepoint( $input, &$offset ): ?string "\u{FFFD}" : mb_chr( $codepoint_value, 'UTF-8' ); - $offset = $hex_end_offset; + $offset += $hex_length; // If the next input code point is whitespace, consume it as well. if ( From a9a077f463c9c981adc811b7be6b27d89c05d9dc Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 22 Nov 2024 20:54:11 +0100 Subject: [PATCH 018/634] Test with UPPER HEX --- tests/phpunit/tests/html-api/wpCssSelectors.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/phpunit/tests/html-api/wpCssSelectors.php b/tests/phpunit/tests/html-api/wpCssSelectors.php index d12fcc42c8e60..270def39b53d3 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectors.php +++ b/tests/phpunit/tests/html-api/wpCssSelectors.php @@ -24,7 +24,8 @@ public static function data_valid_idents() { 'escaped ASCII character' => array( '\\xyz', 'xyz', '' ), 'escaped space' => array( '\\ x', ' x', '' ), 'escaped emoji' => array( '\\😍', '😍', '' ), - 'hex unicode codepoint' => array( '\\abcd', 'ꯍ', '' ), + 'hex unicode codepoint' => array( '\\1f0a1', '🂡', '' ), + 'HEX UNICODE CODEPOINT' => array( '\\1D4B2', '𝒲', '' ), 'hex tab-suffixed 1' => array( "\\31\t23", '123', '' ), 'hex newline-suffixed 1' => array( "\\31\n23", '123', '' ), From 5f53e0a50b472a0aff078f233d6d7ffae189de33 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 25 Nov 2024 17:34:25 +0100 Subject: [PATCH 019/634] Add ID tests --- .../phpunit/tests/html-api/wpCssSelectors.php | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/phpunit/tests/html-api/wpCssSelectors.php b/tests/phpunit/tests/html-api/wpCssSelectors.php index 270def39b53d3..149bcd1f9572d 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectors.php +++ b/tests/phpunit/tests/html-api/wpCssSelectors.php @@ -94,4 +94,33 @@ public static function test( string $input, int &$offset ) { $this->assertNull( $result, 'Ident did not match.' ); $this->assertSame( 0, $offset, 'Offset was incorrectly adjusted.' ); } + + /** + * @ticket TBD + * + * @dataProvider data_ids + */ + public function test_parse_id( string $input, ?string $expected_id = null, ?string $rest = null ) { + $offset = 0; + $result = WP_CSS_ID_Selector::parse( $input, $offset ); + if ( null === $expected_id ) { + $this->assertNull( $result ); + } else { + $this->assertSame( $result->ident, $expected_id ); + $this->assertSame( substr( $input, $offset ), $rest ); + } + } + + public static function data_ids(): array { + return array( + 'valid #_-foo123' => array( '#_-foo123', '_-foo123', '' ), + 'valid #foo#bar' => array( '#foo#bar', 'foo', '#bar' ), + 'escaped #\31 23' => array( '#\\31 23', '123', '' ), + 'with descendant #\31 23 div' => array( '#\\31 23 div', '123', ' div' ), + + 'not ID foo' => array( 'foo' ), + 'not valid #1foo' => array( '#1foo' ), + 'not id .bar' => array( '.bar' ), + ); + } } From effbbbece335486d269ecccf480fab99fc497d17 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 25 Nov 2024 17:46:07 +0100 Subject: [PATCH 020/634] Improve tests --- .../phpunit/tests/html-api/wpCssSelectors.php | 72 ++++++++----------- 1 file changed, 29 insertions(+), 43 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpCssSelectors.php b/tests/phpunit/tests/html-api/wpCssSelectors.php index 149bcd1f9572d..53495f0b09004 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectors.php +++ b/tests/phpunit/tests/html-api/wpCssSelectors.php @@ -15,8 +15,10 @@ class Tests_HtmlApi_WpCssSelectors extends WP_UnitTestCase { /** * Data provider. + * + * @return array */ - public static function data_valid_idents() { + public static function data_idents(): array { return array( 'trailing #' => array( '_-foo123#xyz', '_-foo123', '#xyz' ), 'trailing .' => array( '😍foo123.xyz', '😍foo123', '.xyz' ), @@ -40,29 +42,23 @@ public static function data_valid_idents() { 'leading surrogate max replacement' => array( '\\dbff ', "\u{fffd}", '' ), 'trailing surrogate min replacement' => array( '\\dc00 ', "\u{fffd}", '' ), 'trailing surrogate max replacement' => array( '\\dfff ', "\u{fffd}", '' ), - ); - } - /** - * Data provider. - */ - public static function data_invalid_idents() { - return array( - 'bad start >' => array( '>' ), - 'bad start [' => array( '[' ), - 'bad start #' => array( '#' ), - 'bad start " "' => array( ' ' ), - 'bad start -' => array( '-' ), - 'bad start 1' => array( '-' ), + // Invalid + 'bad start >' => array( '>' ), + 'bad start [' => array( '[' ), + 'bad start #' => array( '#' ), + 'bad start " "' => array( ' ' ), + 'bad start -' => array( '-' ), + 'bad start 1' => array( '-' ), ); } /** * @ticket TBD * - * @dataProvider data_valid_idents + * @dataProvider data_idents */ - public function test_valid_idents( string $input, string $result, string $rest ) { + public function test_parse_ident( string $input, ?string $expected = null, ?string $rest = null ) { $c = new class() extends WP_CSS_Selector_Parser { public static function parse( string $input, int &$offset ) {} public static function test( string $input, &$offset ) { @@ -70,48 +66,38 @@ public static function test( string $input, &$offset ) { } }; - $offset = 0; - $ident = $c::test( $input, $offset ); - $this->assertSame( $ident, $result, 'Ident did not match.' ); - $this->assertSame( substr( $input, $offset ), $rest, 'Offset was not updated correctly.' ); - } - - /** - * @ticket TBD - * - * @dataProvider data_invalid_idents - */ - public function test_invalid_idents( string $input ) { - $c = new class() extends WP_CSS_Selector_Parser { - public static function parse( string $input, int &$offset ) {} - public static function test( string $input, int &$offset ) { - return self::parse_ident( $input, $offset ); - } - }; - $offset = 0; $result = $c::test( $input, $offset ); - $this->assertNull( $result, 'Ident did not match.' ); - $this->assertSame( 0, $offset, 'Offset was incorrectly adjusted.' ); + if ( null === $expected ) { + $this->assertNull( $result ); + } else { + $this->assertSame( $expected, $result, 'Ident did not match.' ); + $this->assertSame( substr( $input, $offset ), $rest, 'Offset was not updated correctly.' ); + } } /** * @ticket TBD * - * @dataProvider data_ids + * @dataProvider data_id_selectors */ - public function test_parse_id( string $input, ?string $expected_id = null, ?string $rest = null ) { + public function test_parse_id( string $input, ?string $expected = null, ?string $rest = null ) { $offset = 0; $result = WP_CSS_ID_Selector::parse( $input, $offset ); - if ( null === $expected_id ) { + if ( null === $expected ) { $this->assertNull( $result ); } else { - $this->assertSame( $result->ident, $expected_id ); + $this->assertSame( $result->ident, $expected ); $this->assertSame( substr( $input, $offset ), $rest ); } } - public static function data_ids(): array { + /** + * Data provider. + * + * @return array + */ + public static function data_id_selectors(): array { return array( 'valid #_-foo123' => array( '#_-foo123', '_-foo123', '' ), 'valid #foo#bar' => array( '#foo#bar', 'foo', '#bar' ), @@ -119,8 +105,8 @@ public static function data_ids(): array { 'with descendant #\31 23 div' => array( '#\\31 23 div', '123', ' div' ), 'not ID foo' => array( 'foo' ), + 'not ID .bar' => array( '.bar' ), 'not valid #1foo' => array( '#1foo' ), - 'not id .bar' => array( '.bar' ), ); } } From 62ec5bb804872afe38073e86a0e23ee1d5cd16a7 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 25 Nov 2024 17:46:23 +0100 Subject: [PATCH 021/634] Add class selector tests --- .../phpunit/tests/html-api/wpCssSelectors.php | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tests/phpunit/tests/html-api/wpCssSelectors.php b/tests/phpunit/tests/html-api/wpCssSelectors.php index 53495f0b09004..aac3339e4d27d 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectors.php +++ b/tests/phpunit/tests/html-api/wpCssSelectors.php @@ -109,4 +109,38 @@ public static function data_id_selectors(): array { 'not valid #1foo' => array( '#1foo' ), ); } + + /** + * @ticket TBD + * + * @dataProvider data_class_selectors + */ + public function test_parse_class( string $input, ?string $expected = null, ?string $rest = null ) { + $offset = 0; + $result = WP_CSS_Class_Selector::parse( $input, $offset ); + if ( null === $expected ) { + $this->assertNull( $result ); + } else { + $this->assertSame( $result->ident, $expected ); + $this->assertSame( substr( $input, $offset ), $rest ); + } + } + + /** + * Data provider. + * + * @return array + */ + public static function data_class_selectors(): array { + return array( + 'valid ._-foo123' => array( '._-foo123', '_-foo123', '' ), + 'valid .foo.bar' => array( '.foo.bar', 'foo', '.bar' ), + 'escaped .\31 23' => array( '.\\31 23', '123', '' ), + 'with descendant .\31 23 div' => array( '.\\31 23 div', '123', ' div' ), + + 'not class foo' => array( 'foo' ), + 'not class #bar' => array( '#bar' ), + 'not valid .1foo' => array( '.1foo' ), + ); + } } From 153f00978429f98cd7c5cc3d65a8b8affdcf1e45 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 25 Nov 2024 17:47:00 +0100 Subject: [PATCH 022/634] Add class selector --- .../html-api/class-wp-css-selectors.php | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 56c31911d95b8..7b72fa0fe9616 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -414,3 +414,29 @@ public static function parse( string $input, int &$offset ): ?self { return new self( $ident ); } } + +final class WP_CSS_Class_Selector extends WP_CSS_Selector_Parser { + /** @var string */ + public $ident; + + private function __construct( string $ident ) { + $this->ident = $ident; + } + + public static function parse( string $input, int &$offset ): ?self { + if ( $offset + 1 >= strlen( $input ) || '.' !== $input[ $offset ] ) { + return null; + } + + $updated_offset = $offset + 1; + $result = self::parse_ident( $input, $updated_offset ); + + if ( null === $result ) { + return null; + $offset = $updated_offset; + } + + $offset = $updated_offset; + return new self( $result ); + } +} From fcc6401475554cd955891ae1dd82e067064067e8 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 25 Nov 2024 17:47:21 +0100 Subject: [PATCH 023/634] Simplify id selector parse --- .../html-api/class-wp-css-selectors.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 7b72fa0fe9616..fbccb55a5a0eb 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -152,12 +152,16 @@ protected static function parse_hash_token( string $input, int &$offset ): ?stri return null; } - $offset_after_hash = $offset + 1; - if ( self::check_if_three_code_points_would_start_an_ident_sequence( $input, $offset_after_hash ) ) { - $offset = $offset_after_hash; - return self::parse_ident( $input, $offset ); + $updated_offset = $offset + 1; + $result = self::parse_ident( $input, $updated_offset ); + + if ( null === $result ) { + return null; + $offset = $updated_offset; } - return null; + + $offset = $updated_offset; + return $result; } /** From 21c67e52745b532489f6a494892b71c83f1b03ac Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 25 Nov 2024 18:02:03 +0100 Subject: [PATCH 024/634] Improve ident tests --- .../phpunit/tests/html-api/wpCssSelectors.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpCssSelectors.php b/tests/phpunit/tests/html-api/wpCssSelectors.php index aac3339e4d27d..b3099146e226c 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectors.php +++ b/tests/phpunit/tests/html-api/wpCssSelectors.php @@ -42,14 +42,20 @@ public static function data_idents(): array { 'leading surrogate max replacement' => array( '\\dbff ', "\u{fffd}", '' ), 'trailing surrogate min replacement' => array( '\\dc00 ', "\u{fffd}", '' ), 'trailing surrogate max replacement' => array( '\\dfff ', "\u{fffd}", '' ), + 'can start with -ident' => array( '-ident', '-ident', '' ), + 'can start with --anything' => array( '--anything', '--anything', '' ), + 'can start with ---anything' => array( '--_anything', '--_anything', '' ), + 'can start with --1anything' => array( '--1anything', '--1anything', '' ), + 'can start with -\31 23' => array( '-\31 23', '-123', '' ), + 'can start with --\31 23' => array( '--\31 23', '--123', '' ), // Invalid - 'bad start >' => array( '>' ), - 'bad start [' => array( '[' ), - 'bad start #' => array( '#' ), - 'bad start " "' => array( ' ' ), - 'bad start -' => array( '-' ), - 'bad start 1' => array( '-' ), + 'bad start >' => array( '>ident' ), + 'bad start [' => array( '[ident' ), + 'bad start #' => array( '#ident' ), + 'bad start " "' => array( ' ident' ), + 'bad start 1' => array( '1ident' ), + 'bad start -1' => array( '-1ident' ), ); } From 728d798d663d27f5b385d82fe54f3b88544983de Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 25 Nov 2024 18:31:24 +0100 Subject: [PATCH 025/634] Add type selector tests --- .../phpunit/tests/html-api/wpCssSelectors.php | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tests/phpunit/tests/html-api/wpCssSelectors.php b/tests/phpunit/tests/html-api/wpCssSelectors.php index b3099146e226c..694c405c09e0b 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectors.php +++ b/tests/phpunit/tests/html-api/wpCssSelectors.php @@ -149,4 +149,39 @@ public static function data_class_selectors(): array { 'not valid .1foo' => array( '.1foo' ), ); } + + /** + * @ticket TBD + * + * @dataProvider data_type_selectors + */ + public function test_parse_type( string $input, ?string $expected = null, ?string $rest = null ) { + $offset = 0; + $result = WP_CSS_Type_Selector::parse( $input, $offset ); + if ( null === $expected ) { + $this->assertNull( $result ); + } else { + $this->assertSame( $result->ident, $expected ); + $this->assertSame( substr( $input, $offset ), $rest ); + } + } + + /** + * Data provider. + * + * @return array + */ + public static function data_type_selectors(): array { + return array( + 'any *' => array( '* .class', '*', ' .class' ), + 'a' => array( 'a', 'a', '' ), + 'div.class' => array( 'div.class', 'div', '.class' ), + 'custom-type#id' => array( 'custom-type#id', 'custom-type', '#id' ), + + // invalid + '#id' => array( '#id' ), + '.class' => array( '.class' ), + '[attr]' => array( '[attr]' ), + ); + } } From e1e8e098cfa4d0854104760e7e225e265f022064 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 25 Nov 2024 18:31:54 +0100 Subject: [PATCH 026/634] Add docs and remove unreachable line --- .../html-api/class-wp-css-selectors.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index fbccb55a5a0eb..4ea438b95d8ce 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -410,6 +410,13 @@ private function __construct( string $ident ) { $this->ident = $ident; } + /** + * Parse an ID selector + * + * > = + * + * https://www.w3.org/TR/selectors/#grammar + */ public static function parse( string $input, int &$offset ): ?self { $ident = self::parse_hash_token( $input, $offset ); if ( null === $ident ) { @@ -427,6 +434,13 @@ private function __construct( string $ident ) { $this->ident = $ident; } + /** + * Parse a class selector + * + * > = '.' + * + * https://www.w3.org/TR/selectors/#grammar + */ public static function parse( string $input, int &$offset ): ?self { if ( $offset + 1 >= strlen( $input ) || '.' !== $input[ $offset ] ) { return null; @@ -437,7 +451,6 @@ public static function parse( string $input, int &$offset ): ?self { if ( null === $result ) { return null; - $offset = $updated_offset; } $offset = $updated_offset; From 13ac3c11204d31e30455870bff92f0b81ecd3386 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 25 Nov 2024 18:32:17 +0100 Subject: [PATCH 027/634] Add type selector class --- .../html-api/class-wp-css-selectors.php | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 4ea438b95d8ce..4a6b65048b62b 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -457,3 +457,46 @@ public static function parse( string $input, int &$offset ): ?self { return new self( $result ); } } + +final class WP_CSS_Type_Selector extends WP_CSS_Selector_Parser { + /** + * @var string + * + * The type identifier string or '*'. + */ + public $ident; + + private function __construct( string $ident ) { + $this->ident = $ident; + } + + /** + * Parse a type selector + * + * > = | ? '*' + * > = [ | '*' ]? '|' + * > = ? + * + * Namespaces (e.g. |div, *|div, or namespace|div) are not supported, + * so this selector effectively matches * or ident. + * + * https://www.w3.org/TR/selectors/#grammar + */ + public static function parse( string $input, int &$offset ): ?self { + if ( $offset >= strlen( $input ) ) { + return false; + } + + if ( '*' === $input[ $offset ] ) { + ++$offset; + return new self( '*' ); + } + + $result = self::parse_ident( $input, $offset ); + if ( null === $result ) { + return null; + } + + return new self( $result ); + } +} From a3c25e892f059f02d42070d593d03c5199a15e8d Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 25 Nov 2024 19:13:39 +0100 Subject: [PATCH 028/634] Add attribute selector tests --- .../phpunit/tests/html-api/wpCssSelectors.php | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/tests/phpunit/tests/html-api/wpCssSelectors.php b/tests/phpunit/tests/html-api/wpCssSelectors.php index 694c405c09e0b..5d0af28006039 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectors.php +++ b/tests/phpunit/tests/html-api/wpCssSelectors.php @@ -184,4 +184,69 @@ public static function data_type_selectors(): array { '[attr]' => array( '[attr]' ), ); } + + /** + * @ticket TBD + * + * @dataProvider data_attribute_selectors + */ + public function test_parse_attribute( + string $input, + ?string $expected_name = null, + ?string $expected_matcher = null, + ?string $expected_value = null, + ?string $expected_modifier = null, + ?string $rest = null + ) { + $offset = 0; + $result = WP_CSS_Attribute_Selector::parse( $input, $offset ); + if ( null === $expected_name ) { + $this->assertNull( $result ); + } else { + $this->assertSame( $result->name, $expected_name ); + $this->assertSame( $result->matcher, $expected_matcher ); + $this->assertSame( $result->value, $expected_value ); + $this->assertSame( $result->modifier, $expected_modifier ); + $this->assertSame( substr( $input, $offset ), $rest ); + } + } + + /** + * Data provider. + * + * @return array + */ + public static function data_attribute_selectors(): array { + return array( + array( '[href]', 'href', null, null, null, '' ), + array( '[href] type', 'href', null, null, null, ' type' ), + array( '[href]#id', 'href', null, null, null, '#id' ), + array( '[href].class', 'href', null, null, null, '.class' ), + array( '[href][href2]', 'href', null, null, null, '[href2]' ), + array( "[\n href\t\r]", 'href', null, null, null, '' ), + array( '[href=foo]', 'href', WP_CSS_Attribute_Selector::MATCH_EXACT, 'foo', null, '' ), + array( "[href \n = bar ]", WP_CSS_Attribute_Selector::MATCH_EXACT, 'bar', null, '' ), + array( "[href \n ^= baz ]", WP_CSS_Attribute_Selector::MATCH_PREFIXED_BY, 'bar', null, '' ), + array( '[match $= insensitive i]', WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY, 'insensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), + array( '[match|=sensitive s]', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'sensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), + array( '[match="quoted[][]"]', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'quoted[][]', null, '' ), + array( "[match='quoted!{}']", WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'quoted!{}', null, '' ), + array( "[match*='quoted's]", WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'quoted', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), + + // Invalid + array( 'foo' ), + array( '[foo' ), + array( '[#foo]' ), + array( '[*|*]' ), + array( '[ns|*]' ), + array( '[* |att]' ), + array( '[*| att]' ), + array( '[att * =]' ), + array( '[att * =]' ), + array( '[att i]' ), + array( '[att s]' ), + array( '[att="val" I]' ), + array( '[att="val" S]' ), + ); + } } From ad5c600d99ffeb98e92e6678b1476c0a7e02a808 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 25 Nov 2024 19:49:57 +0100 Subject: [PATCH 029/634] improve attr tests --- .../phpunit/tests/html-api/wpCssSelectors.php | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpCssSelectors.php b/tests/phpunit/tests/html-api/wpCssSelectors.php index 5d0af28006039..43c710a6f750c 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectors.php +++ b/tests/phpunit/tests/html-api/wpCssSelectors.php @@ -218,35 +218,35 @@ public function test_parse_attribute( */ public static function data_attribute_selectors(): array { return array( - array( '[href]', 'href', null, null, null, '' ), - array( '[href] type', 'href', null, null, null, ' type' ), - array( '[href]#id', 'href', null, null, null, '#id' ), - array( '[href].class', 'href', null, null, null, '.class' ), - array( '[href][href2]', 'href', null, null, null, '[href2]' ), - array( "[\n href\t\r]", 'href', null, null, null, '' ), - array( '[href=foo]', 'href', WP_CSS_Attribute_Selector::MATCH_EXACT, 'foo', null, '' ), - array( "[href \n = bar ]", WP_CSS_Attribute_Selector::MATCH_EXACT, 'bar', null, '' ), - array( "[href \n ^= baz ]", WP_CSS_Attribute_Selector::MATCH_PREFIXED_BY, 'bar', null, '' ), - array( '[match $= insensitive i]', WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY, 'insensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), - array( '[match|=sensitive s]', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'sensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), - array( '[match="quoted[][]"]', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'quoted[][]', null, '' ), - array( "[match='quoted!{}']", WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'quoted!{}', null, '' ), - array( "[match*='quoted's]", WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'quoted', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), + '[href]' => array( '[href]', 'href', null, null, null, '' ), + '[href] type' => array( '[href] type', 'href', null, null, null, ' type' ), + '[href]#id' => array( '[href]#id', 'href', null, null, null, '#id' ), + '[href].class' => array( '[href].class', 'href', null, null, null, '.class' ), + '[href][href2]' => array( '[href][href2]', 'href', null, null, null, '[href2]' ), + '[\n href\t\r]' => array( "[\n href\t\r]", 'href', null, null, null, '' ), + '[href=foo]' => array( '[href=foo]', 'href', WP_CSS_Attribute_Selector::MATCH_EXACT, 'foo', null, '' ), + '[href \n = bar ]' => array( "[href \n = bar ]", WP_CSS_Attribute_Selector::MATCH_EXACT, 'bar', null, '' ), + '[href \n ^= baz ]' => array( "[href \n ^= baz ]", WP_CSS_Attribute_Selector::MATCH_PREFIXED_BY, 'bar', null, '' ), + '[match $= insensitive i]' => array( '[match $= insensitive i]', WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY, 'insensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), + '[match|=sensitive s]' => array( '[match|=sensitive s]', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'sensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), + '[match="quoted[][]"]' => array( '[match="quoted[][]"]', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'quoted[][]', null, '' ), + "[match='quoted!{}']" => array( "[match='quoted!{}']", WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'quoted!{}', null, '' ), + "[match*='quoted's]" => array( "[match*='quoted's]", WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'quoted', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), // Invalid - array( 'foo' ), - array( '[foo' ), - array( '[#foo]' ), - array( '[*|*]' ), - array( '[ns|*]' ), - array( '[* |att]' ), - array( '[*| att]' ), - array( '[att * =]' ), - array( '[att * =]' ), - array( '[att i]' ), - array( '[att s]' ), - array( '[att="val" I]' ), - array( '[att="val" S]' ), + 'foo' => array( 'foo' ), + '[foo' => array( '[foo' ), + '[#foo]' => array( '[#foo]' ), + '[*|*]' => array( '[*|*]' ), + '[ns|*]' => array( '[ns|*]' ), + '[* |att]' => array( '[* |att]' ), + '[*| att]' => array( '[*| att]' ), + '[att * =]' => array( '[att * =]' ), + '[att * =]' => array( '[att * =]' ), + '[att i]' => array( '[att i]' ), + '[att s]' => array( '[att s]' ), + '[att="val" I]' => array( '[att="val" I]' ), + '[att="val" S]' => array( '[att="val" S]' ), ); } } From 675870497312b388d4992090c7681886b06c919a Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 25 Nov 2024 19:53:06 +0100 Subject: [PATCH 030/634] Fix expectation argument order --- .../phpunit/tests/html-api/wpCssSelectors.php | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpCssSelectors.php b/tests/phpunit/tests/html-api/wpCssSelectors.php index 43c710a6f750c..7bea7c3b34180 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectors.php +++ b/tests/phpunit/tests/html-api/wpCssSelectors.php @@ -78,7 +78,7 @@ public static function test( string $input, &$offset ) { $this->assertNull( $result ); } else { $this->assertSame( $expected, $result, 'Ident did not match.' ); - $this->assertSame( substr( $input, $offset ), $rest, 'Offset was not updated correctly.' ); + $this->assertSame( $rest, substr( $input, $offset ), 'Offset was not updated correctly.' ); } } @@ -93,8 +93,8 @@ public function test_parse_id( string $input, ?string $expected = null, ?string if ( null === $expected ) { $this->assertNull( $result ); } else { - $this->assertSame( $result->ident, $expected ); - $this->assertSame( substr( $input, $offset ), $rest ); + $this->assertSame( $expected, $result->ident ); + $this->assertSame( $rest, substr( $input, $offset ) ); } } @@ -127,8 +127,8 @@ public function test_parse_class( string $input, ?string $expected = null, ?stri if ( null === $expected ) { $this->assertNull( $result ); } else { - $this->assertSame( $result->ident, $expected ); - $this->assertSame( substr( $input, $offset ), $rest ); + $this->assertSame( $expected, $result->ident ); + $this->assertSame( $rest, substr( $input, $offset ) ); } } @@ -161,8 +161,8 @@ public function test_parse_type( string $input, ?string $expected = null, ?strin if ( null === $expected ) { $this->assertNull( $result ); } else { - $this->assertSame( $result->ident, $expected ); - $this->assertSame( substr( $input, $offset ), $rest ); + $this->assertSame( $expected, $result->ident ); + $this->assertSame( $rest, substr( $input, $offset ) ); } } @@ -203,11 +203,11 @@ public function test_parse_attribute( if ( null === $expected_name ) { $this->assertNull( $result ); } else { - $this->assertSame( $result->name, $expected_name ); - $this->assertSame( $result->matcher, $expected_matcher ); - $this->assertSame( $result->value, $expected_value ); - $this->assertSame( $result->modifier, $expected_modifier ); - $this->assertSame( substr( $input, $offset ), $rest ); + $this->assertSame( $expected_name, $result->name ); + $this->assertSame( $expected_matcher, $result->matcher ); + $this->assertSame( $expected_value, $result->value ); + $this->assertSame( $expected_modifier, $result->modifier ); + $this->assertSame( $rest, substr( $input, $offset ) ); } } From e97842cf6665fef97059b71acef61e70ebbdf03e Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 25 Nov 2024 21:31:31 +0100 Subject: [PATCH 031/634] Add test and fix is_ident --- .../html-api/class-wp-css-selectors.php | 2 +- .../phpunit/tests/html-api/wpCssSelectors.php | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 4a6b65048b62b..49b51e51fe81e 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -323,7 +323,7 @@ protected static function is_ident_start_codepoint( string $input, int $offset ) '_' === $input[ $offset ] || ( 'a' <= $input[ $offset ] && $input[ $offset ] <= 'z' ) || ( 'A' <= $input[ $offset ] && $input[ $offset ] <= 'Z' ) || - $input[ $offset ] > '\x7F' + ord( $input[ $offset ] ) > 0x7F ); } diff --git a/tests/phpunit/tests/html-api/wpCssSelectors.php b/tests/phpunit/tests/html-api/wpCssSelectors.php index 7bea7c3b34180..55cd1eafb29c9 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectors.php +++ b/tests/phpunit/tests/html-api/wpCssSelectors.php @@ -48,6 +48,7 @@ public static function data_idents(): array { 'can start with --1anything' => array( '--1anything', '--1anything', '' ), 'can start with -\31 23' => array( '-\31 23', '-123', '' ), 'can start with --\31 23' => array( '--\31 23', '--123', '' ), + 'ident ends before ]' => array( 'ident]', 'ident', ']' ), // Invalid 'bad start >' => array( '>ident' ), @@ -59,6 +60,28 @@ public static function data_idents(): array { ); } + /** + * @ticket TBD + */ + public function test_is_ident_and_is_ident_start() { + $c = new class() extends WP_CSS_Selector_Parser { + public static function parse( string $input, int &$offset ) {} + + public static function test_is_ident( string $input, int $offset ) { + return self::is_ident_codepoint( $input, $offset ); + } + + public static function test_is_ident_start( string $input, int $offset ) { + return self::is_ident_start_codepoint( $input, $offset ); + } + }; + + $this->assertFalse( $c::test_is_ident( '[', 0 ) ); + $this->assertFalse( $c::test_is_ident( ']', 0 ) ); + $this->assertFalse( $c::test_is_ident_start( '[', 0 ) ); + $this->assertFalse( $c::test_is_ident_start( ']', 0 ) ); + } + /** * @ticket TBD * From ef0085631424083dfc217308684c1baac3eea7f8 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 26 Nov 2024 12:36:40 +0100 Subject: [PATCH 032/634] Add parse_string stub --- src/wp-includes/html-api/class-wp-css-selectors.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 49b51e51fe81e..96c4465c2dbd6 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -212,6 +212,11 @@ protected static function parse_ident( string $input, int &$offset ): ?string { return $ident; } + // @todo stub + protected static function parse_string( string $input, int &$offset ): ?string { + return null; + } + /** * Consume an escaped code point. * From 463e799a75d713829f84a988d58595d2ba0923f0 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 26 Nov 2024 12:37:31 +0100 Subject: [PATCH 033/634] Add attribute selector parsing --- .../html-api/class-wp-css-selectors.php | 213 ++++++++++++++++++ 1 file changed, 213 insertions(+) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 96c4465c2dbd6..5067d1c2b87e6 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -505,3 +505,216 @@ public static function parse( string $input, int &$offset ): ?self { return new self( $result ); } } + +final class WP_CSS_Attribute_Selector extends WP_CSS_Selector_Parser { + /** + * [attr=value] + * Represents elements with an attribute name of attr whose value is exactly value. + */ + const MATCH_EXACT = 'MATCH_EXACT'; + + /** + * [attr~=value] + * Represents elements with an attribute name of attr whose value is a + * whitespace-separated list of words, one of which is exactly value. + */ + const MATCH_ONE_OF_EXACT = 'MATCH_ONE_OF_EXACT'; + + /** + * [attr|=value] + * Represents elements with an attribute name of attr whose value can be exactly value or + * can begin with value immediately followed by a hyphen, - (U+002D). It is often used for + * language subcode matches. + */ + const MATCH_EXACT_OR_EXACT_WITH_HYPHEN = 'MATCH_EXACT_OR_EXACT_WITH_HYPHEN'; + + /** + * [attr^=value] + * Represents elements with an attribute name of attr whose value is prefixed (preceded) + * by value. + */ + const MATCH_PREFIXED_BY = 'MATCH_PREFIXED_BY'; + + /** + * [attr$=value] + * Represents elements with an attribute name of attr whose value is suffixed (followed) + * by value. + */ + const MATCH_SUFFIXED_BY = 'MATCH_SUFFIXED_BY'; + + /** + * [attr*=value] + * Represents elements with an attribute name of attr whose value contains at least one + * occurrence of value within the string. + */ + const MATCH_CONTAINS = 'MATCH_CONTAINS'; + + /** + * Modifier for case sensitive matching + * [attr=value s] + */ + const MODIFIER_CASE_SENSITIVE = 'case-sensitive'; + + /** + * Modifier for case insensitive matching + * [attr=value i] + */ + const MODIFIER_CASE_INSENSITIVE = 'case-insensitive'; + + + /** + * The attribute name. + * + * @var string + */ + public $name; + + /** + * The attribute matcher. + * + * @var string|null + */ + public $matcher; + + /** + * The attribute value. + * + * @var string|null + */ + public $value; + + /** + * The attribute modifier. + * + * @var string|null + */ + public $modifier; + + private function __construct( string $name, ?string $matcher = null, ?string $value = null, ?string $modifier = null ) { + $this->name = $name; + $this->matcher = $matcher; + $this->value = $value; + $this->modifier = $modifier; + } + + /** + * Parse a attribute selector + * + * > = '[' ']' | + * > '[' [ | ] ? ']' + * > = [ '~' | '|' | '^' | '$' | '*' ]? '=' + * > = i | s + * > = ? + * + * Namespaces are not supported, so attribute names are effectively identifiers. + * + * https://www.w3.org/TR/selectors/#grammar + */ + public static function parse( string $input, int &$offset ): ?self { + // Need at least 3 bytes [x] + if ( $offset + 2 >= strlen( $input ) ) { + return false; + } + + $updated_offset = $offset; + + if ( '[' !== $input[ $updated_offset ] ) { + return null; + } + ++$updated_offset; + + self::parse_whitespace( $input, $updated_offset ); + $attr_name = self::parse_ident( $input, $updated_offset ); + if ( null === $attr_name ) { + return null; + } + self::parse_whitespace( $input, $updated_offset ); + + if ( $updated_offset >= strlen( $input ) ) { + return null; + } + + if ( ']' === $input[ $updated_offset ] ) { + $offset = $updated_offset + 1; + return new self( $attr_name ); + } + + // need to match at least `=x]` at this point + if ( $updated_offset + 3 >= strlen( $input ) ) { + return null; + } + + if ( '=' === $input[ $updated_offset ] ) { + ++$updated_offset; + $attr_matcher = WP_CSS_Attribute_Selector::MATCH_EXACT; + } elseif ( '=' === $input[ $updated_offset + 1 ] ) { + switch ( $input[ $updated_offset ] ) { + case '~': + $attr_matcher = WP_CSS_Attribute_Selector::MATCH_ONE_OF_EXACT; + $updated_offset += 2; + break; + case '|': + $attr_matcher = WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN; + $updated_offset += 2; + break; + case '^': + $attr_matcher = WP_CSS_Attribute_Selector::MATCH_PREFIXED_BY; + $updated_offset += 2; + break; + case '$': + $attr_matcher = WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY; + $updated_offset += 2; + break; + case '*': + $attr_matcher = WP_CSS_Attribute_Selector::MATCH_CONTAINS; + $updated_offset += 2; + break; + default: + return null; + } + } else { + return null; + } + + self::parse_whitespace( $input, $updated_offset ); + $attr_val = + self::parse_string( $input, $updated_offset ) ?? + self::parse_ident( $input, $updated_offset ); + + if ( null === $attr_val ) { + return null; + } + + self::parse_whitespace( $input, $updated_offset ); + if ( $updated_offset >= strlen( $input ) ) { + return null; + } + + $attr_modifier = null; + switch ( $input[ $updated_offset ] ) { + case 'i': + $attr_modifier = WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE; + ++$updated_offset; + break; + + case 's': + $attr_modifier = WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE; + ++$updated_offset; + break; + } + + if ( null !== $attr_modifier ) { + self::parse_whitespace( $input, $updated_offset ); + if ( $updated_offset >= strlen( $input ) ) { + return null; + } + } + + if ( ']' === $input[ $updated_offset ] ) { + $offset = $updated_offset + 1; + return new self( $attr_name, $attr_matcher, $attr_val, $attr_modifier ); + } + + return null; + } +} From 0f5b28cc5ed226f23ea38a3025ae5403b9b24bff Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 26 Nov 2024 12:45:17 +0100 Subject: [PATCH 034/634] Fix test expectations --- tests/phpunit/tests/html-api/wpCssSelectors.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpCssSelectors.php b/tests/phpunit/tests/html-api/wpCssSelectors.php index 55cd1eafb29c9..ae3c3e80c4f90 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectors.php +++ b/tests/phpunit/tests/html-api/wpCssSelectors.php @@ -248,13 +248,13 @@ public static function data_attribute_selectors(): array { '[href][href2]' => array( '[href][href2]', 'href', null, null, null, '[href2]' ), '[\n href\t\r]' => array( "[\n href\t\r]", 'href', null, null, null, '' ), '[href=foo]' => array( '[href=foo]', 'href', WP_CSS_Attribute_Selector::MATCH_EXACT, 'foo', null, '' ), - '[href \n = bar ]' => array( "[href \n = bar ]", WP_CSS_Attribute_Selector::MATCH_EXACT, 'bar', null, '' ), - '[href \n ^= baz ]' => array( "[href \n ^= baz ]", WP_CSS_Attribute_Selector::MATCH_PREFIXED_BY, 'bar', null, '' ), - '[match $= insensitive i]' => array( '[match $= insensitive i]', WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY, 'insensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), - '[match|=sensitive s]' => array( '[match|=sensitive s]', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'sensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), - '[match="quoted[][]"]' => array( '[match="quoted[][]"]', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'quoted[][]', null, '' ), - "[match='quoted!{}']" => array( "[match='quoted!{}']", WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'quoted!{}', null, '' ), - "[match*='quoted's]" => array( "[match*='quoted's]", WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'quoted', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), + '[href \n = bar ]' => array( "[href \n = bar ]", 'href', WP_CSS_Attribute_Selector::MATCH_EXACT, 'bar', null, '' ), + '[href \n ^= baz ]' => array( "[href \n ^= baz ]", 'href', WP_CSS_Attribute_Selector::MATCH_PREFIXED_BY, 'baz', null, '' ), + '[match $= insensitive i]' => array( '[match $= insensitive i]', 'match', WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY, 'insensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), + '[match|=sensitive s]' => array( '[match|=sensitive s]', 'match', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'sensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), + '[match="quoted[][]"]' => array( '[match="quoted[][]"]', 'match', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'quoted[][]', null, '' ), + "[match='quoted!{}']" => array( "[match='quoted!{}']", 'match', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'quoted!{}', null, '' ), + "[match*='quoted's]" => array( "[match*='quoted's]", 'match', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'quoted', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), // Invalid 'foo' => array( 'foo' ), From f4a491ae52aaaf4807e9eb9c9b6c671bae105abf Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 26 Nov 2024 18:11:25 +0100 Subject: [PATCH 035/634] More and improved attribute tests --- .../phpunit/tests/html-api/wpCssSelectors.php | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpCssSelectors.php b/tests/phpunit/tests/html-api/wpCssSelectors.php index ae3c3e80c4f90..4557ee1a5b3c4 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectors.php +++ b/tests/phpunit/tests/html-api/wpCssSelectors.php @@ -252,24 +252,28 @@ public static function data_attribute_selectors(): array { '[href \n ^= baz ]' => array( "[href \n ^= baz ]", 'href', WP_CSS_Attribute_Selector::MATCH_PREFIXED_BY, 'baz', null, '' ), '[match $= insensitive i]' => array( '[match $= insensitive i]', 'match', WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY, 'insensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), '[match|=sensitive s]' => array( '[match|=sensitive s]', 'match', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'sensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), - '[match="quoted[][]"]' => array( '[match="quoted[][]"]', 'match', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'quoted[][]', null, '' ), - "[match='quoted!{}']" => array( "[match='quoted!{}']", 'match', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'quoted!{}', null, '' ), - "[match*='quoted's]" => array( "[match*='quoted's]", 'match', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'quoted', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), + '[match~="quoted[][]"]' => array( '[match~="quoted[][]"]', 'match', WP_CSS_Attribute_Selector::MATCH_ONE_OF_EXACT, 'quoted[][]', null, '' ), + "[match$='quoted!{}']" => array( "[match$='quoted!{}']", 'match', WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY, 'quoted!{}', null, '' ), + "[match*='quoted's]" => array( "[match*='quoted's]", 'match', WP_CSS_Attribute_Selector::MATCH_CONTAINS, 'quoted', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), + + '[escape-nl="foo\\nbar"]' => array( "[escape-nl='foo\\\nbar']", 'escape-nl', WP_CSS_Attribute_Selector::MATCH_EXACT, 'foobar', null, '' ), + '[escape-seq="\\31 23"]' => array( "[escape-seq='\\31 23']", 'escape-seq', WP_CSS_Attribute_Selector::MATCH_EXACT, '123', null, '' ), // Invalid - 'foo' => array( 'foo' ), - '[foo' => array( '[foo' ), - '[#foo]' => array( '[#foo]' ), - '[*|*]' => array( '[*|*]' ), - '[ns|*]' => array( '[ns|*]' ), - '[* |att]' => array( '[* |att]' ), - '[*| att]' => array( '[*| att]' ), - '[att * =]' => array( '[att * =]' ), - '[att * =]' => array( '[att * =]' ), - '[att i]' => array( '[att i]' ), - '[att s]' => array( '[att s]' ), - '[att="val" I]' => array( '[att="val" I]' ), - '[att="val" S]' => array( '[att="val" S]' ), + 'Invalid: foo' => array( 'foo' ), + 'Invalid: [foo' => array( '[foo' ), + 'Invalid: [#foo]' => array( '[#foo]' ), + 'Invalid: [*|*]' => array( '[*|*]' ), + 'Invalid: [ns|*]' => array( '[ns|*]' ), + 'Invalid: [* |att]' => array( '[* |att]' ), + 'Invalid: [*| att]' => array( '[*| att]' ), + 'Invalid: [att * =]' => array( '[att * =]' ), + 'Invalid: [att * =]' => array( '[att * =]' ), + 'Invalid: [att i]' => array( '[att i]' ), + 'Invalid: [att s]' => array( '[att s]' ), + 'Invalid: [att="val" I]' => array( '[att="val" I]' ), + 'Invalid: [att="val" S]' => array( '[att="val" S]' ), + "Invalid: [att='val\\n']" => array( "[att='val\n']" ), ); } } From b680b1b8e5f69bf17490934761899452fc935826 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 26 Nov 2024 18:11:52 +0100 Subject: [PATCH 036/634] Implement parse_string --- .../html-api/class-wp-css-selectors.php | 84 ++++++++++++++++++- 1 file changed, 82 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 5067d1c2b87e6..c1c3e35fc9ae1 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -212,9 +212,89 @@ protected static function parse_ident( string $input, int &$offset ): ?string { return $ident; } - // @todo stub + /** + * Parse a string token + * + * > 4.3.5. Consume a string token + * > This section describes how to consume a string token from a stream of code points. It returns either a or . + * > + * > This algorithm may be called with an ending code point, which denotes the code point that ends the string. If an ending code point is not specified, the current input code point is used. + * > + * > Initially create a with its value set to the empty string. + * > + * > Repeatedly consume the next input code point from the stream: + * > + * > ending code point + * > Return the . + * > EOF + * > This is a parse error. Return the . + * > newline + * > This is a parse error. Reconsume the current input code point, create a , and return it. + * > U+005C REVERSE SOLIDUS (\) + * > If the next input code point is EOF, do nothing. + * > Otherwise, if the next input code point is a newline, consume it. + * > Otherwise, (the stream starts with a valid escape) consume an escaped code point and append the returned code point to the ’s value. + * > + * > anything else + * > Append the current input code point to the ’s value. + * + * https://www.w3.org/TR/css-syntax-3/#consume-string-token + * + * This implementation will never return a because + * the is not a part of the selector grammar. That + * case is treated as failure to parse and null is returned. + */ protected static function parse_string( string $input, int &$offset ): ?string { - return null; + if ( $offset + 1 >= strlen( $input ) ) { + return null; + } + + $ending_code_point = $input[ $offset ]; + if ( '"' !== $ending_code_point && "'" !== $ending_code_point ) { + return null; + } + + $string_token = ''; + + $stop_characters = "\\\n{$ending_code_point}"; + + $updated_offset = $offset + 1; + while ( $updated_offset < strlen( $input ) ) { + switch ( $input[ $updated_offset ] ) { + case '\\': + if ( $updated_offset + 1 >= strlen( $input ) ) { + break; + } + ++$updated_offset; + if ( "\n" === $input[ $updated_offset ] ) { + ++$updated_offset; + break; + } else { + $string_token .= self::consume_escaped_codepoint( $input, $updated_offset ); + } + break; + + /* + * This case would return a . + * The is not a part of the selector grammar + * so we do not return it and instead treat this as a + * failure to parse a string token. + */ + case "\n": + return null; + + case $ending_code_point: + ++$updated_offset; + break 2; + + default: + $string_token .= $input[ $updated_offset ]; + ++$updated_offset; + } + } + + $offset = $updated_offset; + return $string_token; } /** From e7da05f238008dd987f176672565acfeacbd86b4 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 26 Nov 2024 18:25:20 +0100 Subject: [PATCH 037/634] Add string parse tests --- .../phpunit/tests/html-api/wpCssSelectors.php | 72 ++++++++++++++++++- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpCssSelectors.php b/tests/phpunit/tests/html-api/wpCssSelectors.php index 4557ee1a5b3c4..96f2fa96dcb7f 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectors.php +++ b/tests/phpunit/tests/html-api/wpCssSelectors.php @@ -9,8 +9,6 @@ * @since TBD * * @group html-api - * - * @coversDefaultClass WP_CSS_Selectors */ class Tests_HtmlApi_WpCssSelectors extends WP_UnitTestCase { /** @@ -62,6 +60,9 @@ public static function data_idents(): array { /** * @ticket TBD + * + * @covers WP_CSS_Selector_Parser::is_ident_codepoint + * @covers WP_CSS_Selector_Parser::is_ident_start_codepoint */ public function test_is_ident_and_is_ident_start() { $c = new class() extends WP_CSS_Selector_Parser { @@ -86,6 +87,8 @@ public static function test_is_ident_start( string $input, int $offset ) { * @ticket TBD * * @dataProvider data_idents + * + * @covers WP_CSS_Selector_Parser::parse_ident */ public function test_parse_ident( string $input, ?string $expected = null, ?string $rest = null ) { $c = new class() extends WP_CSS_Selector_Parser { @@ -105,10 +108,69 @@ public static function test( string $input, &$offset ) { } } + /** + * @ticket TBD + * + * @dataProvider data_strings + * + * @covers WP_CSS_Selector_Parser::parse_string + */ + public function test_parse_string( string $input, ?string $expected = null, ?string $rest = null ) { + $c = new class() extends WP_CSS_Selector_Parser { + public static function parse( string $input, int &$offset ) {} + public static function test( string $input, &$offset ) { + return self::parse_string( $input, $offset ); + } + }; + + $offset = 0; + $result = $c::test( $input, $offset ); + if ( null === $expected ) { + $this->assertNull( $result ); + } else { + $this->assertSame( $expected, $result, 'String did not match.' ); + $this->assertSame( $rest, substr( $input, $offset ), 'Offset was not updated correctly.' ); + } + } + + /** + * Data provider. + * + * @return array + */ + public static function data_strings(): array { + return array( + '"foo"' => array( '"foo"', 'foo', '' ), + '"foo"after' => array( '"foo"after', 'foo', 'after' ), + '"foo""two"' => array( '"foo""two"', 'foo', '"two"' ), + '"foo"\'two\'' => array( '"foo"\'two\'', 'foo', "'two'" ), + + "'foo'" => array( "'foo'", 'foo', '' ), + "'foo'after" => array( "'foo'after", 'foo', 'after' ), + "'foo'\"two\"" => array( "'foo'\"two\"", 'foo', '"two"' ), + "'foo''two'" => array( "'foo''two'", 'foo', "'two'" ), + + "'foo\\nbar'" => array( "'foo\\\nbar'", 'foobar', '' ), + "'foo\\31 23'" => array( "'foo\\31 23'", 'foo123', '' ), + "'foo\\31\\n23'" => array( "'foo\\31\n23'", 'foo123', '' ), + "'foo\\31\\t23'" => array( "'foo\\31\t23'", 'foo123', '' ), + "'foo\\00003123'" => array( "'foo\\00003123'", 'foo123', '' ), + + // Invalid + "Invalid: 'newline\\n'" => array( "'newline\n'" ), + 'Invalid: foo' => array( 'foo' ), + 'Invalid: \\"' => array( '\\"' ), + 'Invalid: .foo' => array( '.foo' ), + 'Invalid: #foo' => array( '#foo' ), + ); + } + /** * @ticket TBD * * @dataProvider data_id_selectors + * + * @covers WP_CSS_ID_Selector::parse */ public function test_parse_id( string $input, ?string $expected = null, ?string $rest = null ) { $offset = 0; @@ -143,6 +205,8 @@ public static function data_id_selectors(): array { * @ticket TBD * * @dataProvider data_class_selectors + * + * @covers WP_CSS_Class_Selector::parse */ public function test_parse_class( string $input, ?string $expected = null, ?string $rest = null ) { $offset = 0; @@ -177,6 +241,8 @@ public static function data_class_selectors(): array { * @ticket TBD * * @dataProvider data_type_selectors + * + * @covers WP_CSS_Type_Selector::parse */ public function test_parse_type( string $input, ?string $expected = null, ?string $rest = null ) { $offset = 0; @@ -212,6 +278,8 @@ public static function data_type_selectors(): array { * @ticket TBD * * @dataProvider data_attribute_selectors + * + * @covers WP_CSS_Attribute_Selector::parse */ public function test_parse_attribute( string $input, From d5e7e6087aab9f58905aa3c5993a5357efe812e1 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 26 Nov 2024 18:26:01 +0100 Subject: [PATCH 038/634] Remove covers annotations --- tests/phpunit/tests/html-api/wpCssSelectors.php | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpCssSelectors.php b/tests/phpunit/tests/html-api/wpCssSelectors.php index 96f2fa96dcb7f..7c5cdca447bbe 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectors.php +++ b/tests/phpunit/tests/html-api/wpCssSelectors.php @@ -60,9 +60,6 @@ public static function data_idents(): array { /** * @ticket TBD - * - * @covers WP_CSS_Selector_Parser::is_ident_codepoint - * @covers WP_CSS_Selector_Parser::is_ident_start_codepoint */ public function test_is_ident_and_is_ident_start() { $c = new class() extends WP_CSS_Selector_Parser { @@ -87,8 +84,6 @@ public static function test_is_ident_start( string $input, int $offset ) { * @ticket TBD * * @dataProvider data_idents - * - * @covers WP_CSS_Selector_Parser::parse_ident */ public function test_parse_ident( string $input, ?string $expected = null, ?string $rest = null ) { $c = new class() extends WP_CSS_Selector_Parser { @@ -112,8 +107,6 @@ public static function test( string $input, &$offset ) { * @ticket TBD * * @dataProvider data_strings - * - * @covers WP_CSS_Selector_Parser::parse_string */ public function test_parse_string( string $input, ?string $expected = null, ?string $rest = null ) { $c = new class() extends WP_CSS_Selector_Parser { @@ -169,8 +162,6 @@ public static function data_strings(): array { * @ticket TBD * * @dataProvider data_id_selectors - * - * @covers WP_CSS_ID_Selector::parse */ public function test_parse_id( string $input, ?string $expected = null, ?string $rest = null ) { $offset = 0; @@ -205,8 +196,6 @@ public static function data_id_selectors(): array { * @ticket TBD * * @dataProvider data_class_selectors - * - * @covers WP_CSS_Class_Selector::parse */ public function test_parse_class( string $input, ?string $expected = null, ?string $rest = null ) { $offset = 0; @@ -241,8 +230,6 @@ public static function data_class_selectors(): array { * @ticket TBD * * @dataProvider data_type_selectors - * - * @covers WP_CSS_Type_Selector::parse */ public function test_parse_type( string $input, ?string $expected = null, ?string $rest = null ) { $offset = 0; @@ -278,8 +265,6 @@ public static function data_type_selectors(): array { * @ticket TBD * * @dataProvider data_attribute_selectors - * - * @covers WP_CSS_Attribute_Selector::parse */ public function test_parse_attribute( string $input, From 08187c6858d95503d0e11eed6832045a68579f8a Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 26 Nov 2024 18:32:55 +0100 Subject: [PATCH 039/634] Remove unused line --- src/wp-includes/html-api/class-wp-css-selectors.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index c1c3e35fc9ae1..3a4c0a7577679 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -256,8 +256,6 @@ protected static function parse_string( string $input, int &$offset ): ?string { $string_token = ''; - $stop_characters = "\\\n{$ending_code_point}"; - $updated_offset = $offset + 1; while ( $updated_offset < strlen( $input ) ) { switch ( $input[ $updated_offset ] ) { From 5a5066ce52335b330a57441b765ed9cc33184467 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 26 Nov 2024 19:32:21 +0100 Subject: [PATCH 040/634] Improve tests for 100% coverage on parse methods --- .../phpunit/tests/html-api/wpCssSelectors.php | 75 +++++++++++-------- 1 file changed, 42 insertions(+), 33 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpCssSelectors.php b/tests/phpunit/tests/html-api/wpCssSelectors.php index 7c5cdca447bbe..7b6e5ce79a365 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectors.php +++ b/tests/phpunit/tests/html-api/wpCssSelectors.php @@ -49,12 +49,14 @@ public static function data_idents(): array { 'ident ends before ]' => array( 'ident]', 'ident', ']' ), // Invalid - 'bad start >' => array( '>ident' ), - 'bad start [' => array( '[ident' ), - 'bad start #' => array( '#ident' ), - 'bad start " "' => array( ' ident' ), - 'bad start 1' => array( '1ident' ), - 'bad start -1' => array( '-1ident' ), + 'Invalid: (empty string)' => array( '' ), + 'Invalid: bad start >' => array( '>ident' ), + 'Invalid: bad start [' => array( '[ident' ), + 'Invalid: bad start #' => array( '#ident' ), + 'Invalid: bad start " "' => array( ' ident' ), + 'Invalid: bad start 1' => array( '1ident' ), + 'Invalid: bad start -1' => array( '-1ident' ), + 'Invalid: bad start -' => array( '-' ), ); } @@ -133,28 +135,31 @@ public static function test( string $input, &$offset ) { */ public static function data_strings(): array { return array( - '"foo"' => array( '"foo"', 'foo', '' ), - '"foo"after' => array( '"foo"after', 'foo', 'after' ), - '"foo""two"' => array( '"foo""two"', 'foo', '"two"' ), - '"foo"\'two\'' => array( '"foo"\'two\'', 'foo', "'two'" ), + '"foo"' => array( '"foo"', 'foo', '' ), + '"foo"after' => array( '"foo"after', 'foo', 'after' ), + '"foo""two"' => array( '"foo""two"', 'foo', '"two"' ), + '"foo"\'two\'' => array( '"foo"\'two\'', 'foo', "'two'" ), - "'foo'" => array( "'foo'", 'foo', '' ), - "'foo'after" => array( "'foo'after", 'foo', 'after' ), - "'foo'\"two\"" => array( "'foo'\"two\"", 'foo', '"two"' ), - "'foo''two'" => array( "'foo''two'", 'foo', "'two'" ), + "'foo'" => array( "'foo'", 'foo', '' ), + "'foo'after" => array( "'foo'after", 'foo', 'after' ), + "'foo'\"two\"" => array( "'foo'\"two\"", 'foo', '"two"' ), + "'foo''two'" => array( "'foo''two'", 'foo', "'two'" ), - "'foo\\nbar'" => array( "'foo\\\nbar'", 'foobar', '' ), - "'foo\\31 23'" => array( "'foo\\31 23'", 'foo123', '' ), - "'foo\\31\\n23'" => array( "'foo\\31\n23'", 'foo123', '' ), - "'foo\\31\\t23'" => array( "'foo\\31\t23'", 'foo123', '' ), - "'foo\\00003123'" => array( "'foo\\00003123'", 'foo123', '' ), + "'foo\\nbar'" => array( "'foo\\\nbar'", 'foobar', '' ), + "'foo\\31 23'" => array( "'foo\\31 23'", 'foo123', '' ), + "'foo\\31\\n23'" => array( "'foo\\31\n23'", 'foo123', '' ), + "'foo\\31\\t23'" => array( "'foo\\31\t23'", 'foo123', '' ), + "'foo\\00003123'" => array( "'foo\\00003123'", 'foo123', '' ), + + "'foo\\" => array( "'foo\\", 'foo', '' ), // Invalid - "Invalid: 'newline\\n'" => array( "'newline\n'" ), - 'Invalid: foo' => array( 'foo' ), - 'Invalid: \\"' => array( '\\"' ), - 'Invalid: .foo' => array( '.foo' ), - 'Invalid: #foo' => array( '#foo' ), + 'Invalid: (empty string)' => array( '' ), + "Invalid: 'newline\\n'" => array( "'newline\n'" ), + 'Invalid: foo' => array( 'foo' ), + 'Invalid: \\"' => array( '\\"' ), + 'Invalid: .foo' => array( '.foo' ), + 'Invalid: #foo' => array( '#foo' ), ); } @@ -249,15 +254,16 @@ public function test_parse_type( string $input, ?string $expected = null, ?strin */ public static function data_type_selectors(): array { return array( - 'any *' => array( '* .class', '*', ' .class' ), - 'a' => array( 'a', 'a', '' ), - 'div.class' => array( 'div.class', 'div', '.class' ), - 'custom-type#id' => array( 'custom-type#id', 'custom-type', '#id' ), + 'any *' => array( '* .class', '*', ' .class' ), + 'a' => array( 'a', 'a', '' ), + 'div.class' => array( 'div.class', 'div', '.class' ), + 'custom-type#id' => array( 'custom-type#id', 'custom-type', '#id' ), - // invalid - '#id' => array( '#id' ), - '.class' => array( '.class' ), - '[attr]' => array( '[attr]' ), + // Invalid + 'Invalid: (empty string)' => array( '' ), + 'Invalid: #id' => array( '#id' ), + 'Invalid: .class' => array( '.class' ), + 'Invalid: [attr]' => array( '[attr]' ), ); } @@ -313,6 +319,7 @@ public static function data_attribute_selectors(): array { '[escape-seq="\\31 23"]' => array( "[escape-seq='\\31 23']", 'escape-seq', WP_CSS_Attribute_Selector::MATCH_EXACT, '123', null, '' ), // Invalid + 'Invalid: (empty string)' => array( '' ), 'Invalid: foo' => array( 'foo' ), 'Invalid: [foo' => array( '[foo' ), 'Invalid: [#foo]' => array( '[#foo]' ), @@ -321,12 +328,14 @@ public static function data_attribute_selectors(): array { 'Invalid: [* |att]' => array( '[* |att]' ), 'Invalid: [*| att]' => array( '[*| att]' ), 'Invalid: [att * =]' => array( '[att * =]' ), - 'Invalid: [att * =]' => array( '[att * =]' ), + 'Invalid: [att+=val]' => array( '[att+=val]' ), + 'Invalid: [att=val ' => array( '[att=val ' ), 'Invalid: [att i]' => array( '[att i]' ), 'Invalid: [att s]' => array( '[att s]' ), 'Invalid: [att="val" I]' => array( '[att="val" I]' ), 'Invalid: [att="val" S]' => array( '[att="val" S]' ), "Invalid: [att='val\\n']" => array( "[att='val\n']" ), + 'Invalid: [att=val i ' => array( '[att=val i ' ), ); } } From 2f8bd19efec5fb4f5f6cabd51d7173642d79af34 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 26 Nov 2024 19:33:01 +0100 Subject: [PATCH 041/634] Improve documentation --- .../html-api/class-wp-css-selectors.php | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 3a4c0a7577679..669c74c1b676d 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -260,10 +260,10 @@ protected static function parse_string( string $input, int &$offset ): ?string { while ( $updated_offset < strlen( $input ) ) { switch ( $input[ $updated_offset ] ) { case '\\': - if ( $updated_offset + 1 >= strlen( $input ) ) { + ++$updated_offset; + if ( $updated_offset >= strlen( $input ) ) { break; } - ++$updated_offset; if ( "\n" === $input[ $updated_offset ] ) { ++$updated_offset; break; @@ -386,6 +386,11 @@ protected static function next_two_are_valid_escape( string $input, int $offset } /** + * Check if the next code point is an "ident start code point". + * + * Caution! This method does not do any bounds checking, it should not be passed + * a string with an offset that is out of bounds. + * * > ident-start code point * > A letter, a non-ASCII code point, or U+005F LOW LINE (_). * > uppercase letter @@ -396,12 +401,10 @@ protected static function next_two_are_valid_escape( string $input, int $offset * > An uppercase letter or a lowercase letter. * > non-ASCII code point * > A code point with a value equal to or greater than U+0080 . + * + * https://www.w3.org/TR/css-syntax-3/#ident-start-code-point */ protected static function is_ident_start_codepoint( string $input, int $offset ): bool { - if ( $offset >= strlen( $input ) ) { - return false; - } - return ( '_' === $input[ $offset ] || ( 'a' <= $input[ $offset ] && $input[ $offset ] <= 'z' ) || @@ -411,10 +414,17 @@ protected static function is_ident_start_codepoint( string $input, int $offset ) } /** + * Check if the next code point is an "ident code point". + * + * Caution! This method does not do any bounds checking, it should not be passed + * a string with an offset that is out of bounds. + * * > ident code point * > An ident-start code point, a digit, or U+002D HYPHEN-MINUS (-). * > digit * > A code point between U+0030 DIGIT ZERO (0) and U+0039 DIGIT NINE (9) inclusive. + * + * https://www.w3.org/TR/css-syntax-3/#ident-code-point */ protected static function is_ident_codepoint( string $input, int $offset ): bool { return '-' === $input[ $offset ] || From 8b0ac551e7694d3de921d84e60afe372583558b8 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 26 Nov 2024 19:37:26 +0100 Subject: [PATCH 042/634] Fix parse return type and return annotations --- .../html-api/class-wp-css-selectors.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 669c74c1b676d..6a80ca2e42b7c 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -186,6 +186,8 @@ protected static function parse_hash_token( string $input, int &$offset ): ?stri * > Reconsume the current input code point. Return result. * * https://www.w3.org/TR/css-syntax-3/#consume-name + * + * @return string|null */ protected static function parse_ident( string $input, int &$offset ): ?string { if ( ! self::check_if_three_code_points_would_start_an_ident_sequence( $input, $offset ) ) { @@ -243,6 +245,8 @@ protected static function parse_ident( string $input, int &$offset ): ?string { * This implementation will never return a because * the is not a part of the selector grammar. That * case is treated as failure to parse and null is returned. + * + * @return string|null */ protected static function parse_string( string $input, int &$offset ): ?string { if ( $offset + 1 >= strlen( $input ) ) { @@ -509,6 +513,8 @@ private function __construct( string $ident ) { * > = * * https://www.w3.org/TR/selectors/#grammar + * + * @return self|null */ public static function parse( string $input, int &$offset ): ?self { $ident = self::parse_hash_token( $input, $offset ); @@ -533,6 +539,8 @@ private function __construct( string $ident ) { * > = '.' * * https://www.w3.org/TR/selectors/#grammar + * + * @return self|null */ public static function parse( string $input, int &$offset ): ?self { if ( $offset + 1 >= strlen( $input ) || '.' !== $input[ $offset ] ) { @@ -574,10 +582,12 @@ private function __construct( string $ident ) { * so this selector effectively matches * or ident. * * https://www.w3.org/TR/selectors/#grammar + * + * @return self|null */ public static function parse( string $input, int &$offset ): ?self { if ( $offset >= strlen( $input ) ) { - return false; + return null; } if ( '*' === $input[ $offset ] ) { @@ -697,11 +707,13 @@ private function __construct( string $name, ?string $matcher = null, ?string $va * Namespaces are not supported, so attribute names are effectively identifiers. * * https://www.w3.org/TR/selectors/#grammar + * + * @return self|null */ public static function parse( string $input, int &$offset ): ?self { // Need at least 3 bytes [x] if ( $offset + 2 >= strlen( $input ) ) { - return false; + return null; } $updated_offset = $offset; From dffcac6ed016f727aaacfb192f151f5c3cb3c67f Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 27 Nov 2024 17:07:48 +0100 Subject: [PATCH 043/634] Update documentation links and grammar --- .../html-api/class-wp-css-selectors.php | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 6a80ca2e42b7c..264f684692f17 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -19,7 +19,29 @@ * is invalid or unsupported. * * A subset of the CSS selector grammar is supported. The grammar is defined in the CSS Syntax - * specification, which is available at https://www.w3.org/TR/css-syntax-3/. + * specification, which is available at {@link https://www.w3.org/TR/selectors/#grammar}. + * + * @todo Review this grammar, especially the complex selector for accurate support information. + * The supported grammar is: + * + * = + * = # + * = # + * = # + * = [ ? ]* + * = [ ? * ]! + * = | + * = '>' | '+' | '~' | [ '|' '|' ] + * = | '*' + * = | | + * = + * = '.' + * = '[' ']' | + * '[' [ | ] ? ']' + * = [ '~' | '|' | '^' | '$' | '*' ]? '=' + * = i | s + * + * @link https://www.w3.org/TR/selectors/#grammar Refer to the grammar for more details. * * Supported selector syntax: * - Type selectors (tag names, e.g. `div`) @@ -43,10 +65,10 @@ * * @access private * - * @see https://www.w3.org/TR/css-syntax-3/#consume-a-token - * @see https://www.w3.org/tr/selectors/#parse-selector - * @see https://www.w3.org/TR/selectors-api2/ - * @see https://www.w3.org/TR/selectors-4/ + * @see {@link https://www.w3.org/TR/css-syntax-3/} + * @see {@link https://www.w3.org/tr/selectors/} + * @see {@link https://www.w3.org/TR/selectors-api2/} + * @see {@link https://www.w3.org/TR/selectors-4/} * */ class WP_CSS_Selectors { From 9f81744aa7bc68fda9269d48251fa13fb2223519 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 27 Nov 2024 20:29:56 +0100 Subject: [PATCH 044/634] Update documentation and class name --- src/wp-includes/html-api/class-wp-css-selectors.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 264f684692f17..d9bbc4b9235c8 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -14,7 +14,7 @@ * * This class is designed for internal use by the HTML processor. * - * This class is instantiated via the `WP_CSS_Selector::from_selector( string $selector )` method. + * This class is instantiated via the `WP_CSS_Selector_List::from_selector( string $selector )` method. * It accepts a CSS selector string and returns an instance of itself or `null` if the selector * is invalid or unsupported. * @@ -27,10 +27,8 @@ * = * = # * = # - * = # * = [ ? ]* * = [ ? * ]! - * = | * = '>' | '+' | '~' | [ '|' '|' ] * = | '*' * = | | @@ -71,7 +69,7 @@ * @see {@link https://www.w3.org/TR/selectors-4/} * */ -class WP_CSS_Selectors { +class WP_CSS_Selector_List { private $selectors; private function __construct( array $selectors ) { @@ -131,7 +129,7 @@ private static function parse( string $input ) { } } if ( count( $selectors ) ) { - return new WP_CSS_Selectors( $selectors ); + return new WP_CSS_Selector_List( $selectors ); } return null; } From d4c6f382dc246e151dc688a70daf88ad8a9f7916 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 27 Nov 2024 20:30:12 +0100 Subject: [PATCH 045/634] Add selector class --- .../html-api/class-wp-css-selectors.php | 64 +++++++++++++++++++ .../phpunit/tests/html-api/wpCssSelectors.php | 18 ++++++ 2 files changed, 82 insertions(+) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index d9bbc4b9235c8..8d8ec35de98b6 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -838,3 +838,67 @@ public static function parse( string $input, int &$offset ): ?self { return null; } } + +/** + * This corresponds to in the grammar. + */ +final class WP_CSS_Selector extends WP_CSS_Selector_Parser { + + /** @var WP_CSS_Type_Selector|null */ + public $type_selector; + + /** @var array|null */ + public $subclass_selectors; + + private function __construct( ?WP_CSS_Type_Selector $type_selector, array $subclass_selectors ) { + $this->type_selector = $type_selector; + $this->subclass_selectors = array() === $subclass_selectors ? null : $subclass_selectors; + } + + /** + * Parses a selector string into a `WP_CSS_Selector` object. + * + * > = [ ? * ]! + * + * @param string $input The selector string to parse. + * @return WP_CSS_Selector|null The parsed selector, or `null` if the selector is invalid or unsupported. + */ + public static function parse( string $input, int &$offset ): ?self { + if ( $offset >= strlen( $input ) ) { + return null; + } + + $updated_offset = $offset; + $type_selector = WP_CSS_Type_Selector::parse( $input, $updated_offset ); + + $subclass_selectors = array(); + $last_parsed_subclass_selector = self::parse_subclass_selector( $input, $updated_offset ); + while ( null !== $last_parsed_subclass_selector ) { + $subclass_selectors[] = $last_parsed_subclass_selector; + $last_parsed_subclass_selector = self::parse_subclass_selector( $input, $updated_offset ); + } + + if ( null !== $type_selector || array() !== $subclass_selectors ) { + $offset = $updated_offset; + return new self( $type_selector, $subclass_selectors ); + } + } + + /** + * @return WP_CSS_ID_Selector|WP_CSS_Class_Selector|WP_CSS_Attribute_Selector|null + */ + private static function parse_subclass_selector( string $input, int &$offset ) { + if ( $offset >= strlen( $input ) ) { + return null; + } + + $next_char = $input[ $offset ]; + return '.' === $next_char ? + WP_CSS_Class_Selector::parse( $input, $offset ) : ( + '#' === $next_char ? + WP_CSS_ID_Selector::parse( $input, $offset ) : ( + '[' === $next_char ? + WP_CSS_Attribute_Selector::parse( $input, $offset ) : + null ) ); + } +} diff --git a/tests/phpunit/tests/html-api/wpCssSelectors.php b/tests/phpunit/tests/html-api/wpCssSelectors.php index 7b6e5ce79a365..180bee4f53c05 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectors.php +++ b/tests/phpunit/tests/html-api/wpCssSelectors.php @@ -338,4 +338,22 @@ public static function data_attribute_selectors(): array { 'Invalid: [att=val i ' => array( '[att=val i ' ), ); } + + /** + * @ticket TBD + */ + public function test_parse_selector() { + $input = 'el.foo#bar[baz=quux] > .child'; + $offset = 0; + $sel = WP_CSS_Selector::parse( $input, $offset ); + + $this->assertSame( $sel->type_selector->ident, 'el' ); + $this->assertSame( count( $sel->subclass_selectors ), 3 ); + $this->assertSame( $sel->subclass_selectors[0]->ident, 'foo' ); + $this->assertSame( $sel->subclass_selectors[1]->ident, 'bar' ); + $this->assertSame( $sel->subclass_selectors[2]->name, 'baz' ); + $this->assertSame( $sel->subclass_selectors[2]->matcher, WP_CSS_Attribute_Selector::MATCH_EXACT ); + $this->assertSame( $sel->subclass_selectors[2]->value, 'quux' ); + $this->assertSame( ' > .child', substr( $input, $offset ) ); + } } From 6432056bd38a8aebb94c51b6bfe6ac87353181c7 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 27 Nov 2024 21:01:43 +0100 Subject: [PATCH 046/634] Implement complex selector --- .../html-api/class-wp-css-selectors.php | 87 +++++++++++++++++-- .../phpunit/tests/html-api/wpCssSelectors.php | 34 ++++++-- 2 files changed, 106 insertions(+), 15 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 8d8ec35de98b6..8ccec5de029cc 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -123,9 +123,9 @@ private static function parse( string $input ) { $offset = 0; while ( $offset < $length ) { - $sel = WP_CSS_ID_Selector::parse( $input, $offset ); - if ( $sel ) { - $selectors[] = $sel; + $selector = WP_CSS_ID_Selector::parse( $input, $offset ); + if ( null !== $selector ) { + $selectors[] = $selector; } } if ( count( $selectors ) ) { @@ -841,6 +841,8 @@ public static function parse( string $input, int &$offset ): ?self { /** * This corresponds to in the grammar. + * + * > = [ ? * ]! */ final class WP_CSS_Selector extends WP_CSS_Selector_Parser { @@ -856,12 +858,7 @@ private function __construct( ?WP_CSS_Type_Selector $type_selector, array $subcl } /** - * Parses a selector string into a `WP_CSS_Selector` object. - * * > = [ ? * ]! - * - * @param string $input The selector string to parse. - * @return WP_CSS_Selector|null The parsed selector, or `null` if the selector is invalid or unsupported. */ public static function parse( string $input, int &$offset ): ?self { if ( $offset >= strlen( $input ) ) { @@ -882,6 +879,7 @@ public static function parse( string $input, int &$offset ): ?self { $offset = $updated_offset; return new self( $type_selector, $subclass_selectors ); } + return null; } /** @@ -902,3 +900,76 @@ private static function parse_subclass_selector( string $input, int &$offset ) { null ) ); } } + + +/** + * This corresponds to in the grammar. + * + * > = [ ? ]* + */ +final class WP_CSS_Complex_Selector extends WP_CSS_Selector_Parser { + const COMBINATOR_CHILD = '>'; + const COMBINATOR_DESCENDANT = ' '; + const COMBINATOR_NEXT_SIBLING = '+'; + const COMBINATOR_SUBSEQUENT_SIBLING = '~'; + + /** + * even indexes are WP_CSS_Selector, odd indexes are string combinators. + * @var array + */ + public $selectors = array(); + + private function __construct( array $selectors ) { + $this->selectors = $selectors; + } + + public static function parse( string $input, int &$offset ): ?self { + if ( $offset >= strlen( $input ) ) { + return null; + } + + $updated_offset = $offset; + $selector = WP_CSS_Selector::parse( $input, $updated_offset ); + if ( null === $selector ) { + return null; + } + + $selectors = array( $selector ); + + $found_whitespace = self::parse_whitespace( $input, $updated_offset ); + while ( $updated_offset < strlen( $input ) ) { + switch ( $input[ $updated_offset ] ) { + case self::COMBINATOR_CHILD: + case self::COMBINATOR_NEXT_SIBLING: + case self::COMBINATOR_SUBSEQUENT_SIBLING: + $combinator = $input[ $updated_offset ]; + ++$updated_offset; + self::parse_whitespace( $input, $updated_offset ); + break; + + default: + /* + * Whitespace is a descendant combinator. + * Either whitespace was found and we're on a selector, + * or we've failed to find any combinator and parsing is complete. + */ + if ( ! $found_whitespace ) { + break 2; + } + $combinator = self::COMBINATOR_DESCENDANT; + break; + } + // Here we've found a combinator and need another selector. + $selector = WP_CSS_Selector::parse( $input, $updated_offset ); + // Failure to find a selector is a parse error. + if ( null === $selector ) { + return null; + } + $selectors[] = $combinator; + $selectors[] = $selector; + $found_whitespace = self::parse_whitespace( $input, $updated_offset ); + } + $offset = $updated_offset; + return new self( $selectors ); + } +} diff --git a/tests/phpunit/tests/html-api/wpCssSelectors.php b/tests/phpunit/tests/html-api/wpCssSelectors.php index 180bee4f53c05..4189ec586011a 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectors.php +++ b/tests/phpunit/tests/html-api/wpCssSelectors.php @@ -347,13 +347,33 @@ public function test_parse_selector() { $offset = 0; $sel = WP_CSS_Selector::parse( $input, $offset ); - $this->assertSame( $sel->type_selector->ident, 'el' ); - $this->assertSame( count( $sel->subclass_selectors ), 3 ); - $this->assertSame( $sel->subclass_selectors[0]->ident, 'foo' ); - $this->assertSame( $sel->subclass_selectors[1]->ident, 'bar' ); - $this->assertSame( $sel->subclass_selectors[2]->name, 'baz' ); - $this->assertSame( $sel->subclass_selectors[2]->matcher, WP_CSS_Attribute_Selector::MATCH_EXACT ); - $this->assertSame( $sel->subclass_selectors[2]->value, 'quux' ); + $this->assertSame( 'el', $sel->type_selector->ident ); + $this->assertSame( 3, count( $sel->subclass_selectors ) ); + $this->assertSame( 'foo', $sel->subclass_selectors[0]->ident, 'foo' ); + $this->assertSame( 'bar', $sel->subclass_selectors[1]->ident, 'bar' ); + $this->assertSame( 'baz', $sel->subclass_selectors[2]->name, 'baz' ); + $this->assertSame( WP_CSS_Attribute_Selector::MATCH_EXACT, $sel->subclass_selectors[2]->matcher ); + $this->assertSame( 'quux', $sel->subclass_selectors[2]->value ); $this->assertSame( ' > .child', substr( $input, $offset ) ); } + + /** + * @ticket TBD + */ + public function test_parse_complex_selector() { + $input = 'el.foo#bar[baz=quux] > .child, rest'; + $offset = 0; + $sel = WP_CSS_Complex_Selector::parse( $input, $offset ); + + var_dump( $sel ); + $this->assertSame( 3, count( $sel->selectors ) ); + $this->assertNotNull( $sel->selectors[0]->type_selector ); + $this->assertSame( 3, count( $sel->selectors[0]->subclass_selectors ) ); + $this->assertSame( WP_CSS_Complex_Selector::COMBINATOR_CHILD, $sel->selectors[1] ); + $this->assertNull( $sel->selectors[2]->type_selector ); + $this->assertSame( 1, count( $sel->selectors[2]->subclass_selectors ) ); + $this->assertSame( 'child', $sel->selectors[2]->subclass_selectors[0]->ident ); + + $this->assertSame( ', rest', substr( $input, $offset ) ); + } } From 5c746cd58b3e1178e9579e11b71974a5be652ac2 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 27 Nov 2024 22:39:22 +0100 Subject: [PATCH 047/634] Working and tested --- .../html-api/class-wp-css-selectors.php | 83 +++++++++++-------- .../phpunit/tests/html-api/wpCssSelectors.php | 67 ++++++++++++++- 2 files changed, 113 insertions(+), 37 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 8ccec5de029cc..734c3e38d094b 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -117,21 +117,31 @@ private static function parse( string $input ) { $input = str_replace( array( "\r", "\f" ), "\n", $input ); $input = str_replace( "\0", "\u{FFFD}", $input ); - $length = strlen( $input ); - $selectors = array(); - $offset = 0; - while ( $offset < $length ) { - $selector = WP_CSS_ID_Selector::parse( $input, $offset ); - if ( null !== $selector ) { - $selectors[] = $selector; - } + $selector = WP_CSS_Complex_Selector::parse( $input, $offset ); + if ( null === $selector ) { + return null; } - if ( count( $selectors ) ) { - return new WP_CSS_Selector_List( $selectors ); + WP_CSS_Selector_Parser::parse_whitespace( $input, $offset ); + + $selectors = array( $selector ); + while ( $offset < strlen( $input ) ) { + // Each loop should stop on a `,` selector list delimiter. + if ( ',' !== $input[ $offset ] ) { + return null; + } + ++$offset; + WP_CSS_Selector_Parser::parse_whitespace( $input, $offset ); + $selector = WP_CSS_Complex_Selector::parse( $input, $offset ); + if ( null === $selector ) { + return null; + } + $selectors[] = $selector; + WP_CSS_Selector_Parser::parse_whitespace( $input, $offset ); } - return null; + + return new WP_CSS_Selector_List( $selectors ); } } @@ -145,7 +155,7 @@ public static function parse( string $input, int &$offset ); abstract class WP_CSS_Selector_Parser implements IWP_CSS_Selector_Parser { const UTF8_MAX_CODEPOINT_VALUE = 0x10FFFF; - protected static function parse_whitespace( string $input, int &$offset ): bool { + public static function parse_whitespace( string $input, int &$offset ): bool { $length = strspn( $input, " \t\r\n\f", $offset ); $advanced = $length > 0; $offset += $length; @@ -938,35 +948,38 @@ public static function parse( string $input, int &$offset ): ?self { $found_whitespace = self::parse_whitespace( $input, $updated_offset ); while ( $updated_offset < strlen( $input ) ) { - switch ( $input[ $updated_offset ] ) { - case self::COMBINATOR_CHILD: - case self::COMBINATOR_NEXT_SIBLING: - case self::COMBINATOR_SUBSEQUENT_SIBLING: + if ( + self::COMBINATOR_CHILD === $input[ $updated_offset ] || + self::COMBINATOR_NEXT_SIBLING === $input[ $updated_offset ] || + self::COMBINATOR_SUBSEQUENT_SIBLING === $input[ $updated_offset ] + ) { $combinator = $input[ $updated_offset ]; ++$updated_offset; self::parse_whitespace( $input, $updated_offset ); - break; - default: - /* - * Whitespace is a descendant combinator. - * Either whitespace was found and we're on a selector, - * or we've failed to find any combinator and parsing is complete. - */ - if ( ! $found_whitespace ) { - break 2; - } - $combinator = self::COMBINATOR_DESCENDANT; + // Failure to find a selector here is a parse error + $selector = WP_CSS_Selector::parse( $input, $updated_offset ); + // Failure to find a selector is a parse error. + if ( null === $selector ) { + return null; + } + $selectors[] = $combinator; + $selectors[] = $selector; + } elseif ( ! $found_whitespace ) { + break; + } else { + + /* + * Whitespace is ambiguous, it could be a descendant combinator or + * insignificant whitespace. + */ + $selector = WP_CSS_Selector::parse( $input, $updated_offset ); + if ( null === $selector ) { break; + } + $selectors[] = self::COMBINATOR_DESCENDANT; + $selectors[] = $selector; } - // Here we've found a combinator and need another selector. - $selector = WP_CSS_Selector::parse( $input, $updated_offset ); - // Failure to find a selector is a parse error. - if ( null === $selector ) { - return null; - } - $selectors[] = $combinator; - $selectors[] = $selector; $found_whitespace = self::parse_whitespace( $input, $updated_offset ); } $offset = $updated_offset; diff --git a/tests/phpunit/tests/html-api/wpCssSelectors.php b/tests/phpunit/tests/html-api/wpCssSelectors.php index 4189ec586011a..33ada4ccbe3f9 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectors.php +++ b/tests/phpunit/tests/html-api/wpCssSelectors.php @@ -357,15 +357,24 @@ public function test_parse_selector() { $this->assertSame( ' > .child', substr( $input, $offset ) ); } + /** + * @ticket TBD + */ + public function test_parse_empty_selector() { + $input = ''; + $offset = 0; + $result = WP_CSS_Selector::parse( $input, $offset ); + $this->assertNull( $result ); + } + /** * @ticket TBD */ public function test_parse_complex_selector() { - $input = 'el.foo#bar[baz=quux] > .child, rest'; + $input = 'el.foo#bar[baz=quux] > .child , rest'; $offset = 0; $sel = WP_CSS_Complex_Selector::parse( $input, $offset ); - var_dump( $sel ); $this->assertSame( 3, count( $sel->selectors ) ); $this->assertNotNull( $sel->selectors[0]->type_selector ); $this->assertSame( 3, count( $sel->selectors[0]->subclass_selectors ) ); @@ -376,4 +385,58 @@ public function test_parse_complex_selector() { $this->assertSame( ', rest', substr( $input, $offset ) ); } + + /** + * @ticket TBD + */ + public function test_parse_invalid_complex_selector() { + $input = 'el.foo#bar[baz=quux] > , rest'; + $offset = 0; + $result = WP_CSS_Complex_Selector::parse( $input, $offset ); + $this->assertNull( $result ); + } + + public function test_parse_empty_complex_selector() { + $input = ''; + $offset = 0; + $result = WP_CSS_Complex_Selector::parse( $input, $offset ); + $this->assertNull( $result ); + } + + + /** + * @ticket TBD + */ + public function test_parse_selector_list() { + $input = 'el.foo#bar[baz=quux] .descendent , rest'; + $result = WP_CSS_Selector_List::from_selectors( $input ); + $this->assertNotNull( $result ); + } + + /** + * @ticket TBD + */ + public function test_parse_invalid_selector_list() { + $input = 'el,,'; + $result = WP_CSS_Selector_List::from_selectors( $input ); + $this->assertNull( $result ); + } + + /** + * @ticket TBD + */ + public function test_parse_invalid_selector_list2() { + $input = 'el!'; + $result = WP_CSS_Selector_List::from_selectors( $input ); + $this->assertNull( $result ); + } + + /** + * @ticket TBD + */ + public function test_parse_empty_selector_list() { + $input = " \t \t\n\r\f"; + $result = WP_CSS_Selector_List::from_selectors( $input ); + $this->assertNull( $result ); + } } From 501102a87bb3f38bc2781c22b6de9a59d640bf62 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 28 Nov 2024 18:30:47 +0100 Subject: [PATCH 048/634] Selector parsing should allow cap I,S modifier --- src/wp-includes/html-api/class-wp-css-selectors.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 734c3e38d094b..6e382f8f8b744 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -823,11 +823,13 @@ public static function parse( string $input, int &$offset ): ?self { $attr_modifier = null; switch ( $input[ $updated_offset ] ) { case 'i': + case 'I': $attr_modifier = WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE; ++$updated_offset; break; case 's': + case 'S': $attr_modifier = WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE; ++$updated_offset; break; From f98fbb39c71333b22e3c7f97c380c7ce81c56097 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 28 Nov 2024 19:08:17 +0100 Subject: [PATCH 049/634] CSS Add matches to selector classes --- .../html-api/class-wp-css-selectors.php | 120 +++++++++++++++++- 1 file changed, 116 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 6e382f8f8b744..d9c507bb5f557 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -69,7 +69,20 @@ * @see {@link https://www.w3.org/TR/selectors-4/} * */ -class WP_CSS_Selector_List { +class WP_CSS_Selector_List implements IWP_CSS_Selector_Matcher { + public function matches( WP_HTML_Processor $processor ): bool { + if ( $processor->get_token_type() !== '#tag' ) { + return false; + } + + foreach ( $this->selectors as $selector ) { + if ( ! $selector->matches( $processor ) ) { + return false; + } + } + return true; + } + private $selectors; private function __construct( array $selectors ) { @@ -145,6 +158,13 @@ private static function parse( string $input ) { } } +interface IWP_CSS_Selector_Matcher { + /** + * @return bool + */ + public function matches( WP_HTML_Processor $processor ): bool; +} + interface IWP_CSS_Selector_Parser { /** * @return static|null @@ -152,7 +172,7 @@ interface IWP_CSS_Selector_Parser { public static function parse( string $input, int &$offset ); } -abstract class WP_CSS_Selector_Parser implements IWP_CSS_Selector_Parser { +abstract class WP_CSS_Selector_Parser implements IWP_CSS_Selector_Parser, IWP_CSS_Selector_Matcher { const UTF8_MAX_CODEPOINT_VALUE = 0x10FFFF; public static function parse_whitespace( string $input, int &$offset ): bool { @@ -553,9 +573,18 @@ public static function parse( string $input, int &$offset ): ?self { } return new self( $ident ); } + + public function matches( WP_HTML_Processor $processor ): bool { + // @todo check case sensitivity. + return $processor->get_attribute( 'id' ) === $this->ident; + } } final class WP_CSS_Class_Selector extends WP_CSS_Selector_Parser { + public function matches( WP_HTML_Processor $processor ): bool { + return $processor->has_class( $this->ident ); + } + /** @var string */ public $ident; @@ -590,6 +619,13 @@ public static function parse( string $input, int &$offset ): ?self { } final class WP_CSS_Type_Selector extends WP_CSS_Selector_Parser { + public function matches( WP_HTML_Processor $processor ): bool { + if ( '*' === $this->ident ) { + return true; + } + return 0 === strcasecmp( $processor->get_tag(), $this->ident ); + } + /** * @var string * @@ -635,9 +671,64 @@ public static function parse( string $input, int &$offset ): ?self { } final class WP_CSS_Attribute_Selector extends WP_CSS_Selector_Parser { + public function matches( WP_HTML_Processor $processor ): bool { + $att_value = $processor->get_attribute( $this->name ); + if ( null === $att_value ) { + return false; + } + + if ( null === $this->value ) { + return true; + } + + $case_insensitive = self::MODIFIER_CASE_INSENSITIVE === $this->modifier; + + switch ( $this->matcher ) { + case self::MATCH_EXACT: + return $case_insensitive ? + 0 === strcasecmp( $att_value, $this->value ) : + $att_value === $this->value; + + case self::MATCH_ONE_OF_EXACT: + // @todo + throw new Exception( 'One of attribute matching is not supported yet.' ); + + case self::MATCH_EXACT_OR_EXACT_WITH_HYPHEN: + // Attempt the full match first + if ( + $case_insensitive ? + 0 === strcasecmp( $att_value, $this->value ) : + $att_value === $this->value + ) { + return true; + } + + // Partial match + if ( strlen( $att_value ) < strlen( $this->value ) + 1 ) { + return false; + } + + $starts_with = "{$this->value}-"; + return 0 === substr_compare( $att_value, $starts_with, 0, strlen( $starts_with ), $case_insensitive ); + + case self::MATCH_PREFIXED_BY: + return 0 === substr_compare( $att_value, $this->value, 0, strlen( $this->value ), $case_insensitive ); + + case self::MATCH_SUFFIXED_BY: + return 0 === substr_compare( $att_value, $this->value, -strlen( $this->value ), null, $case_insensitive ); + + case self::MATCH_CONTAINS: + return false !== ( + $case_insensitive ? + stripos( $att_value, $this->value ) : + strpos( $att_value, $this->value ) + ); + } + } + /** - * [attr=value] - * Represents elements with an attribute name of attr whose value is exactly value. + * [att=val] + * Represents an element with the att attribute whose value is exactly "val". */ const MATCH_EXACT = 'MATCH_EXACT'; @@ -857,6 +948,19 @@ public static function parse( string $input, int &$offset ): ?self { * > = [ ? * ]! */ final class WP_CSS_Selector extends WP_CSS_Selector_Parser { + public function matches( WP_HTML_Processor $processor ): bool { + if ( $this->type_selector ) { + if ( ! $this->type_selector->matches( $processor ) ) { + return false; + } + } + foreach ( $this->subclass_selectors as $subclass_selector ) { + if ( ! $subclass_selector->matches( $processor ) ) { + return false; + } + } + return true; + } /** @var WP_CSS_Type_Selector|null */ public $type_selector; @@ -920,6 +1024,14 @@ private static function parse_subclass_selector( string $input, int &$offset ) { * > = [ ? ]* */ final class WP_CSS_Complex_Selector extends WP_CSS_Selector_Parser { + public function matches( WP_HTML_Processor $processor ): bool { + // @todo this can throw on parse. + if ( count( $this->selectors ) > 1 ) { + throw new Exception( 'Combined complex selectors are not supported yet.' ); + } + return $this->selectors[0]->matches( $processor ); + } + const COMBINATOR_CHILD = '>'; const COMBINATOR_DESCENDANT = ' '; const COMBINATOR_NEXT_SIBLING = '+'; From c8f16e19f30ec4b4ad0cfbaac849b33e811229e3 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 28 Nov 2024 19:40:55 +0100 Subject: [PATCH 050/634] Match is successful on _any_ match in selector list --- src/wp-includes/html-api/class-wp-css-selectors.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index d9c507bb5f557..1a50defba8ea3 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -76,11 +76,11 @@ public function matches( WP_HTML_Processor $processor ): bool { } foreach ( $this->selectors as $selector ) { - if ( ! $selector->matches( $processor ) ) { - return false; + if ( $selector->matches( $processor ) ) { + return true; } } - return true; + return false; } private $selectors; From c689c9c50fb6827dd330df1707844410479b4234 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 28 Nov 2024 19:41:55 +0100 Subject: [PATCH 051/634] PICKME: Add is_quirks_mode method to processor --- src/wp-includes/html-api/class-wp-html-tag-processor.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wp-includes/html-api/class-wp-html-tag-processor.php b/src/wp-includes/html-api/class-wp-html-tag-processor.php index 39390621e86a6..7dadbc1bebdb2 100644 --- a/src/wp-includes/html-api/class-wp-html-tag-processor.php +++ b/src/wp-includes/html-api/class-wp-html-tag-processor.php @@ -537,6 +537,10 @@ class WP_HTML_Tag_Processor { */ protected $compat_mode = self::NO_QUIRKS_MODE; + public function is_quirks_mode() { + return self::QUIRKS_MODE === $this->compat_mode; + } + /** * Indicates whether the parser is inside foreign content, * e.g. inside an SVG or MathML element. From 1221efae34bf033af893180aa32a13e58b5312d8 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 28 Nov 2024 19:41:27 +0100 Subject: [PATCH 052/634] ID matches depend on quirks mode --- src/wp-includes/html-api/class-wp-css-selectors.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 1a50defba8ea3..01e3253893d57 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -575,8 +575,10 @@ public static function parse( string $input, int &$offset ): ?self { } public function matches( WP_HTML_Processor $processor ): bool { - // @todo check case sensitivity. - return $processor->get_attribute( 'id' ) === $this->ident; + $case_insensitive = method_exists( $processor, 'is_quirks_mode' ) && $processor->is_quirks_mode(); + return $case_insensitive ? + 0 === strcasecmp( $processor->get_attribute( 'id' ), $this->ident ) : + $processor->get_attribute( 'id' ) === $this->ident; } } From e5e94b11b5d9e3c113364c2a595ebb8cfdb715f7 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 28 Nov 2024 19:42:12 +0100 Subject: [PATCH 053/634] has_class may return null, coerce to bool --- src/wp-includes/html-api/class-wp-css-selectors.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 01e3253893d57..3e35a383b4446 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -584,7 +584,7 @@ public function matches( WP_HTML_Processor $processor ): bool { final class WP_CSS_Class_Selector extends WP_CSS_Selector_Parser { public function matches( WP_HTML_Processor $processor ): bool { - return $processor->has_class( $this->ident ); + return (bool) $processor->has_class( $this->ident ); } /** @var string */ From 1e888babcc7e4448a02ace55a509e655bdea1e5d Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 28 Nov 2024 21:29:13 +0100 Subject: [PATCH 054/634] Update docs to only allow subclass selectors in final complex selector position --- .../html-api/class-wp-css-selectors.php | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 3e35a383b4446..b0d5afbb5bba7 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -27,9 +27,9 @@ * = * = # * = # - * = [ ? ]* + * = [ ? ]* * = [ ? * ]! - * = '>' | '+' | '~' | [ '|' '|' ] + * = '>' | [ '|' '|' ] * = | '*' * = | | * = @@ -47,17 +47,23 @@ * - ID selectors (e.g. `#unique-id`) * - Attribute selectors (e.g. `[attribute-name]` or `[attribute-name="value"]`) * - Comma-separated selector lists (e.g. `.selector-1, .selector-2`) - * - The following combinators: - * - descendant (e.g. `.parent .descendant`) - * - child (`.parent > .child`) + * - The following combinators. Only type (element) selectors are allowed in non-final position: + * - descendant (e.g. `el .descendant`) + * - child (`el > .child`) * * Unsupported selector syntax: * - Pseudo-element selectors (e.g. `::before`) * - Pseudo-class selectors (e.g. `:hover` or `:nth-child(2)`) * - Namespace prefixes (e.g. `svg|title` or `[xlink|href]`) * - The following combinators: - * - Next sibling (`.sibling + .sibling`) - * - Subsequent sibling (`.sibling ~ .sibling`) + * - Next sibling (`el + el`) + * - Subsequent sibling (`el ~ el`) + * + * Future ideas + * - Namespace type selectors could be implemented with select namespaces in order to + * select elements from a namespace, for example: + * - `svg|*` to select all SVG elements + * - `html|title` to select only HTML TITLE elements. * * @since TBD * From dd4fcb01184f9e07ec51067e1d7c1a8d4021d168 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 28 Nov 2024 22:10:05 +0100 Subject: [PATCH 055/634] Restrict complex selectors to only allow subclass selectors in final position --- .../html-api/class-wp-css-selectors.php | 43 +++++++++++-------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index b0d5afbb5bba7..45a2f78d94fd5 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -1066,7 +1066,8 @@ public static function parse( string $input, int &$offset ): ?self { return null; } - $selectors = array( $selector ); + $selectors = array( $selector ); + $has_preceding_subclass_selector = null !== $selector->subclass_selectors; $found_whitespace = self::parse_whitespace( $input, $updated_offset ); while ( $updated_offset < strlen( $input ) ) { @@ -1075,22 +1076,13 @@ public static function parse( string $input, int &$offset ): ?self { self::COMBINATOR_NEXT_SIBLING === $input[ $updated_offset ] || self::COMBINATOR_SUBSEQUENT_SIBLING === $input[ $updated_offset ] ) { - $combinator = $input[ $updated_offset ]; - ++$updated_offset; - self::parse_whitespace( $input, $updated_offset ); - - // Failure to find a selector here is a parse error - $selector = WP_CSS_Selector::parse( $input, $updated_offset ); - // Failure to find a selector is a parse error. - if ( null === $selector ) { - return null; - } - $selectors[] = $combinator; - $selectors[] = $selector; - } elseif ( ! $found_whitespace ) { - break; - } else { + $combinator = $input[ $updated_offset ]; + ++$updated_offset; + self::parse_whitespace( $input, $updated_offset ); + // Failure to find a selector here is a parse error + $selector = WP_CSS_Selector::parse( $input, $updated_offset ); + } elseif ( $found_whitespace ) { /* * Whitespace is ambiguous, it could be a descendant combinator or * insignificant whitespace. @@ -1099,9 +1091,24 @@ public static function parse( string $input, int &$offset ): ?self { if ( null === $selector ) { break; } - $selectors[] = self::COMBINATOR_DESCENDANT; - $selectors[] = $selector; + $combinator = self::COMBINATOR_DESCENDANT; + } else { + break; + } + + if ( null === $selector ) { + return null; } + + // `div > .className` is valid, but `.className > div` is not. + if ( $has_preceding_subclass_selector ) { + throw new Exception( 'Unsupported non-final subclass selector.' ); + } + $has_preceding_subclass_selector = null !== $selector->subclass_selectors; + + $selectors[] = $combinator; + $selectors[] = $selector; + $found_whitespace = self::parse_whitespace( $input, $updated_offset ); } $offset = $updated_offset; From 256c55a16d8e5adf3ebdc64a360e3373eeecaa28 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 28 Nov 2024 22:10:21 +0100 Subject: [PATCH 056/634] Work on complex selector handling --- .../html-api/class-wp-css-selectors.php | 49 +++++++++++++++++-- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 45a2f78d94fd5..bc28cfaa4f20e 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -1033,11 +1033,47 @@ private static function parse_subclass_selector( string $input, int &$offset ) { */ final class WP_CSS_Complex_Selector extends WP_CSS_Selector_Parser { public function matches( WP_HTML_Processor $processor ): bool { - // @todo this can throw on parse. - if ( count( $this->selectors ) > 1 ) { - throw new Exception( 'Combined complex selectors are not supported yet.' ); + if ( count( $this->selectors ) === 1 ) { + return $this->selectors[0]->matches( $processor ); + } + + // First selector must match this location. + if ( ! $this->selectors[0]->matches( $processor ) ) { + return false; + } + + $breadcrumbs = array_slice( array_reverse( $processor->get_breadcrumbs() ), 1 ); + $selectors = array_slice( $this->selectors, 1 ); + return $this->explore_matches( $selectors, $breadcrumbs ); + } + + /** + * This only looks at breadcrumbs and can therefore only support type selectors. + * + * @param array $selectors + */ + private function explore_matches( array $selectors, array $breadcrumbs ): bool { + if ( array() === $selectors ) { + return true; + } + if ( array() === $breadcrumbs ) { + return false; + } + + $combinator = $selectors[0]; + $selector = $selectors[1]; + + switch ( $combinator ) { + case self::COMBINATOR_CHILD: + if ( '*' === $selector->type_selector->ident || strcasecmp( $breadcrumbs[0], $selector->type_selector->ident ) === 0 ) { + return $this->explore_matches( array_slice( $selectors, 2 ), array_slice( $breadcrumbs, 1 ) ); + } + return $this->explore_matches( $selectors, array_slice( $breadcrumbs, 1 ) ); + + case self::COMBINATOR_DESCENDANT: + default: + throw new Exception( "Combinator '{$combinator}' is not supported yet." ); } - return $this->selectors[0]->matches( $processor ); } const COMBINATOR_CHILD = '>'; @@ -1047,12 +1083,15 @@ public function matches( WP_HTML_Processor $processor ): bool { /** * even indexes are WP_CSS_Selector, odd indexes are string combinators. + * In reverse order to match the current element and then work up the tree. + * Any non-final selector is a type selector. + * * @var array */ public $selectors = array(); private function __construct( array $selectors ) { - $this->selectors = $selectors; + $this->selectors = array_reverse( $selectors ); } public static function parse( string $input, int &$offset ): ?self { From 465cc3673cb15e2b229767223801224d8fd36335 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 28 Nov 2024 22:26:43 +0100 Subject: [PATCH 057/634] Implement descendent selector matching --- src/wp-includes/html-api/class-wp-css-selectors.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index bc28cfaa4f20e..974c56e6581ff 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -1071,6 +1071,19 @@ private function explore_matches( array $selectors, array $breadcrumbs ): bool { return $this->explore_matches( $selectors, array_slice( $breadcrumbs, 1 ) ); case self::COMBINATOR_DESCENDANT: + $ident = $selector->type_selector->ident; + + // Find _all_ the breadcrumbs that match and recurse from each of them. + for ( $i = 0; $i < count( $breadcrumbs ); $i++ ) { + if ( '*' === $selector->type_selector->ident || strcasecmp( $breadcrumbs[ $i ], $selector->type_selector->ident ) === 0 ) { + $next_crumbs = array_slice( $breadcrumbs, $i + 1 ); + if ( $this->explore_matches( array_slice( $selectors, 2 ), $next_crumbs ) ) { + return true; + } + } + } + return false; + default: throw new Exception( "Combinator '{$combinator}' is not supported yet." ); } From 467d45dc3133dfefb7081e8e7e7821254dd073a0 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 29 Nov 2024 15:48:21 +0100 Subject: [PATCH 058/634] Add null check for subclass selectors --- src/wp-includes/html-api/class-wp-css-selectors.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 974c56e6581ff..21039c0c7940e 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -962,9 +962,11 @@ public function matches( WP_HTML_Processor $processor ): bool { return false; } } - foreach ( $this->subclass_selectors as $subclass_selector ) { - if ( ! $subclass_selector->matches( $processor ) ) { - return false; + if ( null !== $this->subclass_selectors ) { + foreach ( $this->subclass_selectors as $subclass_selector ) { + if ( ! $subclass_selector->matches( $processor ) ) { + return false; + } } } return true; From 44bfc64b4fe9711f1800e854c059156bcf2b45fb Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 29 Nov 2024 16:20:22 +0100 Subject: [PATCH 059/634] CSS selector reformat ternaries --- .../html-api/class-wp-css-selectors.php | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 21039c0c7940e..65e384639abcb 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -390,9 +390,9 @@ protected static function consume_escaped_codepoint( $input, &$offset ): ?string 0 === $codepoint_value || $codepoint_value > self::UTF8_MAX_CODEPOINT_VALUE || ( 0xD800 <= $codepoint_value && $codepoint_value <= 0xDFFF ) - ) ? - "\u{FFFD}" : - mb_chr( $codepoint_value, 'UTF-8' ); + ) + ? "\u{FFFD}" + : mb_chr( $codepoint_value, 'UTF-8' ); $offset += $hex_length; @@ -582,9 +582,9 @@ public static function parse( string $input, int &$offset ): ?self { public function matches( WP_HTML_Processor $processor ): bool { $case_insensitive = method_exists( $processor, 'is_quirks_mode' ) && $processor->is_quirks_mode(); - return $case_insensitive ? - 0 === strcasecmp( $processor->get_attribute( 'id' ), $this->ident ) : - $processor->get_attribute( 'id' ) === $this->ident; + return $case_insensitive + ? 0 === strcasecmp( $processor->get_attribute( 'id' ), $this->ident ) + : $processor->get_attribute( 'id' ) === $this->ident; } } @@ -693,9 +693,9 @@ public function matches( WP_HTML_Processor $processor ): bool { switch ( $this->matcher ) { case self::MATCH_EXACT: - return $case_insensitive ? - 0 === strcasecmp( $att_value, $this->value ) : - $att_value === $this->value; + return $case_insensitive + ? 0 === strcasecmp( $att_value, $this->value ) + : $att_value === $this->value; case self::MATCH_ONE_OF_EXACT: // @todo @@ -704,9 +704,9 @@ public function matches( WP_HTML_Processor $processor ): bool { case self::MATCH_EXACT_OR_EXACT_WITH_HYPHEN: // Attempt the full match first if ( - $case_insensitive ? - 0 === strcasecmp( $att_value, $this->value ) : - $att_value === $this->value + $case_insensitive + ? 0 === strcasecmp( $att_value, $this->value ) + : $att_value === $this->value ) { return true; } @@ -1017,13 +1017,16 @@ private static function parse_subclass_selector( string $input, int &$offset ) { } $next_char = $input[ $offset ]; - return '.' === $next_char ? - WP_CSS_Class_Selector::parse( $input, $offset ) : ( - '#' === $next_char ? - WP_CSS_ID_Selector::parse( $input, $offset ) : ( - '[' === $next_char ? - WP_CSS_Attribute_Selector::parse( $input, $offset ) : - null ) ); + return '.' === $next_char + ? WP_CSS_Class_Selector::parse( $input, $offset ) + : ( + '#' === $next_char + ? WP_CSS_ID_Selector::parse( $input, $offset ) + : ( '[' === $next_char + ? WP_CSS_Attribute_Selector::parse( $input, $offset ) + : null + ) + ); } } From ca4531c0a190b89f6072799b2b1f90dbd1deb2c1 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 29 Nov 2024 16:20:54 +0100 Subject: [PATCH 060/634] Implement ~= attribute matching --- .../html-api/class-wp-css-selectors.php | 43 ++++++++++++++++--- 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 65e384639abcb..49c3daf66c3b2 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -180,9 +180,10 @@ public static function parse( string $input, int &$offset ); abstract class WP_CSS_Selector_Parser implements IWP_CSS_Selector_Parser, IWP_CSS_Selector_Matcher { const UTF8_MAX_CODEPOINT_VALUE = 0x10FFFF; + const WHITESPACE_CHARACTERS = " \t\r\n\f"; public static function parse_whitespace( string $input, int &$offset ): bool { - $length = strspn( $input, " \t\r\n\f", $offset ); + $length = strspn( $input, self::WHITESPACE_CHARACTERS, $offset ); $advanced = $length > 0; $offset += $length; return $advanced; @@ -698,8 +699,16 @@ public function matches( WP_HTML_Processor $processor ): bool { : $att_value === $this->value; case self::MATCH_ONE_OF_EXACT: - // @todo - throw new Exception( 'One of attribute matching is not supported yet.' ); + foreach ( $this->whitespace_delimited_list( $att_value ) as $val ) { + if ( + $case_insensitive + ? 0 === strcasecmp( $val, $this->value ) + : $val === $this->value + ) { + return true; + } + } + return false; case self::MATCH_EXACT_OR_EXACT_WITH_HYPHEN: // Attempt the full match first @@ -727,13 +736,35 @@ public function matches( WP_HTML_Processor $processor ): bool { case self::MATCH_CONTAINS: return false !== ( - $case_insensitive ? - stripos( $att_value, $this->value ) : - strpos( $att_value, $this->value ) + $case_insensitive + ? stripos( $att_value, $this->value ) + : strpos( $att_value, $this->value ) ); } } + /** + * @param string $input + * + * @return Generator + */ + private function whitespace_delimited_list( string $input ): Generator { + $offset = strspn( $input, self::WHITESPACE_CHARACTERS ); + + while ( $offset < strlen( $input ) ) { + // Find the byte length until the next boundary. + $length = strcspn( $input, self::WHITESPACE_CHARACTERS, $offset ); + if ( 0 === $length ) { + return; + } + + $value = substr( $input, $offset, $length ); + $offset += $length + strspn( $input, self::WHITESPACE_CHARACTERS, $offset + $length ); + + yield $value; + } + } + /** * [att=val] * Represents an element with the att attribute whose value is exactly "val". From 489db93a917625bc7d42d6e3d9f5ad924d3a96ed Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 29 Nov 2024 16:48:15 +0100 Subject: [PATCH 061/634] CSS fix return type --- src/wp-includes/html-api/class-wp-css-selectors.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 49c3daf66c3b2..1431dc58afb52 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -113,7 +113,7 @@ public static function from_selectors( string $selectors ): ?self { * * @since TBD * - * @return WP_CSS_Selectors|null + * @return self|null */ private static function parse( string $input ) { // > A selector string is a list of one or more complex selectors ([SELECTORS4], section 3.1) that may be surrounded by whitespace and matches the dom_selectors_group production. From e57a2114aafdd6cb1d0e3cf1b7d2e3064c3e8d0b Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 29 Nov 2024 17:05:40 +0100 Subject: [PATCH 062/634] Fix static analysis problems --- .../html-api/class-wp-css-selectors.php | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 1431dc58afb52..2205146bdf2be 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -1,4 +1,8 @@ -value ) ); } + + throw new Exception( 'Unreachable' ); } /** @@ -830,7 +834,7 @@ private function whitespace_delimited_list( string $input ): Generator { /** * The attribute matcher. * - * @var string|null + * @var null|self::MATCH_* */ public $matcher; @@ -844,7 +848,7 @@ private function whitespace_delimited_list( string $input ): Generator { /** * The attribute modifier. * - * @var string|null + * @var null|self::MODIFIER_* */ public $modifier; @@ -1086,7 +1090,7 @@ public function matches( WP_HTML_Processor $processor ): bool { /** * This only looks at breadcrumbs and can therefore only support type selectors. * - * @param array $selectors + * @param array $selectors */ private function explore_matches( array $selectors, array $breadcrumbs ): bool { if ( array() === $selectors ) { @@ -1096,8 +1100,10 @@ private function explore_matches( array $selectors, array $breadcrumbs ): bool { return false; } + /** @var self::COMBINATOR_* $combinator */ $combinator = $selectors[0]; - $selector = $selectors[1]; + /** @var WP_CSS_Selector $selector */ + $selector = $selectors[1]; switch ( $combinator ) { case self::COMBINATOR_CHILD: @@ -1107,8 +1113,6 @@ private function explore_matches( array $selectors, array $breadcrumbs ): bool { return $this->explore_matches( $selectors, array_slice( $breadcrumbs, 1 ) ); case self::COMBINATOR_DESCENDANT: - $ident = $selector->type_selector->ident; - // Find _all_ the breadcrumbs that match and recurse from each of them. for ( $i = 0; $i < count( $breadcrumbs ); $i++ ) { if ( '*' === $selector->type_selector->ident || strcasecmp( $breadcrumbs[ $i ], $selector->type_selector->ident ) === 0 ) { From 509e648685af757a6b38830c8ccd58e2ac36fe07 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 29 Nov 2024 17:40:39 +0100 Subject: [PATCH 063/634] Fix and annotate things (static analysis) --- .../html-api/class-wp-css-selectors.php | 52 +++++++++++++------ 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 2205146bdf2be..28e51aa9a9735 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -77,7 +77,7 @@ * @see {@link https://www.w3.org/TR/selectors-4/} * */ -class WP_CSS_Selector_List implements IWP_CSS_Selector_Matcher { +class WP_CSS_Selector_List extends WP_CSS_Selector_Parser implements IWP_CSS_Selector_Matcher { public function matches( WP_HTML_Processor $processor ): bool { if ( $processor->get_token_type() !== '#tag' ) { return false; @@ -91,8 +91,14 @@ public function matches( WP_HTML_Processor $processor ): bool { return false; } + /** + * @var array + */ private $selectors; + /** + * @param array $selectors + */ private function __construct( array $selectors ) { $this->selectors = $selectors; } @@ -122,7 +128,7 @@ private static function parse( string $input ) { $input = trim( $input, " \t\r\n\r" ); if ( '' === $input ) { - null; + return null; } /* @@ -144,7 +150,7 @@ private static function parse( string $input ) { if ( null === $selector ) { return null; } - WP_CSS_Selector_Parser::parse_whitespace( $input, $offset ); + self::parse_whitespace( $input, $offset ); $selectors = array( $selector ); while ( $offset < strlen( $input ) ) { @@ -153,16 +159,16 @@ private static function parse( string $input ) { return null; } ++$offset; - WP_CSS_Selector_Parser::parse_whitespace( $input, $offset ); + self::parse_whitespace( $input, $offset ); $selector = WP_CSS_Complex_Selector::parse( $input, $offset ); if ( null === $selector ) { return null; } $selectors[] = $selector; - WP_CSS_Selector_Parser::parse_whitespace( $input, $offset ); + self::parse_whitespace( $input, $offset ); } - return new WP_CSS_Selector_List( $selectors ); + return new self( $selectors ); } } @@ -180,7 +186,7 @@ interface IWP_CSS_Selector_Parser { public static function parse( string $input, int &$offset ); } -abstract class WP_CSS_Selector_Parser implements IWP_CSS_Selector_Parser, IWP_CSS_Selector_Matcher { +abstract class WP_CSS_Selector_Parser { const UTF8_MAX_CODEPOINT_VALUE = 0x10FFFF; const WHITESPACE_CHARACTERS = " \t\r\n\f"; @@ -216,7 +222,6 @@ protected static function parse_hash_token( string $input, int &$offset ): ?stri if ( null === $result ) { return null; - $offset = $updated_offset; } $offset = $updated_offset; @@ -263,8 +268,8 @@ protected static function parse_ident( string $input, int &$offset ): ?string { continue; } elseif ( self::is_ident_codepoint( $input, $offset ) ) { // @todo this should append and advance the correct number of bytes. - $ident .= $input[ $offset ]; - $offset += 1; + $ident .= $input[ $offset ]; + ++$offset; continue; } break; @@ -378,6 +383,10 @@ protected static function parse_string( string $input, int &$offset ): ?string { * > This is a parse error. Return U+FFFD REPLACEMENT CHARACTER (�). * > anything else * > Return the current input code point. + * + * @param string $input + * @param int $offset + * @return string|null */ protected static function consume_escaped_codepoint( $input, &$offset ): ?string { $hex_length = strspn( $input, '0123456789abcdefABCDEF', $offset, 6 ); @@ -558,7 +567,8 @@ protected static function check_if_three_code_points_would_start_an_ident_sequen } } -final class WP_CSS_ID_Selector extends WP_CSS_Selector_Parser { +final class WP_CSS_ID_Selector extends WP_CSS_Selector_Parser implements IWP_CSS_Selector_Parser, IWP_CSS_Selector_Matcher { + /** @var string */ public $ident; @@ -591,7 +601,7 @@ public function matches( WP_HTML_Processor $processor ): bool { } } -final class WP_CSS_Class_Selector extends WP_CSS_Selector_Parser { +final class WP_CSS_Class_Selector extends WP_CSS_Selector_Parser implements IWP_CSS_Selector_Parser, IWP_CSS_Selector_Matcher { public function matches( WP_HTML_Processor $processor ): bool { return (bool) $processor->has_class( $this->ident ); } @@ -629,7 +639,7 @@ public static function parse( string $input, int &$offset ): ?self { } } -final class WP_CSS_Type_Selector extends WP_CSS_Selector_Parser { +final class WP_CSS_Type_Selector extends WP_CSS_Selector_Parser implements IWP_CSS_Selector_Parser, IWP_CSS_Selector_Matcher { public function matches( WP_HTML_Processor $processor ): bool { if ( '*' === $this->ident ) { return true; @@ -681,7 +691,7 @@ public static function parse( string $input, int &$offset ): ?self { } } -final class WP_CSS_Attribute_Selector extends WP_CSS_Selector_Parser { +final class WP_CSS_Attribute_Selector extends WP_CSS_Selector_Parser implements IWP_CSS_Selector_Parser, IWP_CSS_Selector_Matcher { public function matches( WP_HTML_Processor $processor ): bool { $att_value = $processor->get_attribute( $this->name ); if ( null === $att_value ) { @@ -990,7 +1000,7 @@ public static function parse( string $input, int &$offset ): ?self { * * > = [ ? * ]! */ -final class WP_CSS_Selector extends WP_CSS_Selector_Parser { +final class WP_CSS_Selector extends WP_CSS_Selector_Parser implements IWP_CSS_Selector_Parser, IWP_CSS_Selector_Matcher { public function matches( WP_HTML_Processor $processor ): bool { if ( $this->type_selector ) { if ( ! $this->type_selector->matches( $processor ) ) { @@ -1013,6 +1023,10 @@ public function matches( WP_HTML_Processor $processor ): bool { /** @var array|null */ public $subclass_selectors; + /** + * @param WP_CSS_Type_Selector|null $type_selector + * @param array $subclass_selectors + */ private function __construct( ?WP_CSS_Type_Selector $type_selector, array $subclass_selectors ) { $this->type_selector = $type_selector; $this->subclass_selectors = array() === $subclass_selectors ? null : $subclass_selectors; @@ -1071,7 +1085,7 @@ private static function parse_subclass_selector( string $input, int &$offset ) { * * > = [ ? ]* */ -final class WP_CSS_Complex_Selector extends WP_CSS_Selector_Parser { +final class WP_CSS_Complex_Selector extends WP_CSS_Selector_Parser implements IWP_CSS_Selector_Parser, IWP_CSS_Selector_Matcher { public function matches( WP_HTML_Processor $processor ): bool { if ( count( $this->selectors ) === 1 ) { return $this->selectors[0]->matches( $processor ); @@ -1091,6 +1105,7 @@ public function matches( WP_HTML_Processor $processor ): bool { * This only looks at breadcrumbs and can therefore only support type selectors. * * @param array $selectors + * @param array $breadcrumbs */ private function explore_matches( array $selectors, array $breadcrumbs ): bool { if ( array() === $selectors ) { @@ -1139,10 +1154,13 @@ private function explore_matches( array $selectors, array $breadcrumbs ): bool { * In reverse order to match the current element and then work up the tree. * Any non-final selector is a type selector. * - * @var array + * @var array */ public $selectors = array(); + /** + * @param array $selectors + */ private function __construct( array $selectors ) { $this->selectors = array_reverse( $selectors ); } From 58c1698b16a55ac3d9bc92c35b4c2346e43b67c7 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 29 Nov 2024 17:40:46 +0100 Subject: [PATCH 064/634] update tests --- .../phpunit/tests/html-api/wpCssSelectors.php | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpCssSelectors.php b/tests/phpunit/tests/html-api/wpCssSelectors.php index 33ada4ccbe3f9..5983f91c5d9ba 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectors.php +++ b/tests/phpunit/tests/html-api/wpCssSelectors.php @@ -309,8 +309,12 @@ public static function data_attribute_selectors(): array { '[href=foo]' => array( '[href=foo]', 'href', WP_CSS_Attribute_Selector::MATCH_EXACT, 'foo', null, '' ), '[href \n = bar ]' => array( "[href \n = bar ]", 'href', WP_CSS_Attribute_Selector::MATCH_EXACT, 'bar', null, '' ), '[href \n ^= baz ]' => array( "[href \n ^= baz ]", 'href', WP_CSS_Attribute_Selector::MATCH_PREFIXED_BY, 'baz', null, '' ), + '[match $= insensitive i]' => array( '[match $= insensitive i]', 'match', WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY, 'insensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), '[match|=sensitive s]' => array( '[match|=sensitive s]', 'match', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'sensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), + '[att=val I]' => array( '[att=val I]', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'val', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), + '[att=val S]' => array( '[att=val S]', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'val', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), + '[match~="quoted[][]"]' => array( '[match~="quoted[][]"]', 'match', WP_CSS_Attribute_Selector::MATCH_ONE_OF_EXACT, 'quoted[][]', null, '' ), "[match$='quoted!{}']" => array( "[match$='quoted!{}']", 'match', WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY, 'quoted!{}', null, '' ), "[match*='quoted's]" => array( "[match*='quoted's]", 'match', WP_CSS_Attribute_Selector::MATCH_CONTAINS, 'quoted', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), @@ -332,8 +336,6 @@ public static function data_attribute_selectors(): array { 'Invalid: [att=val ' => array( '[att=val ' ), 'Invalid: [att i]' => array( '[att i]' ), 'Invalid: [att s]' => array( '[att s]' ), - 'Invalid: [att="val" I]' => array( '[att="val" I]' ), - 'Invalid: [att="val" S]' => array( '[att="val" S]' ), "Invalid: [att='val\\n']" => array( "[att='val\n']" ), 'Invalid: [att=val i ' => array( '[att=val i ' ), ); @@ -371,17 +373,21 @@ public function test_parse_empty_selector() { * @ticket TBD */ public function test_parse_complex_selector() { - $input = 'el.foo#bar[baz=quux] > .child , rest'; + $input = 'el1 > .child#bar[baz=quux] , rest'; $offset = 0; $sel = WP_CSS_Complex_Selector::parse( $input, $offset ); $this->assertSame( 3, count( $sel->selectors ) ); - $this->assertNotNull( $sel->selectors[0]->type_selector ); - $this->assertSame( 3, count( $sel->selectors[0]->subclass_selectors ) ); + + $this->assertSame( 'el1', $sel->selectors[2]->type_selector->ident ); + $this->assertNull( $sel->selectors[2]->subclass_selectors ); + $this->assertSame( WP_CSS_Complex_Selector::COMBINATOR_CHILD, $sel->selectors[1] ); - $this->assertNull( $sel->selectors[2]->type_selector ); - $this->assertSame( 1, count( $sel->selectors[2]->subclass_selectors ) ); - $this->assertSame( 'child', $sel->selectors[2]->subclass_selectors[0]->ident ); + + $this->assertSame( 3, count( $sel->selectors[0]->subclass_selectors ) ); + $this->assertNull( $sel->selectors[0]->type_selector ); + $this->assertSame( 3, count( $sel->selectors[0]->subclass_selectors ) ); + $this->assertSame( 'child', $sel->selectors[0]->subclass_selectors[0]->ident ); $this->assertSame( ', rest', substr( $input, $offset ) ); } @@ -408,7 +414,7 @@ public function test_parse_empty_complex_selector() { * @ticket TBD */ public function test_parse_selector_list() { - $input = 'el.foo#bar[baz=quux] .descendent , rest'; + $input = 'el1 el2 el.foo#bar[baz=quux], rest'; $result = WP_CSS_Selector_List::from_selectors( $input ); $this->assertNotNull( $result ); } From c9b914517674004d8b7c38099325183cf3a592a8 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 29 Nov 2024 17:44:21 +0100 Subject: [PATCH 065/634] Id attribute must be a string to match id selector --- src/wp-includes/html-api/class-wp-css-selectors.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 28e51aa9a9735..8af33c2194723 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -594,9 +594,14 @@ public static function parse( string $input, int &$offset ): ?self { } public function matches( WP_HTML_Processor $processor ): bool { + $id = $processor->get_attribute( 'id' ); + if ( ! is_string( $id ) ) { + return false; + } + $case_insensitive = method_exists( $processor, 'is_quirks_mode' ) && $processor->is_quirks_mode(); return $case_insensitive - ? 0 === strcasecmp( $processor->get_attribute( 'id' ), $this->ident ) + ? 0 === strcasecmp( $id, $this->ident ) : $processor->get_attribute( 'id' ) === $this->ident; } } From e5cac63369f3c7b1a6cdf3c02c097bdae4e3d669 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 29 Nov 2024 17:47:31 +0100 Subject: [PATCH 066/634] Coerce boolean attributes to "" --- src/wp-includes/html-api/class-wp-css-selectors.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 8af33c2194723..8b92150cbef8f 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -707,6 +707,10 @@ public function matches( WP_HTML_Processor $processor ): bool { return true; } + if ( true === $att_value ) { + $att_value = ''; + } + $case_insensitive = self::MODIFIER_CASE_INSENSITIVE === $this->modifier; switch ( $this->matcher ) { From 2bafae995a64897ec393167e8a7416b74ff8b485 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 29 Nov 2024 17:56:57 +0100 Subject: [PATCH 067/634] Fix a few more static analysis things --- .../html-api/class-wp-css-selectors.php | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 8b92150cbef8f..87e32727a434e 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -871,6 +871,12 @@ private function whitespace_delimited_list( string $input ): Generator { */ public $modifier; + /** + * @param string $name + * @param null|self::MATCH_* $matcher + * @param null|string $value + * @param null|self::MODIFIER_* $modifier + */ private function __construct( string $name, ?string $matcher = null, ?string $value = null, ?string $modifier = null ) { $this->name = $name; $this->matcher = $matcher; @@ -1092,19 +1098,20 @@ private static function parse_subclass_selector( string $input, int &$offset ) { /** * This corresponds to in the grammar. * - * > = [ ? ]* + * > = [ ? ] * */ final class WP_CSS_Complex_Selector extends WP_CSS_Selector_Parser implements IWP_CSS_Selector_Parser, IWP_CSS_Selector_Matcher { public function matches( WP_HTML_Processor $processor ): bool { - if ( count( $this->selectors ) === 1 ) { - return $this->selectors[0]->matches( $processor ); - } - // First selector must match this location. if ( ! $this->selectors[0]->matches( $processor ) ) { return false; } + if ( count( $this->selectors ) === 1 ) { + return true; + } + + /** @var array $breadcrumbs */ $breadcrumbs = array_slice( array_reverse( $processor->get_breadcrumbs() ), 1 ); $selectors = array_slice( $this->selectors, 1 ); return $this->explore_matches( $selectors, $breadcrumbs ); From 8fe57e393d947c2b8db0ee326cfa7989ade8c801 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 28 Nov 2024 18:04:13 +0100 Subject: [PATCH 068/634] Add select method --- .../html-api/class-wp-html-processor.php | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index e88757ec7b4c2..438dee4c47f4e 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -635,6 +635,44 @@ public function get_unsupported_exception() { return $this->unsupported_exception; } + /** + * Use a selector to advance. + * + * @param string $selectors + * @return Generator|null + */ + public function select_all( string $selectors ): ?Generator { + $select = WP_CSS_Selector_List::from_selectors( $selectors ); + if ( null === $select ) { + return null; + } + + while ( $this->next_tag() ) { + if ( $select->matches( $this ) ) { + yield; + } + } + } + + /** + * Select the next matching element. + * + * If iterating through matching elements, use `select_all` instead. + * + * @param string $selectors + * @return bool|null + */ + public function select( string $selectors ) { + $selection = $this->select_all( $selectors ); + if ( null === $selection ) { + return null; + } + foreach ( $selection as $_ ) { + return true; + } + return false; + } + /** * Finds the next tag matching the $query. * From ab2fe0d78e2f2f54b29dae6ddb36a664f703d476 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 3 Dec 2024 18:20:01 +0100 Subject: [PATCH 069/634] Unify parsing under single class --- .../html-api/class-wp-css-selectors.php | 820 +++++++++--------- .../html-api/class-wp-html-processor.php | 2 +- .../phpunit/tests/html-api/wpCssSelectors.php | 121 ++- 3 files changed, 510 insertions(+), 433 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selectors.php index 87e32727a434e..7588eb72294bd 100644 --- a/src/wp-includes/html-api/class-wp-css-selectors.php +++ b/src/wp-includes/html-api/class-wp-css-selectors.php @@ -16,8 +16,8 @@ * * This class is designed for internal use by the HTML processor. * - * This class is instantiated via the `WP_CSS_Selector_List::from_selector( string $selector )` method. - * It accepts a CSS selector string and returns an instance of itself or `null` if the selector + * This class is instantiated via the `WP_CSS_Selector::from_selectors( string $input )` method. + * It takes a CSS selector string and returns an instance of itself or `null` if the selector * is invalid or unsupported. * * A subset of the CSS selector grammar is supported. The grammar is defined in the CSS Syntax @@ -39,7 +39,7 @@ * = '[' ']' | * '[' [ | ] ? ']' * = [ '~' | '|' | '^' | '$' | '*' ]? '=' - * = i | s + * = i | I | s | S * * @link https://www.w3.org/TR/selectors/#grammar Refer to the grammar for more details. * @@ -77,7 +77,7 @@ * @see {@link https://www.w3.org/TR/selectors-4/} * */ -class WP_CSS_Selector_List extends WP_CSS_Selector_Parser implements IWP_CSS_Selector_Matcher { +class WP_CSS_Selector implements IWP_CSS_Selector_Matcher { public function matches( WP_HTML_Processor $processor ): bool { if ( $processor->get_token_type() !== '#tag' ) { return false; @@ -97,34 +97,25 @@ public function matches( WP_HTML_Processor $processor ): bool { private $selectors; /** + * Constructor. + * * @param array $selectors */ - private function __construct( array $selectors ) { + protected function __construct( array $selectors ) { $this->selectors = $selectors; } /** - * Takes a CSS selectors string and returns an instance of itself or `null` if the selector - * is invalid or unsupported. - * - * @since TBD - * - * @param string $selectors CSS selectors string. - * @return self|null - */ - public static function from_selectors( string $selectors ): ?self { - return self::parse( $selectors ); - } - - /** - * Returns a list of selectors. + * Takes a CSS selector string and returns an instance of itself or `null` if the selector + * string is invalid or unsupported. * * @since TBD * + * @param string $input CSS selectors. * @return self|null */ - private static function parse( string $input ) { - // > A selector string is a list of one or more complex selectors ([SELECTORS4], section 3.1) that may be surrounded by whitespace and matches the dom_selectors_group production. + public static function from_selectors( string $input ): ?self { + // > A selector string is a list of one or more complex selectors ([SELECTORS4], section 3.1) that may be surrounded by whitespace… $input = trim( $input, " \t\r\n\r" ); if ( '' === $input ) { @@ -146,7 +137,7 @@ private static function parse( string $input ) { $offset = 0; - $selector = WP_CSS_Complex_Selector::parse( $input, $offset ); + $selector = self::parse_complex_selector( $input, $offset ); if ( null === $selector ) { return null; } @@ -160,7 +151,7 @@ private static function parse( string $input ) { } ++$offset; self::parse_whitespace( $input, $offset ); - $selector = WP_CSS_Complex_Selector::parse( $input, $offset ); + $selector = self::parse_complex_selector( $input, $offset ); if ( null === $selector ) { return null; } @@ -170,23 +161,343 @@ private static function parse( string $input ) { return new self( $selectors ); } -} -interface IWP_CSS_Selector_Matcher { + /* + * ------------------------------ + * Selector parsing functionality + * ------------------------------ + */ + /** - * @return bool + * Parse an ID selector + * + * > = + * + * https://www.w3.org/TR/selectors/#grammar + * + * @return WP_CSS_ID_Selector|null */ - public function matches( WP_HTML_Processor $processor ): bool; -} + final protected static function parse_id_selector( string $input, int &$offset ): ?WP_CSS_ID_Selector { + $ident = self::parse_hash_token( $input, $offset ); + if ( null === $ident ) { + return null; + } + return new WP_CSS_ID_Selector( $ident ); + } -interface IWP_CSS_Selector_Parser { /** - * @return static|null + * Parse a class selector + * + * > = '.' + * + * https://www.w3.org/TR/selectors/#grammar + * + * @return WP_CSS_Class_Selector|null + */ + final protected static function parse_class_selector( string $input, int &$offset ): ?WP_CSS_Class_Selector { + if ( $offset + 1 >= strlen( $input ) || '.' !== $input[ $offset ] ) { + return null; + } + + $updated_offset = $offset + 1; + $result = self::parse_ident( $input, $updated_offset ); + + if ( null === $result ) { + return null; + } + + $offset = $updated_offset; + return new WP_CSS_Class_Selector( $result ); + } + + /** + * Parse a type selector + * + * > = | ? '*' + * > = [ | '*' ]? '|' + * > = ? + * + * Namespaces (e.g. |div, *|div, or namespace|div) are not supported, + * so this selector effectively matches * or ident. + * + * https://www.w3.org/TR/selectors/#grammar + * + * @return WP_CSS_Type_Selector|null + */ + final protected static function parse_type_selector( string $input, int &$offset ): ?WP_CSS_Type_Selector { + if ( $offset >= strlen( $input ) ) { + return null; + } + + if ( '*' === $input[ $offset ] ) { + ++$offset; + return new WP_CSS_Type_Selector( '*' ); + } + + $result = self::parse_ident( $input, $offset ); + if ( null === $result ) { + return null; + } + + return new WP_CSS_Type_Selector( $result ); + } + + /** + * Parse an attribute selector + * + * > = '[' ']' | + * > '[' [ | ] ? ']' + * > = [ '~' | '|' | '^' | '$' | '*' ]? '=' + * > = i | s + * > = ? + * + * Namespaces are not supported, so attribute names are effectively identifiers. + * + * https://www.w3.org/TR/selectors/#grammar + * + * @return WP_CSS_Attribute_Selector|null + */ + final protected static function parse_attribute_selector( string $input, int &$offset ): ?WP_CSS_Attribute_Selector { + // Need at least 3 bytes [x] + if ( $offset + 2 >= strlen( $input ) ) { + return null; + } + + $updated_offset = $offset; + + if ( '[' !== $input[ $updated_offset ] ) { + return null; + } + ++$updated_offset; + + self::parse_whitespace( $input, $updated_offset ); + $attr_name = self::parse_ident( $input, $updated_offset ); + if ( null === $attr_name ) { + return null; + } + self::parse_whitespace( $input, $updated_offset ); + + if ( $updated_offset >= strlen( $input ) ) { + return null; + } + + if ( ']' === $input[ $updated_offset ] ) { + $offset = $updated_offset + 1; + return new WP_CSS_Attribute_Selector( $attr_name ); + } + + // need to match at least `=x]` at this point + if ( $updated_offset + 3 >= strlen( $input ) ) { + return null; + } + + if ( '=' === $input[ $updated_offset ] ) { + ++$updated_offset; + $attr_matcher = WP_CSS_Attribute_Selector::MATCH_EXACT; + } elseif ( '=' === $input[ $updated_offset + 1 ] ) { + switch ( $input[ $updated_offset ] ) { + case '~': + $attr_matcher = WP_CSS_Attribute_Selector::MATCH_ONE_OF_EXACT; + $updated_offset += 2; + break; + case '|': + $attr_matcher = WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN; + $updated_offset += 2; + break; + case '^': + $attr_matcher = WP_CSS_Attribute_Selector::MATCH_PREFIXED_BY; + $updated_offset += 2; + break; + case '$': + $attr_matcher = WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY; + $updated_offset += 2; + break; + case '*': + $attr_matcher = WP_CSS_Attribute_Selector::MATCH_CONTAINS; + $updated_offset += 2; + break; + default: + return null; + } + } else { + return null; + } + + self::parse_whitespace( $input, $updated_offset ); + $attr_val = + self::parse_string( $input, $updated_offset ) ?? + self::parse_ident( $input, $updated_offset ); + + if ( null === $attr_val ) { + return null; + } + + self::parse_whitespace( $input, $updated_offset ); + if ( $updated_offset >= strlen( $input ) ) { + return null; + } + + $attr_modifier = null; + switch ( $input[ $updated_offset ] ) { + case 'i': + case 'I': + $attr_modifier = WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE; + ++$updated_offset; + break; + + case 's': + case 'S': + $attr_modifier = WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE; + ++$updated_offset; + break; + } + + if ( null !== $attr_modifier ) { + self::parse_whitespace( $input, $updated_offset ); + if ( $updated_offset >= strlen( $input ) ) { + return null; + } + } + + if ( ']' === $input[ $updated_offset ] ) { + $offset = $updated_offset + 1; + return new WP_CSS_Attribute_Selector( $attr_name, $attr_matcher, $attr_val, $attr_modifier ); + } + + return null; + } + + /** + * Parses a compound selector. + * + * > = [ ? * ]! + * + * @return WP_CSS_Compound_Selector|null + */ + final protected static function parse_compound_selector( string $input, int &$offset ): ?WP_CSS_Compound_Selector { + if ( $offset >= strlen( $input ) ) { + return null; + } + + $updated_offset = $offset; + $type_selector = self::parse_type_selector( $input, $updated_offset ); + + $subclass_selectors = array(); + $last_parsed_subclass_selector = self::parse_subclass_selector( $input, $updated_offset ); + while ( null !== $last_parsed_subclass_selector ) { + $subclass_selectors[] = $last_parsed_subclass_selector; + $last_parsed_subclass_selector = self::parse_subclass_selector( $input, $updated_offset ); + } + + if ( null !== $type_selector || array() !== $subclass_selectors ) { + $offset = $updated_offset; + return new WP_CSS_Compound_Selector( $type_selector, $subclass_selectors ); + } + return null; + } + + /** + * Parses a complex selector. + * + * > = [ ? ]* + * + * @return WP_CSS_Complex_Selector|null + */ + final protected static function parse_complex_selector( string $input, int &$offset ): ?WP_CSS_Complex_Selector { + if ( $offset >= strlen( $input ) ) { + return null; + } + + $updated_offset = $offset; + $selector = self::parse_compound_selector( $input, $updated_offset ); + if ( null === $selector ) { + return null; + } + + $selectors = array( $selector ); + $has_preceding_subclass_selector = null !== $selector->subclass_selectors; + + $found_whitespace = self::parse_whitespace( $input, $updated_offset ); + while ( $updated_offset < strlen( $input ) ) { + if ( + WP_CSS_Complex_Selector::COMBINATOR_CHILD === $input[ $updated_offset ] || + WP_CSS_Complex_Selector::COMBINATOR_NEXT_SIBLING === $input[ $updated_offset ] || + WP_CSS_Complex_Selector::COMBINATOR_SUBSEQUENT_SIBLING === $input[ $updated_offset ] + ) { + $combinator = $input[ $updated_offset ]; + ++$updated_offset; + self::parse_whitespace( $input, $updated_offset ); + + // Failure to find a selector here is a parse error + $selector = self::parse_compound_selector( $input, $updated_offset ); + } elseif ( $found_whitespace ) { + /* + * Whitespace is ambiguous, it could be a descendant combinator or + * insignificant whitespace. + */ + $selector = self::parse_compound_selector( $input, $updated_offset ); + if ( null === $selector ) { + break; + } + $combinator = WP_CSS_Complex_Selector::COMBINATOR_DESCENDANT; + } else { + break; + } + + if ( null === $selector ) { + return null; + } + + // `div > .className` is valid, but `.className > div` is not. + if ( $has_preceding_subclass_selector ) { + throw new Exception( 'Unsupported non-final subclass selector.' ); + } + $has_preceding_subclass_selector = null !== $selector->subclass_selectors; + + $selectors[] = $combinator; + $selectors[] = $selector; + + $found_whitespace = self::parse_whitespace( $input, $updated_offset ); + } + $offset = $updated_offset; + return new WP_CSS_Complex_Selector( $selectors ); + } + + /** + * Parses a subclass selector. + * + * > = | | + * + * @return WP_CSS_ID_Selector|WP_CSS_Class_Selector|WP_CSS_Attribute_Selector|null + */ + private static function parse_subclass_selector( string $input, int &$offset ) { + if ( $offset >= strlen( $input ) ) { + return null; + } + + $next_char = $input[ $offset ]; + return '.' === $next_char + ? self::parse_class_selector( $input, $offset ) + : ( + '#' === $next_char + ? self::parse_id_selector( $input, $offset ) + : ( '[' === $next_char + ? self::parse_attribute_selector( $input, $offset ) + : null + ) + ); + } + + + /* + * ------------------------ + * Selector partial parsing + * ------------------------ + * + * These functions consume parts of a selector string input when successful + * and return meaningful values to be used by selectors. */ - public static function parse( string $input, int &$offset ); -} -abstract class WP_CSS_Selector_Parser { const UTF8_MAX_CODEPOINT_VALUE = 0x10FFFF; const WHITESPACE_CHARACTERS = " \t\r\n\f"; @@ -212,7 +523,7 @@ public static function parse_whitespace( string $input, int &$offset ): bool { * * This implementation is not interested in the , a '#' delim token is not relevant for selectors. */ - protected static function parse_hash_token( string $input, int &$offset ): ?string { + final protected static function parse_hash_token( string $input, int &$offset ): ?string { if ( $offset + 1 >= strlen( $input ) || '#' !== $input[ $offset ] ) { return null; } @@ -253,7 +564,7 @@ protected static function parse_hash_token( string $input, int &$offset ): ?stri * * @return string|null */ - protected static function parse_ident( string $input, int &$offset ): ?string { + final protected static function parse_ident( string $input, int &$offset ): ?string { if ( ! self::check_if_three_code_points_would_start_an_ident_sequence( $input, $offset ) ) { return null; } @@ -312,7 +623,7 @@ protected static function parse_ident( string $input, int &$offset ): ?string { * * @return string|null */ - protected static function parse_string( string $input, int &$offset ): ?string { + final protected static function parse_string( string $input, int &$offset ): ?string { if ( $offset + 1 >= strlen( $input ) ) { return null; } @@ -388,16 +699,24 @@ protected static function parse_string( string $input, int &$offset ): ?string { * @param int $offset * @return string|null */ - protected static function consume_escaped_codepoint( $input, &$offset ): ?string { + final protected static function consume_escaped_codepoint( $input, &$offset ): ?string { $hex_length = strspn( $input, '0123456789abcdefABCDEF', $offset, 6 ); if ( $hex_length > 0 ) { + /** + * The 6-character hex string has a maximum value of 0xFFFFFF. + * It is likely to fit in an int value and not be a float. + * + * @var int + */ $codepoint_value = hexdec( substr( $input, $offset, $hex_length ) ); - // > A surrogate is a leading surrogate or a trailing surrogate. - // > A leading surrogate is a code point that is in the range U+D800 to U+DBFF, inclusive. - // > A trailing surrogate is a code point that is in the range U+DC00 to U+DFFF, inclusive. - // The surrogate ranges are adjacent, so the complete range is 0xD800..=0xDFFF, - // inclusive. + /* + * > A surrogate is a leading surrogate or a trailing surrogate. + * > A leading surrogate is a code point that is in the range U+D800 to U+DBFF, inclusive. + * > A trailing surrogate is a code point that is in the range U+DC00 to U+DFFF, inclusive. + * + * The surrogate ranges are adjacent, so the complete range is 0xD800 to 0xDFFF, inclusive. + */ $codepoint_char = ( 0 === $codepoint_value || $codepoint_value > self::UTF8_MAX_CODEPOINT_VALUE || @@ -428,13 +747,16 @@ protected static function consume_escaped_codepoint( $input, &$offset ): ?string } /* - * Utiltities - * ========== + * --------------------------- + * Selector parsing utiltities + * --------------------------- * - * The following functions do not consume any input. + * The following functions are used for parsing but do not consume any input. */ /** + * Checks for two valid escape codepoints. + * * > 4.3.8. Check if two code points are a valid escape * > This section describes how to check if two code points are a valid escape. The algorithm described here can be called explicitly with two code points, or can be called with the input stream itself. In the latter case, the two code points in question are the current input code point and the next input code point, in that order. * > @@ -449,8 +771,12 @@ protected static function consume_escaped_codepoint( $input, &$offset ): ?string * https://www.w3.org/TR/css-syntax-3/#starts-with-a-valid-escape * * @todo this does not check whether the second codepoint is valid. + * + * @param string $input The input string. + * @param int $offset The byte offset in the string. + * @return bool True if the next two codepoints are a valid escape, otherwise false. */ - protected static function next_two_are_valid_escape( string $input, int $offset ): bool { + private static function next_two_are_valid_escape( string $input, int $offset ): bool { if ( $offset + 1 >= strlen( $input ) ) { return false; } @@ -458,7 +784,7 @@ protected static function next_two_are_valid_escape( string $input, int $offset } /** - * Check if the next code point is an "ident start code point". + * Checks if the next code point is an "ident start code point". * * Caution! This method does not do any bounds checking, it should not be passed * a string with an offset that is out of bounds. @@ -474,9 +800,13 @@ protected static function next_two_are_valid_escape( string $input, int $offset * > non-ASCII code point * > A code point with a value equal to or greater than U+0080 . * - * https://www.w3.org/TR/css-syntax-3/#ident-start-code-point + * @link https://www.w3.org/TR/css-syntax-3/#ident-start-code-point + * + * @param string $input The input string. + * @param int $offset The byte offset in the string. + * @return bool True if the next codepoint is an ident start code point, otherwise false. */ - protected static function is_ident_start_codepoint( string $input, int $offset ): bool { + final protected static function is_ident_start_codepoint( string $input, int $offset ): bool { return ( '_' === $input[ $offset ] || ( 'a' <= $input[ $offset ] && $input[ $offset ] <= 'z' ) || @@ -486,7 +816,7 @@ protected static function is_ident_start_codepoint( string $input, int $offset ) } /** - * Check if the next code point is an "ident code point". + * Checks if the next code point is an "ident code point". * * Caution! This method does not do any bounds checking, it should not be passed * a string with an offset that is out of bounds. @@ -496,15 +826,21 @@ protected static function is_ident_start_codepoint( string $input, int $offset ) * > digit * > A code point between U+0030 DIGIT ZERO (0) and U+0039 DIGIT NINE (9) inclusive. * - * https://www.w3.org/TR/css-syntax-3/#ident-code-point + * @link https://www.w3.org/TR/css-syntax-3/#ident-code-point + * + * @param string $input The input string. + * @param int $offset The byte offset in the string. + * @return bool True if the next codepoint is an ident code point, otherwise false. */ - protected static function is_ident_codepoint( string $input, int $offset ): bool { + final protected static function is_ident_codepoint( string $input, int $offset ): bool { return '-' === $input[ $offset ] || ( '0' <= $input[ $offset ] && $input[ $offset ] <= '9' ) || self::is_ident_start_codepoint( $input, $offset ); } /** + * Checks if three code points would start an ident sequence. + * * > 4.3.9. Check if three code points would start an ident sequence * > This section describes how to check if three code points would start an ident sequence. The algorithm described here can be called explicitly with three code points, or can be called with the input stream itself. In the latter case, the three code points in question are the current input code point and the next two input code points, in that order. * > @@ -521,9 +857,13 @@ protected static function is_ident_codepoint( string $input, int $offset ): bool * > anything else * > Return false. * - * https://www.w3.org/TR/css-syntax-3/#would-start-an-identifier + * @link https://www.w3.org/TR/css-syntax-3/#would-start-an-identifier + * + * @param string $input The input string. + * @param int $offset The byte offset in the string. + * @return bool True if the next three codepoints would start an ident sequence, otherwise false. */ - protected static function check_if_three_code_points_would_start_an_ident_sequence( string $input, int $offset ): bool { + private static function check_if_three_code_points_would_start_an_ident_sequence( string $input, int $offset ): bool { if ( $offset >= strlen( $input ) ) { return false; } @@ -567,32 +907,21 @@ protected static function check_if_three_code_points_would_start_an_ident_sequen } } -final class WP_CSS_ID_Selector extends WP_CSS_Selector_Parser implements IWP_CSS_Selector_Parser, IWP_CSS_Selector_Matcher { +interface IWP_CSS_Selector_Matcher { + /** + * @return bool + */ + public function matches( WP_HTML_Processor $processor ): bool; +} +final class WP_CSS_ID_Selector implements IWP_CSS_Selector_Matcher { /** @var string */ public $ident; - private function __construct( string $ident ) { + public function __construct( string $ident ) { $this->ident = $ident; } - /** - * Parse an ID selector - * - * > = - * - * https://www.w3.org/TR/selectors/#grammar - * - * @return self|null - */ - public static function parse( string $input, int &$offset ): ?self { - $ident = self::parse_hash_token( $input, $offset ); - if ( null === $ident ) { - return null; - } - return new self( $ident ); - } - public function matches( WP_HTML_Processor $processor ): bool { $id = $processor->get_attribute( 'id' ); if ( ! is_string( $id ) ) { @@ -606,50 +935,29 @@ public function matches( WP_HTML_Processor $processor ): bool { } } -final class WP_CSS_Class_Selector extends WP_CSS_Selector_Parser implements IWP_CSS_Selector_Parser, IWP_CSS_Selector_Matcher { - public function matches( WP_HTML_Processor $processor ): bool { - return (bool) $processor->has_class( $this->ident ); - } - - /** @var string */ - public $ident; - - private function __construct( string $ident ) { - $this->ident = $ident; - } - - /** - * Parse a class selector - * - * > = '.' - * - * https://www.w3.org/TR/selectors/#grammar - * - * @return self|null - */ - public static function parse( string $input, int &$offset ): ?self { - if ( $offset + 1 >= strlen( $input ) || '.' !== $input[ $offset ] ) { - return null; - } - - $updated_offset = $offset + 1; - $result = self::parse_ident( $input, $updated_offset ); - - if ( null === $result ) { - return null; - } +final class WP_CSS_Class_Selector implements IWP_CSS_Selector_Matcher { + public function matches( WP_HTML_Processor $processor ): bool { + return (bool) $processor->has_class( $this->ident ); + } - $offset = $updated_offset; - return new self( $result ); + /** @var string */ + public $ident; + + public function __construct( string $ident ) { + $this->ident = $ident; } } -final class WP_CSS_Type_Selector extends WP_CSS_Selector_Parser implements IWP_CSS_Selector_Parser, IWP_CSS_Selector_Matcher { +final class WP_CSS_Type_Selector implements IWP_CSS_Selector_Matcher { public function matches( WP_HTML_Processor $processor ): bool { + $tag_name = $processor->get_tag(); + if ( null === $tag_name ) { + return false; + } if ( '*' === $this->ident ) { return true; } - return 0 === strcasecmp( $processor->get_tag(), $this->ident ); + return 0 === strcasecmp( $tag_name, $this->ident ); } /** @@ -659,44 +967,12 @@ public function matches( WP_HTML_Processor $processor ): bool { */ public $ident; - private function __construct( string $ident ) { + public function __construct( string $ident ) { $this->ident = $ident; } - - /** - * Parse a type selector - * - * > = | ? '*' - * > = [ | '*' ]? '|' - * > = ? - * - * Namespaces (e.g. |div, *|div, or namespace|div) are not supported, - * so this selector effectively matches * or ident. - * - * https://www.w3.org/TR/selectors/#grammar - * - * @return self|null - */ - public static function parse( string $input, int &$offset ): ?self { - if ( $offset >= strlen( $input ) ) { - return null; - } - - if ( '*' === $input[ $offset ] ) { - ++$offset; - return new self( '*' ); - } - - $result = self::parse_ident( $input, $offset ); - if ( null === $result ) { - return null; - } - - return new self( $result ); - } } -final class WP_CSS_Attribute_Selector extends WP_CSS_Selector_Parser implements IWP_CSS_Selector_Parser, IWP_CSS_Selector_Matcher { +final class WP_CSS_Attribute_Selector implements IWP_CSS_Selector_Matcher { public function matches( WP_HTML_Processor $processor ): bool { $att_value = $processor->get_attribute( $this->name ); if ( null === $att_value ) { @@ -772,17 +1048,17 @@ public function matches( WP_HTML_Processor $processor ): bool { * @return Generator */ private function whitespace_delimited_list( string $input ): Generator { - $offset = strspn( $input, self::WHITESPACE_CHARACTERS ); + $offset = strspn( $input, WP_CSS_Selector::WHITESPACE_CHARACTERS ); while ( $offset < strlen( $input ) ) { // Find the byte length until the next boundary. - $length = strcspn( $input, self::WHITESPACE_CHARACTERS, $offset ); + $length = strcspn( $input, WP_CSS_Selector::WHITESPACE_CHARACTERS, $offset ); if ( 0 === $length ) { return; } $value = substr( $input, $offset, $length ); - $offset += $length + strspn( $input, self::WHITESPACE_CHARACTERS, $offset + $length ); + $offset += $length + strspn( $input, WP_CSS_Selector::WHITESPACE_CHARACTERS, $offset + $length ); yield $value; } @@ -877,137 +1153,12 @@ private function whitespace_delimited_list( string $input ): Generator { * @param null|string $value * @param null|self::MODIFIER_* $modifier */ - private function __construct( string $name, ?string $matcher = null, ?string $value = null, ?string $modifier = null ) { + public function __construct( string $name, ?string $matcher = null, ?string $value = null, ?string $modifier = null ) { $this->name = $name; $this->matcher = $matcher; $this->value = $value; $this->modifier = $modifier; } - - /** - * Parse a attribute selector - * - * > = '[' ']' | - * > '[' [ | ] ? ']' - * > = [ '~' | '|' | '^' | '$' | '*' ]? '=' - * > = i | s - * > = ? - * - * Namespaces are not supported, so attribute names are effectively identifiers. - * - * https://www.w3.org/TR/selectors/#grammar - * - * @return self|null - */ - public static function parse( string $input, int &$offset ): ?self { - // Need at least 3 bytes [x] - if ( $offset + 2 >= strlen( $input ) ) { - return null; - } - - $updated_offset = $offset; - - if ( '[' !== $input[ $updated_offset ] ) { - return null; - } - ++$updated_offset; - - self::parse_whitespace( $input, $updated_offset ); - $attr_name = self::parse_ident( $input, $updated_offset ); - if ( null === $attr_name ) { - return null; - } - self::parse_whitespace( $input, $updated_offset ); - - if ( $updated_offset >= strlen( $input ) ) { - return null; - } - - if ( ']' === $input[ $updated_offset ] ) { - $offset = $updated_offset + 1; - return new self( $attr_name ); - } - - // need to match at least `=x]` at this point - if ( $updated_offset + 3 >= strlen( $input ) ) { - return null; - } - - if ( '=' === $input[ $updated_offset ] ) { - ++$updated_offset; - $attr_matcher = WP_CSS_Attribute_Selector::MATCH_EXACT; - } elseif ( '=' === $input[ $updated_offset + 1 ] ) { - switch ( $input[ $updated_offset ] ) { - case '~': - $attr_matcher = WP_CSS_Attribute_Selector::MATCH_ONE_OF_EXACT; - $updated_offset += 2; - break; - case '|': - $attr_matcher = WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN; - $updated_offset += 2; - break; - case '^': - $attr_matcher = WP_CSS_Attribute_Selector::MATCH_PREFIXED_BY; - $updated_offset += 2; - break; - case '$': - $attr_matcher = WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY; - $updated_offset += 2; - break; - case '*': - $attr_matcher = WP_CSS_Attribute_Selector::MATCH_CONTAINS; - $updated_offset += 2; - break; - default: - return null; - } - } else { - return null; - } - - self::parse_whitespace( $input, $updated_offset ); - $attr_val = - self::parse_string( $input, $updated_offset ) ?? - self::parse_ident( $input, $updated_offset ); - - if ( null === $attr_val ) { - return null; - } - - self::parse_whitespace( $input, $updated_offset ); - if ( $updated_offset >= strlen( $input ) ) { - return null; - } - - $attr_modifier = null; - switch ( $input[ $updated_offset ] ) { - case 'i': - case 'I': - $attr_modifier = WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE; - ++$updated_offset; - break; - - case 's': - case 'S': - $attr_modifier = WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE; - ++$updated_offset; - break; - } - - if ( null !== $attr_modifier ) { - self::parse_whitespace( $input, $updated_offset ); - if ( $updated_offset >= strlen( $input ) ) { - return null; - } - } - - if ( ']' === $input[ $updated_offset ] ) { - $offset = $updated_offset + 1; - return new self( $attr_name, $attr_matcher, $attr_val, $attr_modifier ); - } - - return null; - } } /** @@ -1015,7 +1166,7 @@ public static function parse( string $input, int &$offset ): ?self { * * > = [ ? * ]! */ -final class WP_CSS_Selector extends WP_CSS_Selector_Parser implements IWP_CSS_Selector_Parser, IWP_CSS_Selector_Matcher { +final class WP_CSS_Compound_Selector implements IWP_CSS_Selector_Matcher { public function matches( WP_HTML_Processor $processor ): bool { if ( $this->type_selector ) { if ( ! $this->type_selector->matches( $processor ) ) { @@ -1042,65 +1193,18 @@ public function matches( WP_HTML_Processor $processor ): bool { * @param WP_CSS_Type_Selector|null $type_selector * @param array $subclass_selectors */ - private function __construct( ?WP_CSS_Type_Selector $type_selector, array $subclass_selectors ) { + public function __construct( ?WP_CSS_Type_Selector $type_selector, array $subclass_selectors ) { $this->type_selector = $type_selector; $this->subclass_selectors = array() === $subclass_selectors ? null : $subclass_selectors; } - - /** - * > = [ ? * ]! - */ - public static function parse( string $input, int &$offset ): ?self { - if ( $offset >= strlen( $input ) ) { - return null; - } - - $updated_offset = $offset; - $type_selector = WP_CSS_Type_Selector::parse( $input, $updated_offset ); - - $subclass_selectors = array(); - $last_parsed_subclass_selector = self::parse_subclass_selector( $input, $updated_offset ); - while ( null !== $last_parsed_subclass_selector ) { - $subclass_selectors[] = $last_parsed_subclass_selector; - $last_parsed_subclass_selector = self::parse_subclass_selector( $input, $updated_offset ); - } - - if ( null !== $type_selector || array() !== $subclass_selectors ) { - $offset = $updated_offset; - return new self( $type_selector, $subclass_selectors ); - } - return null; - } - - /** - * @return WP_CSS_ID_Selector|WP_CSS_Class_Selector|WP_CSS_Attribute_Selector|null - */ - private static function parse_subclass_selector( string $input, int &$offset ) { - if ( $offset >= strlen( $input ) ) { - return null; - } - - $next_char = $input[ $offset ]; - return '.' === $next_char - ? WP_CSS_Class_Selector::parse( $input, $offset ) - : ( - '#' === $next_char - ? WP_CSS_ID_Selector::parse( $input, $offset ) - : ( '[' === $next_char - ? WP_CSS_Attribute_Selector::parse( $input, $offset ) - : null - ) - ); - } } - /** * This corresponds to in the grammar. * * > = [ ? ] * */ -final class WP_CSS_Complex_Selector extends WP_CSS_Selector_Parser implements IWP_CSS_Selector_Parser, IWP_CSS_Selector_Matcher { +final class WP_CSS_Complex_Selector implements IWP_CSS_Selector_Matcher { public function matches( WP_HTML_Processor $processor ): bool { // First selector must match this location. if ( ! $this->selectors[0]->matches( $processor ) ) { @@ -1120,7 +1224,7 @@ public function matches( WP_HTML_Processor $processor ): bool { /** * This only looks at breadcrumbs and can therefore only support type selectors. * - * @param array $selectors + * @param array $selectors * @param array $breadcrumbs */ private function explore_matches( array $selectors, array $breadcrumbs ): bool { @@ -1133,7 +1237,7 @@ private function explore_matches( array $selectors, array $breadcrumbs ): bool { /** @var self::COMBINATOR_* $combinator */ $combinator = $selectors[0]; - /** @var WP_CSS_Selector $selector */ + /** @var WP_CSS_Compound_Selector $selector */ $selector = $selectors[1]; switch ( $combinator ) { @@ -1166,78 +1270,18 @@ private function explore_matches( array $selectors, array $breadcrumbs ): bool { const COMBINATOR_SUBSEQUENT_SIBLING = '~'; /** - * even indexes are WP_CSS_Selector, odd indexes are string combinators. + * even indexes are WP_CSS_Compound_Selector, odd indexes are string combinators. * In reverse order to match the current element and then work up the tree. * Any non-final selector is a type selector. * - * @var array + * @var array */ public $selectors = array(); /** - * @param array $selectors + * @param array $selectors */ - private function __construct( array $selectors ) { + public function __construct( array $selectors ) { $this->selectors = array_reverse( $selectors ); } - - public static function parse( string $input, int &$offset ): ?self { - if ( $offset >= strlen( $input ) ) { - return null; - } - - $updated_offset = $offset; - $selector = WP_CSS_Selector::parse( $input, $updated_offset ); - if ( null === $selector ) { - return null; - } - - $selectors = array( $selector ); - $has_preceding_subclass_selector = null !== $selector->subclass_selectors; - - $found_whitespace = self::parse_whitespace( $input, $updated_offset ); - while ( $updated_offset < strlen( $input ) ) { - if ( - self::COMBINATOR_CHILD === $input[ $updated_offset ] || - self::COMBINATOR_NEXT_SIBLING === $input[ $updated_offset ] || - self::COMBINATOR_SUBSEQUENT_SIBLING === $input[ $updated_offset ] - ) { - $combinator = $input[ $updated_offset ]; - ++$updated_offset; - self::parse_whitespace( $input, $updated_offset ); - - // Failure to find a selector here is a parse error - $selector = WP_CSS_Selector::parse( $input, $updated_offset ); - } elseif ( $found_whitespace ) { - /* - * Whitespace is ambiguous, it could be a descendant combinator or - * insignificant whitespace. - */ - $selector = WP_CSS_Selector::parse( $input, $updated_offset ); - if ( null === $selector ) { - break; - } - $combinator = self::COMBINATOR_DESCENDANT; - } else { - break; - } - - if ( null === $selector ) { - return null; - } - - // `div > .className` is valid, but `.className > div` is not. - if ( $has_preceding_subclass_selector ) { - throw new Exception( 'Unsupported non-final subclass selector.' ); - } - $has_preceding_subclass_selector = null !== $selector->subclass_selectors; - - $selectors[] = $combinator; - $selectors[] = $selector; - - $found_whitespace = self::parse_whitespace( $input, $updated_offset ); - } - $offset = $updated_offset; - return new self( $selectors ); - } } diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index 438dee4c47f4e..bee0f63824abd 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -642,7 +642,7 @@ public function get_unsupported_exception() { * @return Generator|null */ public function select_all( string $selectors ): ?Generator { - $select = WP_CSS_Selector_List::from_selectors( $selectors ); + $select = WP_CSS_Selector::from_selectors( $selectors ); if ( null === $select ) { return null; } diff --git a/tests/phpunit/tests/html-api/wpCssSelectors.php b/tests/phpunit/tests/html-api/wpCssSelectors.php index 5983f91c5d9ba..19c1595253d84 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectors.php +++ b/tests/phpunit/tests/html-api/wpCssSelectors.php @@ -11,6 +11,63 @@ * @group html-api */ class Tests_HtmlApi_WpCssSelectors extends WP_UnitTestCase { + private $test_class; + + public function set_up(): void { + parent::set_up(); + $this->test_class = new class() extends WP_CSS_Selector { + public function __construct() { + parent::__construct( array() ); + } + + /* + * Parsing + */ + public static function test_parse_ident( string $input, int &$offset ) { + return self::parse_ident( $input, $offset ); + } + + public static function test_parse_string( string $input, int &$offset ) { + return self::parse_string( $input, $offset ); + } + + public static function test_parse_type_selector( string $input, int &$offset ) { + return self::parse_type_selector( $input, $offset ); + } + + public static function test_parse_id_selector( string $input, int &$offset ) { + return self::parse_id_selector( $input, $offset ); + } + + public static function test_parse_class_selector( string $input, int &$offset ) { + return self::parse_class_selector( $input, $offset ); + } + + public static function test_parse_attribute_selector( string $input, int &$offset ) { + return self::parse_attribute_selector( $input, $offset ); + } + + public static function test_parse_compound_selector( string $input, int &$offset ) { + return self::parse_compound_selector( $input, $offset ); + } + + public static function test_parse_complex_selector( string $input, int &$offset ) { + return self::parse_complex_selector( $input, $offset ); + } + + /* + * Utilities + */ + public static function test_is_ident_codepoint( string $input, int $offset ) { + return self::is_ident_codepoint( $input, $offset ); + } + + public static function test_is_ident_start_codepoint( string $input, int $offset ) { + return self::is_ident_start_codepoint( $input, $offset ); + } + }; + } + /** * Data provider. * @@ -64,22 +121,10 @@ public static function data_idents(): array { * @ticket TBD */ public function test_is_ident_and_is_ident_start() { - $c = new class() extends WP_CSS_Selector_Parser { - public static function parse( string $input, int &$offset ) {} - - public static function test_is_ident( string $input, int $offset ) { - return self::is_ident_codepoint( $input, $offset ); - } - - public static function test_is_ident_start( string $input, int $offset ) { - return self::is_ident_start_codepoint( $input, $offset ); - } - }; - - $this->assertFalse( $c::test_is_ident( '[', 0 ) ); - $this->assertFalse( $c::test_is_ident( ']', 0 ) ); - $this->assertFalse( $c::test_is_ident_start( '[', 0 ) ); - $this->assertFalse( $c::test_is_ident_start( ']', 0 ) ); + $this->assertFalse( $this->test_class::test_is_ident_codepoint( '[', 0 ) ); + $this->assertFalse( $this->test_class::test_is_ident_codepoint( ']', 0 ) ); + $this->assertFalse( $this->test_class::test_is_ident_start_codepoint( '[', 0 ) ); + $this->assertFalse( $this->test_class::test_is_ident_start_codepoint( ']', 0 ) ); } /** @@ -88,15 +133,9 @@ public static function test_is_ident_start( string $input, int $offset ) { * @dataProvider data_idents */ public function test_parse_ident( string $input, ?string $expected = null, ?string $rest = null ) { - $c = new class() extends WP_CSS_Selector_Parser { - public static function parse( string $input, int &$offset ) {} - public static function test( string $input, &$offset ) { - return self::parse_ident( $input, $offset ); - } - }; $offset = 0; - $result = $c::test( $input, $offset ); + $result = $this->test_class::test_parse_ident( $input, $offset ); if ( null === $expected ) { $this->assertNull( $result ); } else { @@ -111,15 +150,8 @@ public static function test( string $input, &$offset ) { * @dataProvider data_strings */ public function test_parse_string( string $input, ?string $expected = null, ?string $rest = null ) { - $c = new class() extends WP_CSS_Selector_Parser { - public static function parse( string $input, int &$offset ) {} - public static function test( string $input, &$offset ) { - return self::parse_string( $input, $offset ); - } - }; - $offset = 0; - $result = $c::test( $input, $offset ); + $result = $this->test_class::test_parse_string( $input, $offset ); if ( null === $expected ) { $this->assertNull( $result ); } else { @@ -170,7 +202,7 @@ public static function data_strings(): array { */ public function test_parse_id( string $input, ?string $expected = null, ?string $rest = null ) { $offset = 0; - $result = WP_CSS_ID_Selector::parse( $input, $offset ); + $result = $this->test_class::test_parse_id_selector( $input, $offset ); if ( null === $expected ) { $this->assertNull( $result ); } else { @@ -204,7 +236,7 @@ public static function data_id_selectors(): array { */ public function test_parse_class( string $input, ?string $expected = null, ?string $rest = null ) { $offset = 0; - $result = WP_CSS_Class_Selector::parse( $input, $offset ); + $result = $this->test_class::test_parse_class_selector( $input, $offset ); if ( null === $expected ) { $this->assertNull( $result ); } else { @@ -238,7 +270,7 @@ public static function data_class_selectors(): array { */ public function test_parse_type( string $input, ?string $expected = null, ?string $rest = null ) { $offset = 0; - $result = WP_CSS_Type_Selector::parse( $input, $offset ); + $result = $this->test_class::test_parse_type_selector( $input, $offset ); if ( null === $expected ) { $this->assertNull( $result ); } else { @@ -281,7 +313,7 @@ public function test_parse_attribute( ?string $rest = null ) { $offset = 0; - $result = WP_CSS_Attribute_Selector::parse( $input, $offset ); + $result = $this->test_class::test_parse_attribute_selector( $input, $offset ); if ( null === $expected_name ) { $this->assertNull( $result ); } else { @@ -347,7 +379,7 @@ public static function data_attribute_selectors(): array { public function test_parse_selector() { $input = 'el.foo#bar[baz=quux] > .child'; $offset = 0; - $sel = WP_CSS_Selector::parse( $input, $offset ); + $sel = $this->test_class::test_parse_compound_selector( $input, $offset ); $this->assertSame( 'el', $sel->type_selector->ident ); $this->assertSame( 3, count( $sel->subclass_selectors ) ); @@ -365,8 +397,9 @@ public function test_parse_selector() { public function test_parse_empty_selector() { $input = ''; $offset = 0; - $result = WP_CSS_Selector::parse( $input, $offset ); + $result = $this->test_class::test_parse_compound_selector( $input, $offset ); $this->assertNull( $result ); + $this->assertSame( 0, $offset ); } /** @@ -375,7 +408,7 @@ public function test_parse_empty_selector() { public function test_parse_complex_selector() { $input = 'el1 > .child#bar[baz=quux] , rest'; $offset = 0; - $sel = WP_CSS_Complex_Selector::parse( $input, $offset ); + $sel = $this->test_class::test_parse_complex_selector( $input, $offset ); $this->assertSame( 3, count( $sel->selectors ) ); @@ -398,14 +431,14 @@ public function test_parse_complex_selector() { public function test_parse_invalid_complex_selector() { $input = 'el.foo#bar[baz=quux] > , rest'; $offset = 0; - $result = WP_CSS_Complex_Selector::parse( $input, $offset ); + $result = $this->test_class::test_parse_complex_selector( $input, $offset ); $this->assertNull( $result ); } public function test_parse_empty_complex_selector() { $input = ''; $offset = 0; - $result = WP_CSS_Complex_Selector::parse( $input, $offset ); + $result = $this->test_class::test_parse_complex_selector( $input, $offset ); $this->assertNull( $result ); } @@ -415,7 +448,7 @@ public function test_parse_empty_complex_selector() { */ public function test_parse_selector_list() { $input = 'el1 el2 el.foo#bar[baz=quux], rest'; - $result = WP_CSS_Selector_List::from_selectors( $input ); + $result = WP_CSS_Selector::from_selectors( $input ); $this->assertNotNull( $result ); } @@ -424,7 +457,7 @@ public function test_parse_selector_list() { */ public function test_parse_invalid_selector_list() { $input = 'el,,'; - $result = WP_CSS_Selector_List::from_selectors( $input ); + $result = WP_CSS_Selector::from_selectors( $input ); $this->assertNull( $result ); } @@ -433,7 +466,7 @@ public function test_parse_invalid_selector_list() { */ public function test_parse_invalid_selector_list2() { $input = 'el!'; - $result = WP_CSS_Selector_List::from_selectors( $input ); + $result = WP_CSS_Selector::from_selectors( $input ); $this->assertNull( $result ); } @@ -442,7 +475,7 @@ public function test_parse_invalid_selector_list2() { */ public function test_parse_empty_selector_list() { $input = " \t \t\n\r\f"; - $result = WP_CSS_Selector_List::from_selectors( $input ); + $result = WP_CSS_Selector::from_selectors( $input ); $this->assertNull( $result ); } } From 6a6969f435d659f9fc26c208faf4495c18c60278 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 3 Dec 2024 18:22:35 +0100 Subject: [PATCH 070/634] Rename files to align with class name --- .../{class-wp-css-selectors.php => class-wp-css-selector.php} | 0 src/wp-settings.php | 2 +- .../html-api/{wpCssSelectors.php => wpCssSelector-parsing.php} | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename src/wp-includes/html-api/{class-wp-css-selectors.php => class-wp-css-selector.php} (100%) rename tests/phpunit/tests/html-api/{wpCssSelectors.php => wpCssSelector-parsing.php} (99%) diff --git a/src/wp-includes/html-api/class-wp-css-selectors.php b/src/wp-includes/html-api/class-wp-css-selector.php similarity index 100% rename from src/wp-includes/html-api/class-wp-css-selectors.php rename to src/wp-includes/html-api/class-wp-css-selector.php diff --git a/src/wp-settings.php b/src/wp-settings.php index 6c799d5c95140..cfdd9234b7003 100644 --- a/src/wp-settings.php +++ b/src/wp-settings.php @@ -265,7 +265,7 @@ require ABSPATH . WPINC . '/html-api/class-wp-html-stack-event.php'; require ABSPATH . WPINC . '/html-api/class-wp-html-processor-state.php'; require ABSPATH . WPINC . '/html-api/class-wp-html-processor.php'; -require ABSPATH . WPINC . '/html-api/class-wp-css-selectors.php'; +require ABSPATH . WPINC . '/html-api/class-wp-css-selector.php'; require ABSPATH . WPINC . '/class-wp-http.php'; require ABSPATH . WPINC . '/class-wp-http-streams.php'; require ABSPATH . WPINC . '/class-wp-http-curl.php'; diff --git a/tests/phpunit/tests/html-api/wpCssSelectors.php b/tests/phpunit/tests/html-api/wpCssSelector-parsing.php similarity index 99% rename from tests/phpunit/tests/html-api/wpCssSelectors.php rename to tests/phpunit/tests/html-api/wpCssSelector-parsing.php index 19c1595253d84..4caa186158149 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectors.php +++ b/tests/phpunit/tests/html-api/wpCssSelector-parsing.php @@ -10,7 +10,7 @@ * * @group html-api */ -class Tests_HtmlApi_WpCssSelectors extends WP_UnitTestCase { +class Tests_HtmlApi_WpCssSelector_Parsing extends WP_UnitTestCase { private $test_class; public function set_up(): void { From 27ca891846d35f6d18f0b0031147ece99bd11d9e Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 3 Dec 2024 21:00:08 +0100 Subject: [PATCH 071/634] Add html processor select test suite --- .../tests/html-api/wpHtmlProcessor-select.php | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 tests/phpunit/tests/html-api/wpHtmlProcessor-select.php diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php new file mode 100644 index 0000000000000..e70dedcfcd3c4 --- /dev/null +++ b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php @@ -0,0 +1,68 @@ +' ); + $this->assertFalse( $processor->select( 'div' ) ); + } + + /** + * @ticket TBD + * + * @dataProvider data_selectors + */ + public function test_select( string $html, string $selector ) { + $processor = WP_HTML_Processor::create_full_parser( $html ); + $this->assertTrue( $processor->select( $selector ) ); + $this->assertTrue( $processor->get_attribute( 'match' ) ); + } + + /** + * Data provider. + * + * @return array + */ + public static function data_selectors(): array { + return array( + 'simple type' => array( '
', 'div' ), + 'any type' => array( '', '*' ), + 'simple class' => array( '
', '.x' ), + 'simple id' => array( '
', '#x' ), + 'simple attribute' => array( '
', '[att]' ), + 'attribute value' => array( '
', '[att=val]' ), + 'attribute quoted value' => array( '
', '[att="::"]' ), + 'complex any descendant' => array( '
', 'section *' ), + 'complex any child' => array( '
', 'section > *' ), + + 'list' => array( '

', 'a, p' ), + 'compound' => array( '

', 'section[att~="bar"]' ), + ); + } + + /** + * @ticket TBD + */ + public function test_select_all() { + $processor = WP_HTML_Processor::create_full_parser( '

' ); + $count = 0; + foreach ( $processor->select_all( 'div, .x, svg>rect, #y' ) as $_ ) { + ++$count; + $this->assertTrue( $processor->get_attribute( 'match' ) ); + } + $this->assertSame( 4, $count ); + } +} From 9ff276965a60f3a7ccd89facc67cc9d4b267d90e Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 3 Dec 2024 21:00:30 +0100 Subject: [PATCH 072/634] Fix select types --- src/wp-includes/html-api/class-wp-html-processor.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index bee0f63824abd..23ca6edc4ff7e 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -638,13 +638,15 @@ public function get_unsupported_exception() { /** * Use a selector to advance. * + * @todo _doing_it_wrong on null selector? + * * @param string $selectors - * @return Generator|null + * @return Generator */ public function select_all( string $selectors ): ?Generator { $select = WP_CSS_Selector::from_selectors( $selectors ); if ( null === $select ) { - return null; + return; } while ( $this->next_tag() ) { @@ -660,13 +662,10 @@ public function select_all( string $selectors ): ?Generator { * If iterating through matching elements, use `select_all` instead. * * @param string $selectors - * @return bool|null + * @return bool */ public function select( string $selectors ) { $selection = $this->select_all( $selectors ); - if ( null === $selection ) { - return null; - } foreach ( $selection as $_ ) { return true; } From d1a276b848ef8b9b5f954641ed762ad3d591b2cb Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 4 Dec 2024 13:55:57 +0100 Subject: [PATCH 073/634] Update class doc --- src/wp-includes/html-api/class-wp-css-selector.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selector.php b/src/wp-includes/html-api/class-wp-css-selector.php index 7588eb72294bd..c27c81593059d 100644 --- a/src/wp-includes/html-api/class-wp-css-selector.php +++ b/src/wp-includes/html-api/class-wp-css-selector.php @@ -23,8 +23,7 @@ * A subset of the CSS selector grammar is supported. The grammar is defined in the CSS Syntax * specification, which is available at {@link https://www.w3.org/TR/selectors/#grammar}. * - * @todo Review this grammar, especially the complex selector for accurate support information. - * The supported grammar is: + * This class is rougly analogous to the in the grammar. The supported grammar is: * * = * = # @@ -43,6 +42,7 @@ * * @link https://www.w3.org/TR/selectors/#grammar Refer to the grammar for more details. * + * Note that this grammar has been adapted and does not support the full CSS selector grammar. * Supported selector syntax: * - Type selectors (tag names, e.g. `div`) * - Class selectors (e.g. `.class-name`) @@ -61,11 +61,11 @@ * - Next sibling (`el + el`) * - Subsequent sibling (`el ~ el`) * - * Future ideas - * - Namespace type selectors could be implemented with select namespaces in order to - * select elements from a namespace, for example: - * - `svg|*` to select all SVG elements - * - `html|title` to select only HTML TITLE elements. + * Future ideas: + * - Namespace type selectors could be implemented with select namespaces in order to + * select elements from a namespace, for example: + * - `svg|*` to select all SVG elements + * - `html|title` to select only HTML TITLE elements. * * @since TBD * From 4909b569c067ab556e81b0cbcce087d3d1867676 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 4 Dec 2024 16:00:36 +0100 Subject: [PATCH 074/634] Improve select_ method arguments, docs, implementation --- .../html-api/class-wp-html-processor.php | 57 ++++++++++++++----- 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index 23ca6edc4ff7e..398c5c4fd096c 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -636,37 +636,64 @@ public function get_unsupported_exception() { } /** - * Use a selector to advance. + * Progress through a document pausing on tags matching the provided CSS selector string. + * + * @example + * + * $processor = WP_HTML_Processor::create_fragment( + * 'Example' + * ); + * foreach ( $processor->select_all( 'meta[property^="og:" i]' ) as $_ ) { + * // Loop is entered twice. + * var_dump( + * $processor->get_tag(), // string(4) "META" + * $processor->get_attribute( 'property' ), // string(7) "og:type" / string(14) "og:description" + * $processor->get_attribute( 'content' ), // string(7) "website" / string(11) "An example." + * ); + * } * - * @todo _doing_it_wrong on null selector? + * @since TBD * - * @param string $selectors - * @return Generator + * @param string $selector_string Selector string. + * @return Generator A generator pausing on each tag matching the selector. */ - public function select_all( string $selectors ): ?Generator { - $select = WP_CSS_Selector::from_selectors( $selectors ); - if ( null === $select ) { + public function select_all( string $selector_string ): ?Generator { + $selector = WP_CSS_Selector::from_selectors( $selector_string ); + if ( null === $selector ) { return; } while ( $this->next_tag() ) { - if ( $select->matches( $this ) ) { + if ( $selector->matches( $this ) ) { yield; } } } /** - * Select the next matching element. + * Move to the next tag matching the provided CSS selector string. * - * If iterating through matching elements, use `select_all` instead. + * This method will stop at the next match. To progress through all matches, use + * the `select_all` method. * - * @param string $selectors - * @return bool + * @example + * + * $processor = WP_HTML_Processor::create_fragment( + * 'Example' + * ); + * $processor->select( 'meta[charset]' ); + * var_dump( + * $processor->get_tag(), // string(4) "META" + * $processor->get_attribute( 'charset' ), // string(5) "utf-8" + * ); + * + * @since TBD + * + * @param string $selector_string + * @return bool True if a matching tag was found, otherwise false. */ - public function select( string $selectors ) { - $selection = $this->select_all( $selectors ); - foreach ( $selection as $_ ) { + public function select( string $selector_string ) { + foreach ( $this->select_all( $selector_string ) as $_ ) { return true; } return false; From 1d45225e46b85b2e8e9f8091cf9aefac3c46c2eb Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 4 Dec 2024 18:08:58 +0100 Subject: [PATCH 075/634] Split classes into their own files Satisfy the 1-class-per-file requirement --- .../class-wp-css-attribute-selector.php | 190 +++++++++ .../html-api/class-wp-css-class-selector.php | 14 + .../class-wp-css-complex-selector.php | 88 ++++ .../class-wp-css-compound-selector.php | 39 ++ .../html-api/class-wp-css-id-selector.php | 22 + .../html-api/class-wp-css-selector.php | 389 +----------------- .../html-api/class-wp-css-type-selector.php | 25 ++ ...nterface-wp-css-html-processor-matcher.php | 8 + src/wp-settings.php | 7 + 9 files changed, 396 insertions(+), 386 deletions(-) create mode 100644 src/wp-includes/html-api/class-wp-css-attribute-selector.php create mode 100644 src/wp-includes/html-api/class-wp-css-class-selector.php create mode 100644 src/wp-includes/html-api/class-wp-css-complex-selector.php create mode 100644 src/wp-includes/html-api/class-wp-css-compound-selector.php create mode 100644 src/wp-includes/html-api/class-wp-css-id-selector.php create mode 100644 src/wp-includes/html-api/class-wp-css-type-selector.php create mode 100644 src/wp-includes/html-api/interface-wp-css-html-processor-matcher.php diff --git a/src/wp-includes/html-api/class-wp-css-attribute-selector.php b/src/wp-includes/html-api/class-wp-css-attribute-selector.php new file mode 100644 index 0000000000000..be7332c85b72d --- /dev/null +++ b/src/wp-includes/html-api/class-wp-css-attribute-selector.php @@ -0,0 +1,190 @@ +get_attribute( $this->name ); + if ( null === $att_value ) { + return false; + } + + if ( null === $this->value ) { + return true; + } + + if ( true === $att_value ) { + $att_value = ''; + } + + $case_insensitive = self::MODIFIER_CASE_INSENSITIVE === $this->modifier; + + switch ( $this->matcher ) { + case self::MATCH_EXACT: + return $case_insensitive + ? 0 === strcasecmp( $att_value, $this->value ) + : $att_value === $this->value; + + case self::MATCH_ONE_OF_EXACT: + foreach ( $this->whitespace_delimited_list( $att_value ) as $val ) { + if ( + $case_insensitive + ? 0 === strcasecmp( $val, $this->value ) + : $val === $this->value + ) { + return true; + } + } + return false; + + case self::MATCH_EXACT_OR_EXACT_WITH_HYPHEN: + // Attempt the full match first + if ( + $case_insensitive + ? 0 === strcasecmp( $att_value, $this->value ) + : $att_value === $this->value + ) { + return true; + } + + // Partial match + if ( strlen( $att_value ) < strlen( $this->value ) + 1 ) { + return false; + } + + $starts_with = "{$this->value}-"; + return 0 === substr_compare( $att_value, $starts_with, 0, strlen( $starts_with ), $case_insensitive ); + + case self::MATCH_PREFIXED_BY: + return 0 === substr_compare( $att_value, $this->value, 0, strlen( $this->value ), $case_insensitive ); + + case self::MATCH_SUFFIXED_BY: + return 0 === substr_compare( $att_value, $this->value, -strlen( $this->value ), null, $case_insensitive ); + + case self::MATCH_CONTAINS: + return false !== ( + $case_insensitive + ? stripos( $att_value, $this->value ) + : strpos( $att_value, $this->value ) + ); + } + + throw new Exception( 'Unreachable' ); + } + + /** + * @param string $input + * + * @return Generator + */ + private function whitespace_delimited_list( string $input ): Generator { + $offset = strspn( $input, WP_CSS_Selector::WHITESPACE_CHARACTERS ); + + while ( $offset < strlen( $input ) ) { + // Find the byte length until the next boundary. + $length = strcspn( $input, WP_CSS_Selector::WHITESPACE_CHARACTERS, $offset ); + if ( 0 === $length ) { + return; + } + + $value = substr( $input, $offset, $length ); + $offset += $length + strspn( $input, WP_CSS_Selector::WHITESPACE_CHARACTERS, $offset + $length ); + + yield $value; + } + } + + /** + * [att=val] + * Represents an element with the att attribute whose value is exactly "val". + */ + const MATCH_EXACT = 'MATCH_EXACT'; + + /** + * [attr~=value] + * Represents elements with an attribute name of attr whose value is a + * whitespace-separated list of words, one of which is exactly value. + */ + const MATCH_ONE_OF_EXACT = 'MATCH_ONE_OF_EXACT'; + + /** + * [attr|=value] + * Represents elements with an attribute name of attr whose value can be exactly value or + * can begin with value immediately followed by a hyphen, - (U+002D). It is often used for + * language subcode matches. + */ + const MATCH_EXACT_OR_EXACT_WITH_HYPHEN = 'MATCH_EXACT_OR_EXACT_WITH_HYPHEN'; + + /** + * [attr^=value] + * Represents elements with an attribute name of attr whose value is prefixed (preceded) + * by value. + */ + const MATCH_PREFIXED_BY = 'MATCH_PREFIXED_BY'; + + /** + * [attr$=value] + * Represents elements with an attribute name of attr whose value is suffixed (followed) + * by value. + */ + const MATCH_SUFFIXED_BY = 'MATCH_SUFFIXED_BY'; + + /** + * [attr*=value] + * Represents elements with an attribute name of attr whose value contains at least one + * occurrence of value within the string. + */ + const MATCH_CONTAINS = 'MATCH_CONTAINS'; + + /** + * Modifier for case sensitive matching + * [attr=value s] + */ + const MODIFIER_CASE_SENSITIVE = 'case-sensitive'; + + /** + * Modifier for case insensitive matching + * [attr=value i] + */ + const MODIFIER_CASE_INSENSITIVE = 'case-insensitive'; + + + /** + * The attribute name. + * + * @var string + */ + public $name; + + /** + * The attribute matcher. + * + * @var null|self::MATCH_* + */ + public $matcher; + + /** + * The attribute value. + * + * @var string|null + */ + public $value; + + /** + * The attribute modifier. + * + * @var null|self::MODIFIER_* + */ + public $modifier; + + /** + * @param string $name + * @param null|self::MATCH_* $matcher + * @param null|string $value + * @param null|self::MODIFIER_* $modifier + */ + public function __construct( string $name, ?string $matcher = null, ?string $value = null, ?string $modifier = null ) { + $this->name = $name; + $this->matcher = $matcher; + $this->value = $value; + $this->modifier = $modifier; + } +} diff --git a/src/wp-includes/html-api/class-wp-css-class-selector.php b/src/wp-includes/html-api/class-wp-css-class-selector.php new file mode 100644 index 0000000000000..c4f858d4a05d9 --- /dev/null +++ b/src/wp-includes/html-api/class-wp-css-class-selector.php @@ -0,0 +1,14 @@ +has_class( $this->ident ); + } + + /** @var string */ + public $ident; + + public function __construct( string $ident ) { + $this->ident = $ident; + } +} diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector.php b/src/wp-includes/html-api/class-wp-css-complex-selector.php new file mode 100644 index 0000000000000..520f3bf3d8fde --- /dev/null +++ b/src/wp-includes/html-api/class-wp-css-complex-selector.php @@ -0,0 +1,88 @@ + in the grammar. + * + * > = [ ? ] * + */ +final class WP_CSS_Complex_Selector implements WP_CSS_HTML_Processor_Matcher { + public function matches( WP_HTML_Processor $processor ): bool { + // First selector must match this location. + if ( ! $this->selectors[0]->matches( $processor ) ) { + return false; + } + + if ( count( $this->selectors ) === 1 ) { + return true; + } + + /** @var array $breadcrumbs */ + $breadcrumbs = array_slice( array_reverse( $processor->get_breadcrumbs() ), 1 ); + $selectors = array_slice( $this->selectors, 1 ); + return $this->explore_matches( $selectors, $breadcrumbs ); + } + + /** + * This only looks at breadcrumbs and can therefore only support type selectors. + * + * @param array $selectors + * @param array $breadcrumbs + */ + private function explore_matches( array $selectors, array $breadcrumbs ): bool { + if ( array() === $selectors ) { + return true; + } + if ( array() === $breadcrumbs ) { + return false; + } + + /** @var self::COMBINATOR_* $combinator */ + $combinator = $selectors[0]; + /** @var WP_CSS_Compound_Selector $selector */ + $selector = $selectors[1]; + + switch ( $combinator ) { + case self::COMBINATOR_CHILD: + if ( '*' === $selector->type_selector->ident || strcasecmp( $breadcrumbs[0], $selector->type_selector->ident ) === 0 ) { + return $this->explore_matches( array_slice( $selectors, 2 ), array_slice( $breadcrumbs, 1 ) ); + } + return $this->explore_matches( $selectors, array_slice( $breadcrumbs, 1 ) ); + + case self::COMBINATOR_DESCENDANT: + // Find _all_ the breadcrumbs that match and recurse from each of them. + for ( $i = 0; $i < count( $breadcrumbs ); $i++ ) { + if ( '*' === $selector->type_selector->ident || strcasecmp( $breadcrumbs[ $i ], $selector->type_selector->ident ) === 0 ) { + $next_crumbs = array_slice( $breadcrumbs, $i + 1 ); + if ( $this->explore_matches( array_slice( $selectors, 2 ), $next_crumbs ) ) { + return true; + } + } + } + return false; + + default: + throw new Exception( "Combinator '{$combinator}' is not supported yet." ); + } + } + + const COMBINATOR_CHILD = '>'; + const COMBINATOR_DESCENDANT = ' '; + const COMBINATOR_NEXT_SIBLING = '+'; + const COMBINATOR_SUBSEQUENT_SIBLING = '~'; + + /** + * even indexes are WP_CSS_Compound_Selector, odd indexes are string combinators. + * In reverse order to match the current element and then work up the tree. + * Any non-final selector is a type selector. + * + * @var array + */ + public $selectors = array(); + + /** + * @param array $selectors + */ + public function __construct( array $selectors ) { + $this->selectors = array_reverse( $selectors ); + } +} diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector.php b/src/wp-includes/html-api/class-wp-css-compound-selector.php new file mode 100644 index 0000000000000..1162aaef78c1e --- /dev/null +++ b/src/wp-includes/html-api/class-wp-css-compound-selector.php @@ -0,0 +1,39 @@ + in the grammar. + * + * > = [ ? * ]! + */ +final class WP_CSS_Compound_Selector implements WP_CSS_HTML_Processor_Matcher { + public function matches( WP_HTML_Processor $processor ): bool { + if ( $this->type_selector ) { + if ( ! $this->type_selector->matches( $processor ) ) { + return false; + } + } + if ( null !== $this->subclass_selectors ) { + foreach ( $this->subclass_selectors as $subclass_selector ) { + if ( ! $subclass_selector->matches( $processor ) ) { + return false; + } + } + } + return true; + } + + /** @var WP_CSS_Type_Selector|null */ + public $type_selector; + + /** @var array|null */ + public $subclass_selectors; + + /** + * @param WP_CSS_Type_Selector|null $type_selector + * @param array $subclass_selectors + */ + public function __construct( ?WP_CSS_Type_Selector $type_selector, array $subclass_selectors ) { + $this->type_selector = $type_selector; + $this->subclass_selectors = array() === $subclass_selectors ? null : $subclass_selectors; + } +} diff --git a/src/wp-includes/html-api/class-wp-css-id-selector.php b/src/wp-includes/html-api/class-wp-css-id-selector.php new file mode 100644 index 0000000000000..cc0589327c829 --- /dev/null +++ b/src/wp-includes/html-api/class-wp-css-id-selector.php @@ -0,0 +1,22 @@ +ident = $ident; + } + + public function matches( WP_HTML_Processor $processor ): bool { + $id = $processor->get_attribute( 'id' ); + if ( ! is_string( $id ) ) { + return false; + } + + $case_insensitive = method_exists( $processor, 'is_quirks_mode' ) && $processor->is_quirks_mode(); + return $case_insensitive + ? 0 === strcasecmp( $id, $this->ident ) + : $processor->get_attribute( 'id' ) === $this->ident; + } +} diff --git a/src/wp-includes/html-api/class-wp-css-selector.php b/src/wp-includes/html-api/class-wp-css-selector.php index c27c81593059d..b776bad66146b 100644 --- a/src/wp-includes/html-api/class-wp-css-selector.php +++ b/src/wp-includes/html-api/class-wp-css-selector.php @@ -1,10 +1,6 @@ -get_token_type() !== '#tag' ) { return false; @@ -906,382 +902,3 @@ private static function check_if_three_code_points_would_start_an_ident_sequence return self::is_ident_start_codepoint( $input, $offset ); } } - -interface IWP_CSS_Selector_Matcher { - /** - * @return bool - */ - public function matches( WP_HTML_Processor $processor ): bool; -} - -final class WP_CSS_ID_Selector implements IWP_CSS_Selector_Matcher { - /** @var string */ - public $ident; - - public function __construct( string $ident ) { - $this->ident = $ident; - } - - public function matches( WP_HTML_Processor $processor ): bool { - $id = $processor->get_attribute( 'id' ); - if ( ! is_string( $id ) ) { - return false; - } - - $case_insensitive = method_exists( $processor, 'is_quirks_mode' ) && $processor->is_quirks_mode(); - return $case_insensitive - ? 0 === strcasecmp( $id, $this->ident ) - : $processor->get_attribute( 'id' ) === $this->ident; - } -} - -final class WP_CSS_Class_Selector implements IWP_CSS_Selector_Matcher { - public function matches( WP_HTML_Processor $processor ): bool { - return (bool) $processor->has_class( $this->ident ); - } - - /** @var string */ - public $ident; - - public function __construct( string $ident ) { - $this->ident = $ident; - } -} - -final class WP_CSS_Type_Selector implements IWP_CSS_Selector_Matcher { - public function matches( WP_HTML_Processor $processor ): bool { - $tag_name = $processor->get_tag(); - if ( null === $tag_name ) { - return false; - } - if ( '*' === $this->ident ) { - return true; - } - return 0 === strcasecmp( $tag_name, $this->ident ); - } - - /** - * @var string - * - * The type identifier string or '*'. - */ - public $ident; - - public function __construct( string $ident ) { - $this->ident = $ident; - } -} - -final class WP_CSS_Attribute_Selector implements IWP_CSS_Selector_Matcher { - public function matches( WP_HTML_Processor $processor ): bool { - $att_value = $processor->get_attribute( $this->name ); - if ( null === $att_value ) { - return false; - } - - if ( null === $this->value ) { - return true; - } - - if ( true === $att_value ) { - $att_value = ''; - } - - $case_insensitive = self::MODIFIER_CASE_INSENSITIVE === $this->modifier; - - switch ( $this->matcher ) { - case self::MATCH_EXACT: - return $case_insensitive - ? 0 === strcasecmp( $att_value, $this->value ) - : $att_value === $this->value; - - case self::MATCH_ONE_OF_EXACT: - foreach ( $this->whitespace_delimited_list( $att_value ) as $val ) { - if ( - $case_insensitive - ? 0 === strcasecmp( $val, $this->value ) - : $val === $this->value - ) { - return true; - } - } - return false; - - case self::MATCH_EXACT_OR_EXACT_WITH_HYPHEN: - // Attempt the full match first - if ( - $case_insensitive - ? 0 === strcasecmp( $att_value, $this->value ) - : $att_value === $this->value - ) { - return true; - } - - // Partial match - if ( strlen( $att_value ) < strlen( $this->value ) + 1 ) { - return false; - } - - $starts_with = "{$this->value}-"; - return 0 === substr_compare( $att_value, $starts_with, 0, strlen( $starts_with ), $case_insensitive ); - - case self::MATCH_PREFIXED_BY: - return 0 === substr_compare( $att_value, $this->value, 0, strlen( $this->value ), $case_insensitive ); - - case self::MATCH_SUFFIXED_BY: - return 0 === substr_compare( $att_value, $this->value, -strlen( $this->value ), null, $case_insensitive ); - - case self::MATCH_CONTAINS: - return false !== ( - $case_insensitive - ? stripos( $att_value, $this->value ) - : strpos( $att_value, $this->value ) - ); - } - - throw new Exception( 'Unreachable' ); - } - - /** - * @param string $input - * - * @return Generator - */ - private function whitespace_delimited_list( string $input ): Generator { - $offset = strspn( $input, WP_CSS_Selector::WHITESPACE_CHARACTERS ); - - while ( $offset < strlen( $input ) ) { - // Find the byte length until the next boundary. - $length = strcspn( $input, WP_CSS_Selector::WHITESPACE_CHARACTERS, $offset ); - if ( 0 === $length ) { - return; - } - - $value = substr( $input, $offset, $length ); - $offset += $length + strspn( $input, WP_CSS_Selector::WHITESPACE_CHARACTERS, $offset + $length ); - - yield $value; - } - } - - /** - * [att=val] - * Represents an element with the att attribute whose value is exactly "val". - */ - const MATCH_EXACT = 'MATCH_EXACT'; - - /** - * [attr~=value] - * Represents elements with an attribute name of attr whose value is a - * whitespace-separated list of words, one of which is exactly value. - */ - const MATCH_ONE_OF_EXACT = 'MATCH_ONE_OF_EXACT'; - - /** - * [attr|=value] - * Represents elements with an attribute name of attr whose value can be exactly value or - * can begin with value immediately followed by a hyphen, - (U+002D). It is often used for - * language subcode matches. - */ - const MATCH_EXACT_OR_EXACT_WITH_HYPHEN = 'MATCH_EXACT_OR_EXACT_WITH_HYPHEN'; - - /** - * [attr^=value] - * Represents elements with an attribute name of attr whose value is prefixed (preceded) - * by value. - */ - const MATCH_PREFIXED_BY = 'MATCH_PREFIXED_BY'; - - /** - * [attr$=value] - * Represents elements with an attribute name of attr whose value is suffixed (followed) - * by value. - */ - const MATCH_SUFFIXED_BY = 'MATCH_SUFFIXED_BY'; - - /** - * [attr*=value] - * Represents elements with an attribute name of attr whose value contains at least one - * occurrence of value within the string. - */ - const MATCH_CONTAINS = 'MATCH_CONTAINS'; - - /** - * Modifier for case sensitive matching - * [attr=value s] - */ - const MODIFIER_CASE_SENSITIVE = 'case-sensitive'; - - /** - * Modifier for case insensitive matching - * [attr=value i] - */ - const MODIFIER_CASE_INSENSITIVE = 'case-insensitive'; - - - /** - * The attribute name. - * - * @var string - */ - public $name; - - /** - * The attribute matcher. - * - * @var null|self::MATCH_* - */ - public $matcher; - - /** - * The attribute value. - * - * @var string|null - */ - public $value; - - /** - * The attribute modifier. - * - * @var null|self::MODIFIER_* - */ - public $modifier; - - /** - * @param string $name - * @param null|self::MATCH_* $matcher - * @param null|string $value - * @param null|self::MODIFIER_* $modifier - */ - public function __construct( string $name, ?string $matcher = null, ?string $value = null, ?string $modifier = null ) { - $this->name = $name; - $this->matcher = $matcher; - $this->value = $value; - $this->modifier = $modifier; - } -} - -/** - * This corresponds to in the grammar. - * - * > = [ ? * ]! - */ -final class WP_CSS_Compound_Selector implements IWP_CSS_Selector_Matcher { - public function matches( WP_HTML_Processor $processor ): bool { - if ( $this->type_selector ) { - if ( ! $this->type_selector->matches( $processor ) ) { - return false; - } - } - if ( null !== $this->subclass_selectors ) { - foreach ( $this->subclass_selectors as $subclass_selector ) { - if ( ! $subclass_selector->matches( $processor ) ) { - return false; - } - } - } - return true; - } - - /** @var WP_CSS_Type_Selector|null */ - public $type_selector; - - /** @var array|null */ - public $subclass_selectors; - - /** - * @param WP_CSS_Type_Selector|null $type_selector - * @param array $subclass_selectors - */ - public function __construct( ?WP_CSS_Type_Selector $type_selector, array $subclass_selectors ) { - $this->type_selector = $type_selector; - $this->subclass_selectors = array() === $subclass_selectors ? null : $subclass_selectors; - } -} - -/** - * This corresponds to in the grammar. - * - * > = [ ? ] * - */ -final class WP_CSS_Complex_Selector implements IWP_CSS_Selector_Matcher { - public function matches( WP_HTML_Processor $processor ): bool { - // First selector must match this location. - if ( ! $this->selectors[0]->matches( $processor ) ) { - return false; - } - - if ( count( $this->selectors ) === 1 ) { - return true; - } - - /** @var array $breadcrumbs */ - $breadcrumbs = array_slice( array_reverse( $processor->get_breadcrumbs() ), 1 ); - $selectors = array_slice( $this->selectors, 1 ); - return $this->explore_matches( $selectors, $breadcrumbs ); - } - - /** - * This only looks at breadcrumbs and can therefore only support type selectors. - * - * @param array $selectors - * @param array $breadcrumbs - */ - private function explore_matches( array $selectors, array $breadcrumbs ): bool { - if ( array() === $selectors ) { - return true; - } - if ( array() === $breadcrumbs ) { - return false; - } - - /** @var self::COMBINATOR_* $combinator */ - $combinator = $selectors[0]; - /** @var WP_CSS_Compound_Selector $selector */ - $selector = $selectors[1]; - - switch ( $combinator ) { - case self::COMBINATOR_CHILD: - if ( '*' === $selector->type_selector->ident || strcasecmp( $breadcrumbs[0], $selector->type_selector->ident ) === 0 ) { - return $this->explore_matches( array_slice( $selectors, 2 ), array_slice( $breadcrumbs, 1 ) ); - } - return $this->explore_matches( $selectors, array_slice( $breadcrumbs, 1 ) ); - - case self::COMBINATOR_DESCENDANT: - // Find _all_ the breadcrumbs that match and recurse from each of them. - for ( $i = 0; $i < count( $breadcrumbs ); $i++ ) { - if ( '*' === $selector->type_selector->ident || strcasecmp( $breadcrumbs[ $i ], $selector->type_selector->ident ) === 0 ) { - $next_crumbs = array_slice( $breadcrumbs, $i + 1 ); - if ( $this->explore_matches( array_slice( $selectors, 2 ), $next_crumbs ) ) { - return true; - } - } - } - return false; - - default: - throw new Exception( "Combinator '{$combinator}' is not supported yet." ); - } - } - - const COMBINATOR_CHILD = '>'; - const COMBINATOR_DESCENDANT = ' '; - const COMBINATOR_NEXT_SIBLING = '+'; - const COMBINATOR_SUBSEQUENT_SIBLING = '~'; - - /** - * even indexes are WP_CSS_Compound_Selector, odd indexes are string combinators. - * In reverse order to match the current element and then work up the tree. - * Any non-final selector is a type selector. - * - * @var array - */ - public $selectors = array(); - - /** - * @param array $selectors - */ - public function __construct( array $selectors ) { - $this->selectors = array_reverse( $selectors ); - } -} diff --git a/src/wp-includes/html-api/class-wp-css-type-selector.php b/src/wp-includes/html-api/class-wp-css-type-selector.php new file mode 100644 index 0000000000000..a2dcd16521cb5 --- /dev/null +++ b/src/wp-includes/html-api/class-wp-css-type-selector.php @@ -0,0 +1,25 @@ +get_tag(); + if ( null === $tag_name ) { + return false; + } + if ( '*' === $this->ident ) { + return true; + } + return 0 === strcasecmp( $tag_name, $this->ident ); + } + + /** + * @var string + * + * The type identifier string or '*'. + */ + public $ident; + + public function __construct( string $ident ) { + $this->ident = $ident; + } +} diff --git a/src/wp-includes/html-api/interface-wp-css-html-processor-matcher.php b/src/wp-includes/html-api/interface-wp-css-html-processor-matcher.php new file mode 100644 index 0000000000000..2ae29413b35d2 --- /dev/null +++ b/src/wp-includes/html-api/interface-wp-css-html-processor-matcher.php @@ -0,0 +1,8 @@ + Date: Wed, 4 Dec 2024 18:09:17 +0100 Subject: [PATCH 076/634] Remove redundant see phpdoc annotations --- src/wp-includes/html-api/class-wp-css-selector.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selector.php b/src/wp-includes/html-api/class-wp-css-selector.php index b776bad66146b..487c100ab47e4 100644 --- a/src/wp-includes/html-api/class-wp-css-selector.php +++ b/src/wp-includes/html-api/class-wp-css-selector.php @@ -67,11 +67,10 @@ * * @access private * - * @see {@link https://www.w3.org/TR/css-syntax-3/} - * @see {@link https://www.w3.org/tr/selectors/} - * @see {@link https://www.w3.org/TR/selectors-api2/} - * @see {@link https://www.w3.org/TR/selectors-4/} - * + * @link https://www.w3.org/TR/css-syntax-3/ + * @link https://www.w3.org/tr/selectors/ + * @link https://www.w3.org/TR/selectors-api2/ + * @link https://www.w3.org/TR/selectors-4/ */ class WP_CSS_Selector implements WP_CSS_HTML_Processor_Matcher { public function matches( WP_HTML_Processor $processor ): bool { From 0c53c422de2f40206b9322f8f0ae3beaf85b5e4b Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 4 Dec 2024 18:28:54 +0100 Subject: [PATCH 077/634] Fix docs and return type on select_all --- src/wp-includes/html-api/class-wp-html-processor.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index 398c5c4fd096c..9f7a43acaebbd 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -657,7 +657,7 @@ public function get_unsupported_exception() { * @param string $selector_string Selector string. * @return Generator A generator pausing on each tag matching the selector. */ - public function select_all( string $selector_string ): ?Generator { + public function select_all( string $selector_string ): Generator { $selector = WP_CSS_Selector::from_selectors( $selector_string ); if ( null === $selector ) { return; @@ -674,7 +674,7 @@ public function select_all( string $selector_string ): ?Generator { * Move to the next tag matching the provided CSS selector string. * * This method will stop at the next match. To progress through all matches, use - * the `select_all` method. + * the {@see WP_HTML_Processor::select_all()} method. * * @example * From d966e9ad7fdc9270fded62abb9e32923ced79d61 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 4 Dec 2024 18:31:05 +0100 Subject: [PATCH 078/634] Improve html select test docs --- tests/phpunit/tests/html-api/wpHtmlProcessor-select.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php index e70dedcfcd3c4..c3a1e4121ecab 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php @@ -1,6 +1,9 @@ Date: Wed, 4 Dec 2024 19:40:23 +0100 Subject: [PATCH 079/634] Add select support to tag processor Split up main CSS selector class and support more restricted selectors in the tag processor. --- .../class-wp-css-attribute-selector.php | 12 +- .../html-api/class-wp-css-class-selector.php | 4 +- .../class-wp-css-complex-selector-list.php | 165 ++++++++++++++++++ ...> class-wp-css-compound-selector-list.php} | 126 ++++--------- .../class-wp-css-compound-selector.php | 4 +- .../html-api/class-wp-css-id-selector.php | 7 +- .../html-api/class-wp-css-type-selector.php | 4 +- .../html-api/class-wp-html-processor.php | 11 +- .../html-api/class-wp-html-tag-processor.php | 69 ++++++++ ...face-wp-css-html-tag-processor-matcher.php | 8 + src/wp-settings.php | 4 +- .../html-api/wpCssComplexSelectorList.php | 107 ++++++++++++ ...sing.php => wpCssCompoundSelectorList.php} | 59 +------ .../tests/html-api/wpHtmlProcessor-select.php | 10 ++ .../html-api/wpHtmlTagProcessor-select.php | 92 ++++++++++ 15 files changed, 520 insertions(+), 162 deletions(-) create mode 100644 src/wp-includes/html-api/class-wp-css-complex-selector-list.php rename src/wp-includes/html-api/{class-wp-css-selector.php => class-wp-css-compound-selector-list.php} (87%) create mode 100644 src/wp-includes/html-api/interface-wp-css-html-tag-processor-matcher.php create mode 100644 tests/phpunit/tests/html-api/wpCssComplexSelectorList.php rename tests/phpunit/tests/html-api/{wpCssSelector-parsing.php => wpCssCompoundSelectorList.php} (89%) create mode 100644 tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php diff --git a/src/wp-includes/html-api/class-wp-css-attribute-selector.php b/src/wp-includes/html-api/class-wp-css-attribute-selector.php index be7332c85b72d..76ccdf3804b36 100644 --- a/src/wp-includes/html-api/class-wp-css-attribute-selector.php +++ b/src/wp-includes/html-api/class-wp-css-attribute-selector.php @@ -1,7 +1,9 @@ get_attribute( $this->name ); if ( null === $att_value ) { return false; @@ -76,17 +78,17 @@ public function matches( WP_HTML_Processor $processor ): bool { * @return Generator */ private function whitespace_delimited_list( string $input ): Generator { - $offset = strspn( $input, WP_CSS_Selector::WHITESPACE_CHARACTERS ); + $offset = strspn( $input, self::WHITESPACE_CHARACTERS ); while ( $offset < strlen( $input ) ) { // Find the byte length until the next boundary. - $length = strcspn( $input, WP_CSS_Selector::WHITESPACE_CHARACTERS, $offset ); + $length = strcspn( $input, self::WHITESPACE_CHARACTERS, $offset ); if ( 0 === $length ) { return; } $value = substr( $input, $offset, $length ); - $offset += $length + strspn( $input, WP_CSS_Selector::WHITESPACE_CHARACTERS, $offset + $length ); + $offset += $length + strspn( $input, self::WHITESPACE_CHARACTERS, $offset + $length ); yield $value; } diff --git a/src/wp-includes/html-api/class-wp-css-class-selector.php b/src/wp-includes/html-api/class-wp-css-class-selector.php index c4f858d4a05d9..c3e7ced008a6e 100644 --- a/src/wp-includes/html-api/class-wp-css-class-selector.php +++ b/src/wp-includes/html-api/class-wp-css-class-selector.php @@ -1,7 +1,7 @@ has_class( $this->ident ); } diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php new file mode 100644 index 0000000000000..f3769a035f6e5 --- /dev/null +++ b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php @@ -0,0 +1,165 @@ + in the grammar. See {@see WP_CSS_Compound_Selector_List} for more details on the grammar. + * + * This class supports the same selector syntax as {@see WP_CSS_Compound_Selector_List} as well as: + * - The following combinators: + * - Next sibling (`el + el`) + * - Subsequent sibling (`el ~ el`) + * + * @since TBD + * + * @access private + */ +class WP_CSS_Complex_Selector_List extends WP_CSS_Compound_Selector_List implements WP_CSS_HTML_Processor_Matcher { + /** + * Takes a CSS selector string and returns an instance of itself or `null` if the selector + * string is invalid or unsupported. + * + * @since TBD + * + * @param string $input CSS selectors. + * @return static|null + */ + public static function from_selectors( string $input ) { + // > A selector string is a list of one or more complex selectors ([SELECTORS4], section 3.1) that may be surrounded by whitespace… + $input = trim( $input, " \t\r\n\r" ); + + if ( '' === $input ) { + return null; + } + + /* + * > The input stream consists of the filtered code points pushed into it as the input byte stream is decoded. + * > + * > To filter code points from a stream of (unfiltered) code points input: + * > Replace any U+000D CARRIAGE RETURN (CR) code points, U+000C FORM FEED (FF) code points, or pairs of U+000D CARRIAGE RETURN (CR) followed by U+000A LINE FEED (LF) in input by a single U+000A LINE FEED (LF) code point. + * > Replace any U+0000 NULL or surrogate code points in input with U+FFFD REPLACEMENT CHARACTER (�). + * + * https://www.w3.org/TR/css-syntax-3/#input-preprocessing + */ + $input = str_replace( array( "\r\n" ), "\n", $input ); + $input = str_replace( array( "\r", "\f" ), "\n", $input ); + $input = str_replace( "\0", "\u{FFFD}", $input ); + + $offset = 0; + + $selector = self::parse_complex_selector( $input, $offset ); + if ( null === $selector ) { + return null; + } + self::parse_whitespace( $input, $offset ); + + $selectors = array( $selector ); + while ( $offset < strlen( $input ) ) { + // Each loop should stop on a `,` selector list delimiter. + if ( ',' !== $input[ $offset ] ) { + return null; + } + ++$offset; + self::parse_whitespace( $input, $offset ); + $selector = self::parse_complex_selector( $input, $offset ); + if ( null === $selector ) { + return null; + } + $selectors[] = $selector; + self::parse_whitespace( $input, $offset ); + } + + return new self( $selectors ); + } + + /* + * ------------------------------ + * Selector parsing functionality + * ------------------------------ + */ + + /** + * Parses a complex selector. + * + * > = [ ? ]* + * + * @return WP_CSS_Complex_Selector|null + */ + final protected static function parse_complex_selector( string $input, int &$offset ): ?WP_CSS_Complex_Selector { + if ( $offset >= strlen( $input ) ) { + return null; + } + + $updated_offset = $offset; + $selector = self::parse_compound_selector( $input, $updated_offset ); + if ( null === $selector ) { + return null; + } + + $selectors = array( $selector ); + $has_preceding_subclass_selector = null !== $selector->subclass_selectors; + + $found_whitespace = self::parse_whitespace( $input, $updated_offset ); + while ( $updated_offset < strlen( $input ) ) { + if ( + WP_CSS_Complex_Selector::COMBINATOR_CHILD === $input[ $updated_offset ] || + WP_CSS_Complex_Selector::COMBINATOR_NEXT_SIBLING === $input[ $updated_offset ] || + WP_CSS_Complex_Selector::COMBINATOR_SUBSEQUENT_SIBLING === $input[ $updated_offset ] + ) { + $combinator = $input[ $updated_offset ]; + ++$updated_offset; + self::parse_whitespace( $input, $updated_offset ); + + // Failure to find a selector here is a parse error + $selector = self::parse_compound_selector( $input, $updated_offset ); + } elseif ( $found_whitespace ) { + /* + * Whitespace is ambiguous, it could be a descendant combinator or + * insignificant whitespace. + */ + $selector = self::parse_compound_selector( $input, $updated_offset ); + if ( null === $selector ) { + break; + } + $combinator = WP_CSS_Complex_Selector::COMBINATOR_DESCENDANT; + } else { + break; + } + + if ( null === $selector ) { + return null; + } + + // `div > .className` is valid, but `.className > div` is not. + if ( $has_preceding_subclass_selector ) { + throw new Exception( 'Unsupported non-final subclass selector.' ); + } + $has_preceding_subclass_selector = null !== $selector->subclass_selectors; + + $selectors[] = $combinator; + $selectors[] = $selector; + + $found_whitespace = self::parse_whitespace( $input, $updated_offset ); + } + $offset = $updated_offset; + return new WP_CSS_Complex_Selector( $selectors ); + } +} diff --git a/src/wp-includes/html-api/class-wp-css-selector.php b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php similarity index 87% rename from src/wp-includes/html-api/class-wp-css-selector.php rename to src/wp-includes/html-api/class-wp-css-compound-selector-list.php index 487c100ab47e4..2aae51d671f6b 100644 --- a/src/wp-includes/html-api/class-wp-css-selector.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php @@ -1,6 +1,6 @@ in the grammar. The supported grammar is: + * This class is analogous to in the grammar. The supported grammar is: * * = * = # @@ -38,6 +40,10 @@ * * @link https://www.w3.org/TR/selectors/#grammar Refer to the grammar for more details. * + * This class of selectors does not support "complex" selectors. That is any selector with a + * combinator such as descendent (`.ancestor .descendant`) or child (`.parent > .child`). + * See {@see WP_CSS_Complex_Selector_List} for support of some combinators. + * * Note that this grammar has been adapted and does not support the full CSS selector grammar. * Supported selector syntax: * - Type selectors (tag names, e.g. `div`) @@ -50,12 +56,10 @@ * - child (`el > .child`) * * Unsupported selector syntax: - * - Pseudo-element selectors (e.g. `::before`) - * - Pseudo-class selectors (e.g. `:hover` or `:nth-child(2)`) - * - Namespace prefixes (e.g. `svg|title` or `[xlink|href]`) - * - The following combinators: - * - Next sibling (`el + el`) - * - Subsequent sibling (`el ~ el`) + * - Pseudo-element selectors (`::before`) + * - Pseudo-class selectors (`:hover` or `:nth-child(2)`) + * - Namespace prefixes (`svg|title` or `[xlink|href]`) + * - No combinators are supported (descendant, child, next sibling, subsequent sibling) * * Future ideas: * - Namespace type selectors could be implemented with select namespaces in order to @@ -72,8 +76,12 @@ * @link https://www.w3.org/TR/selectors-api2/ * @link https://www.w3.org/TR/selectors-4/ */ -class WP_CSS_Selector implements WP_CSS_HTML_Processor_Matcher { - public function matches( WP_HTML_Processor $processor ): bool { +class WP_CSS_Compound_Selector_List implements WP_CSS_HTML_Tag_Processor_Matcher { + /** + * @param WP_HTML_Tag_Processor $processor + * @return bool + */ + public function matches( $processor ): bool { if ( $processor->get_token_type() !== '#tag' ) { return false; } @@ -87,14 +95,16 @@ public function matches( WP_HTML_Processor $processor ): bool { } /** - * @var array + * Array of selectors. + * + * @var array */ private $selectors; /** * Constructor. * - * @param array $selectors + * @param array $selectors Array of selectors. */ protected function __construct( array $selectors ) { $this->selectors = $selectors; @@ -107,10 +117,9 @@ protected function __construct( array $selectors ) { * @since TBD * * @param string $input CSS selectors. - * @return self|null + * @return static|null */ - public static function from_selectors( string $input ): ?self { - // > A selector string is a list of one or more complex selectors ([SELECTORS4], section 3.1) that may be surrounded by whitespace… + public static function from_selectors( string $input ) { $input = trim( $input, " \t\r\n\r" ); if ( '' === $input ) { @@ -132,7 +141,7 @@ public static function from_selectors( string $input ): ?self { $offset = 0; - $selector = self::parse_complex_selector( $input, $offset ); + $selector = self::parse_compound_selector( $input, $offset ); if ( null === $selector ) { return null; } @@ -146,7 +155,7 @@ public static function from_selectors( string $input ): ?self { } ++$offset; self::parse_whitespace( $input, $offset ); - $selector = self::parse_complex_selector( $input, $offset ); + $selector = self::parse_compound_selector( $input, $offset ); if ( null === $selector ) { return null; } @@ -391,73 +400,6 @@ final protected static function parse_compound_selector( string $input, int &$of return null; } - /** - * Parses a complex selector. - * - * > = [ ? ]* - * - * @return WP_CSS_Complex_Selector|null - */ - final protected static function parse_complex_selector( string $input, int &$offset ): ?WP_CSS_Complex_Selector { - if ( $offset >= strlen( $input ) ) { - return null; - } - - $updated_offset = $offset; - $selector = self::parse_compound_selector( $input, $updated_offset ); - if ( null === $selector ) { - return null; - } - - $selectors = array( $selector ); - $has_preceding_subclass_selector = null !== $selector->subclass_selectors; - - $found_whitespace = self::parse_whitespace( $input, $updated_offset ); - while ( $updated_offset < strlen( $input ) ) { - if ( - WP_CSS_Complex_Selector::COMBINATOR_CHILD === $input[ $updated_offset ] || - WP_CSS_Complex_Selector::COMBINATOR_NEXT_SIBLING === $input[ $updated_offset ] || - WP_CSS_Complex_Selector::COMBINATOR_SUBSEQUENT_SIBLING === $input[ $updated_offset ] - ) { - $combinator = $input[ $updated_offset ]; - ++$updated_offset; - self::parse_whitespace( $input, $updated_offset ); - - // Failure to find a selector here is a parse error - $selector = self::parse_compound_selector( $input, $updated_offset ); - } elseif ( $found_whitespace ) { - /* - * Whitespace is ambiguous, it could be a descendant combinator or - * insignificant whitespace. - */ - $selector = self::parse_compound_selector( $input, $updated_offset ); - if ( null === $selector ) { - break; - } - $combinator = WP_CSS_Complex_Selector::COMBINATOR_DESCENDANT; - } else { - break; - } - - if ( null === $selector ) { - return null; - } - - // `div > .className` is valid, but `.className > div` is not. - if ( $has_preceding_subclass_selector ) { - throw new Exception( 'Unsupported non-final subclass selector.' ); - } - $has_preceding_subclass_selector = null !== $selector->subclass_selectors; - - $selectors[] = $combinator; - $selectors[] = $selector; - - $found_whitespace = self::parse_whitespace( $input, $updated_offset ); - } - $offset = $updated_offset; - return new WP_CSS_Complex_Selector( $selectors ); - } - /** * Parses a subclass selector. * @@ -496,7 +438,7 @@ private static function parse_subclass_selector( string $input, int &$offset ) { const UTF8_MAX_CODEPOINT_VALUE = 0x10FFFF; const WHITESPACE_CHARACTERS = " \t\r\n\f"; - public static function parse_whitespace( string $input, int &$offset ): bool { + final public static function parse_whitespace( string $input, int &$offset ): bool { $length = strspn( $input, self::WHITESPACE_CHARACTERS, $offset ); $advanced = $length > 0; $offset += $length; @@ -692,9 +634,9 @@ final protected static function parse_string( string $input, int &$offset ): ?st * * @param string $input * @param int $offset - * @return string|null + * @return string */ - final protected static function consume_escaped_codepoint( $input, &$offset ): ?string { + final protected static function consume_escaped_codepoint( $input, &$offset ): string { $hex_length = strspn( $input, '0123456789abcdefABCDEF', $offset, 6 ); if ( $hex_length > 0 ) { /** @@ -771,7 +713,7 @@ final protected static function consume_escaped_codepoint( $input, &$offset ): ? * @param int $offset The byte offset in the string. * @return bool True if the next two codepoints are a valid escape, otherwise false. */ - private static function next_two_are_valid_escape( string $input, int $offset ): bool { + final protected static function next_two_are_valid_escape( string $input, int $offset ): bool { if ( $offset + 1 >= strlen( $input ) ) { return false; } @@ -858,7 +800,7 @@ final protected static function is_ident_codepoint( string $input, int $offset ) * @param int $offset The byte offset in the string. * @return bool True if the next three codepoints would start an ident sequence, otherwise false. */ - private static function check_if_three_code_points_would_start_an_ident_sequence( string $input, int $offset ): bool { + final protected static function check_if_three_code_points_would_start_an_ident_sequence( string $input, int $offset ): bool { if ( $offset >= strlen( $input ) ) { return false; } diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector.php b/src/wp-includes/html-api/class-wp-css-compound-selector.php index 1162aaef78c1e..e64695abe9ab3 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector.php @@ -5,8 +5,8 @@ * * > = [ ? * ]! */ -final class WP_CSS_Compound_Selector implements WP_CSS_HTML_Processor_Matcher { - public function matches( WP_HTML_Processor $processor ): bool { +final class WP_CSS_Compound_Selector implements WP_CSS_HTML_Tag_Processor_Matcher { + public function matches( WP_HTML_Tag_Processor $processor ): bool { if ( $this->type_selector ) { if ( ! $this->type_selector->matches( $processor ) ) { return false; diff --git a/src/wp-includes/html-api/class-wp-css-id-selector.php b/src/wp-includes/html-api/class-wp-css-id-selector.php index cc0589327c829..83339ff839317 100644 --- a/src/wp-includes/html-api/class-wp-css-id-selector.php +++ b/src/wp-includes/html-api/class-wp-css-id-selector.php @@ -1,6 +1,6 @@ ident = $ident; } - public function matches( WP_HTML_Processor $processor ): bool { + public function matches( WP_HTML_Tag_Processor $processor ): bool { $id = $processor->get_attribute( 'id' ); if ( ! is_string( $id ) ) { return false; } - $case_insensitive = method_exists( $processor, 'is_quirks_mode' ) && $processor->is_quirks_mode(); + $case_insensitive = $processor->is_quirks_mode(); + return $case_insensitive ? 0 === strcasecmp( $id, $this->ident ) : $processor->get_attribute( 'id' ) === $this->ident; diff --git a/src/wp-includes/html-api/class-wp-css-type-selector.php b/src/wp-includes/html-api/class-wp-css-type-selector.php index a2dcd16521cb5..c65adce14047d 100644 --- a/src/wp-includes/html-api/class-wp-css-type-selector.php +++ b/src/wp-includes/html-api/class-wp-css-type-selector.php @@ -1,7 +1,7 @@ get_tag(); if ( null === $tag_name ) { return false; diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index 9f7a43acaebbd..bbca730279876 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -657,9 +657,14 @@ public function get_unsupported_exception() { * @param string $selector_string Selector string. * @return Generator A generator pausing on each tag matching the selector. */ - public function select_all( string $selector_string ): Generator { - $selector = WP_CSS_Selector::from_selectors( $selector_string ); + public function select_all( $selector_string ): Generator { + $selector = WP_CSS_Complex_Selector_List::from_selectors( $selector_string ); if ( null === $selector ) { + _doing_it_wrong( + __METHOD__, + sprintf( 'Received unsupported or invalid selector "%s".', $selector_string ), + '6.8' + ); return; } @@ -692,7 +697,7 @@ public function select_all( string $selector_string ): Generator { * @param string $selector_string * @return bool True if a matching tag was found, otherwise false. */ - public function select( string $selector_string ) { + public function select( string $selector_string ): bool { foreach ( $this->select_all( $selector_string ) as $_ ) { return true; } diff --git a/src/wp-includes/html-api/class-wp-html-tag-processor.php b/src/wp-includes/html-api/class-wp-html-tag-processor.php index 7dadbc1bebdb2..a7633291b6bb2 100644 --- a/src/wp-includes/html-api/class-wp-html-tag-processor.php +++ b/src/wp-includes/html-api/class-wp-html-tag-processor.php @@ -860,6 +860,75 @@ public function change_parsing_namespace( string $new_namespace ): bool { return true; } + /** + * Progress through a document pausing on tags matching the provided CSS selector string. + * + * @example + * + * $processor = new WP_HTML_Tag_Processor( + * 'Example' + * ); + * foreach ( $processor->select_all( 'meta[property^="og:" i]' ) as $_ ) { + * // Loop is entered twice. + * var_dump( + * $processor->get_tag(), // string(4) "META" + * $processor->get_attribute( 'property' ), // string(7) "og:type" / string(14) "og:description" + * $processor->get_attribute( 'content' ), // string(7) "website" / string(11) "An example." + * ); + * } + * + * @since TBD + * + * @param string $selector_string Selector string. + * @return Generator A generator pausing on each tag matching the selector. + */ + public function select_all( $selector_string ): Generator { + $selector = WP_CSS_Compound_Selector_List::from_selectors( $selector_string ); + if ( null === $selector ) { + _doing_it_wrong( + __METHOD__, + sprintf( 'Received unsupported or invalid selector "%s".', $selector_string ), + '6.8' + ); + return; + } + + while ( $this->next_tag() ) { + if ( $selector->matches( $this ) ) { + yield; + } + } + } + + /** + * Move to the next tag matching the provided CSS selector string. + * + * This method will stop at the next match. To progress through all matches, use + * the {@see WP_HTML_Tag_Processor::select_all()} method. + * + * @example + * + * $processor = new WP_HTML_Tag_Processor( + * 'Example' + * ); + * $processor->select( 'meta[charset]' ); + * var_dump( + * $processor->get_tag(), // string(4) "META" + * $processor->get_attribute( 'charset' ), // string(5) "utf-8" + * ); + * + * @since TBD + * + * @param string $selector_string + * @return bool True if a matching tag was found, otherwise false. + */ + public function select( string $selector_string ): bool { + foreach ( $this->select_all( $selector_string ) as $_ ) { + return true; + } + return false; + } + /** * Finds the next tag matching the $query. * diff --git a/src/wp-includes/html-api/interface-wp-css-html-tag-processor-matcher.php b/src/wp-includes/html-api/interface-wp-css-html-tag-processor-matcher.php new file mode 100644 index 0000000000000..73d108150bb95 --- /dev/null +++ b/src/wp-includes/html-api/interface-wp-css-html-tag-processor-matcher.php @@ -0,0 +1,8 @@ +test_class = new class() extends WP_CSS_Complex_Selector_List { + public function __construct() { + parent::__construct( array() ); + } + + public static function test_parse_complex_selector( string $input, int &$offset ) { + return self::parse_complex_selector( $input, $offset ); + } + }; + } + + /** + * @ticket TBD + */ + public function test_parse_complex_selector() { + $input = 'el1 > .child#bar[baz=quux] , rest'; + $offset = 0; + $sel = $this->test_class::test_parse_complex_selector( $input, $offset ); + + $this->assertSame( 3, count( $sel->selectors ) ); + + $this->assertSame( 'el1', $sel->selectors[2]->type_selector->ident ); + $this->assertNull( $sel->selectors[2]->subclass_selectors ); + + $this->assertSame( WP_CSS_Complex_Selector::COMBINATOR_CHILD, $sel->selectors[1] ); + + $this->assertSame( 3, count( $sel->selectors[0]->subclass_selectors ) ); + $this->assertNull( $sel->selectors[0]->type_selector ); + $this->assertSame( 3, count( $sel->selectors[0]->subclass_selectors ) ); + $this->assertSame( 'child', $sel->selectors[0]->subclass_selectors[0]->ident ); + + $this->assertSame( ', rest', substr( $input, $offset ) ); + } + + /** + * @ticket TBD + */ + public function test_parse_invalid_complex_selector() { + $input = 'el.foo#bar[baz=quux] > , rest'; + $offset = 0; + $result = $this->test_class::test_parse_complex_selector( $input, $offset ); + $this->assertNull( $result ); + } + + /** + * @ticket TBD + */ + public function test_parse_empty_complex_selector() { + $input = ''; + $offset = 0; + $result = $this->test_class::test_parse_complex_selector( $input, $offset ); + $this->assertNull( $result ); + } + + /** + * @ticket TBD + */ + public function test_parse_complex_selector_list() { + $input = 'el1 el2 el.foo#bar[baz=quux], second > selector'; + $result = WP_CSS_Complex_Selector_List::from_selectors( $input ); + $this->assertNotNull( $result ); + } + + /** + * @ticket TBD + */ + public function test_parse_invalid_selector_list() { + $input = 'el,,'; + $result = WP_CSS_Complex_Selector_List::from_selectors( $input ); + $this->assertNull( $result ); + } + + /** + * @ticket TBD + */ + public function test_parse_invalid_selector_list2() { + $input = 'el!'; + $result = WP_CSS_Complex_Selector_List::from_selectors( $input ); + $this->assertNull( $result ); + } + + /** + * @ticket TBD + */ + public function test_parse_empty_selector_list() { + $input = " \t \t\n\r\f"; + $result = WP_CSS_Complex_Selector_List::from_selectors( $input ); + $this->assertNull( $result ); + } +} diff --git a/tests/phpunit/tests/html-api/wpCssSelector-parsing.php b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php similarity index 89% rename from tests/phpunit/tests/html-api/wpCssSelector-parsing.php rename to tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php index 4caa186158149..d94b61d49c14e 100644 --- a/tests/phpunit/tests/html-api/wpCssSelector-parsing.php +++ b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php @@ -10,12 +10,12 @@ * * @group html-api */ -class Tests_HtmlApi_WpCssSelector_Parsing extends WP_UnitTestCase { +class Tests_HtmlApi_WpCssCompoundSelectorList extends WP_UnitTestCase { private $test_class; public function set_up(): void { parent::set_up(); - $this->test_class = new class() extends WP_CSS_Selector { + $this->test_class = new class() extends WP_CSS_Compound_Selector_List { public function __construct() { parent::__construct( array() ); } @@ -51,10 +51,6 @@ public static function test_parse_compound_selector( string $input, int &$offset return self::parse_compound_selector( $input, $offset ); } - public static function test_parse_complex_selector( string $input, int &$offset ) { - return self::parse_complex_selector( $input, $offset ); - } - /* * Utilities */ @@ -402,53 +398,12 @@ public function test_parse_empty_selector() { $this->assertSame( 0, $offset ); } - /** - * @ticket TBD - */ - public function test_parse_complex_selector() { - $input = 'el1 > .child#bar[baz=quux] , rest'; - $offset = 0; - $sel = $this->test_class::test_parse_complex_selector( $input, $offset ); - - $this->assertSame( 3, count( $sel->selectors ) ); - - $this->assertSame( 'el1', $sel->selectors[2]->type_selector->ident ); - $this->assertNull( $sel->selectors[2]->subclass_selectors ); - - $this->assertSame( WP_CSS_Complex_Selector::COMBINATOR_CHILD, $sel->selectors[1] ); - - $this->assertSame( 3, count( $sel->selectors[0]->subclass_selectors ) ); - $this->assertNull( $sel->selectors[0]->type_selector ); - $this->assertSame( 3, count( $sel->selectors[0]->subclass_selectors ) ); - $this->assertSame( 'child', $sel->selectors[0]->subclass_selectors[0]->ident ); - - $this->assertSame( ', rest', substr( $input, $offset ) ); - } - - /** - * @ticket TBD - */ - public function test_parse_invalid_complex_selector() { - $input = 'el.foo#bar[baz=quux] > , rest'; - $offset = 0; - $result = $this->test_class::test_parse_complex_selector( $input, $offset ); - $this->assertNull( $result ); - } - - public function test_parse_empty_complex_selector() { - $input = ''; - $offset = 0; - $result = $this->test_class::test_parse_complex_selector( $input, $offset ); - $this->assertNull( $result ); - } - - /** * @ticket TBD */ public function test_parse_selector_list() { - $input = 'el1 el2 el.foo#bar[baz=quux], rest'; - $result = WP_CSS_Selector::from_selectors( $input ); + $input = 'el1, el2, el.foo#bar[baz=quux]'; + $result = WP_CSS_Compound_Selector_List::from_selectors( $input ); $this->assertNotNull( $result ); } @@ -457,7 +412,7 @@ public function test_parse_selector_list() { */ public function test_parse_invalid_selector_list() { $input = 'el,,'; - $result = WP_CSS_Selector::from_selectors( $input ); + $result = WP_CSS_Compound_Selector_List::from_selectors( $input ); $this->assertNull( $result ); } @@ -466,7 +421,7 @@ public function test_parse_invalid_selector_list() { */ public function test_parse_invalid_selector_list2() { $input = 'el!'; - $result = WP_CSS_Selector::from_selectors( $input ); + $result = WP_CSS_Compound_Selector_List::from_selectors( $input ); $this->assertNull( $result ); } @@ -475,7 +430,7 @@ public function test_parse_invalid_selector_list2() { */ public function test_parse_empty_selector_list() { $input = " \t \t\n\r\f"; - $result = WP_CSS_Selector::from_selectors( $input ); + $result = WP_CSS_Compound_Selector_List::from_selectors( $input ); $this->assertNull( $result ); } } diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php index c3a1e4121ecab..733a7135f1b17 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php @@ -66,4 +66,14 @@ public function test_select_all() { } $this->assertSame( 4, $count ); } + + /** + * @ticket TBD + * + * @expectedIncorrectUsage WP_HTML_Processor::select_all + */ + public function test_invalid_selector() { + $processor = WP_HTML_Processor::create_fragment( 'irrelevant' ); + $this->assertFalse( $processor->select( '[invalid!selector]' ) ); + } } diff --git a/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php new file mode 100644 index 0000000000000..c42c69ff0a095 --- /dev/null +++ b/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php @@ -0,0 +1,92 @@ +' ); + $this->assertFalse( $processor->select( 'div' ) ); + } + + /** + * @ticket TBD + * + * @dataProvider data_selectors + */ + public function test_select( string $html, string $selector ) { + $processor = new WP_HTML_Tag_Processor( $html ); + $this->assertTrue( $processor->select( $selector ) ); + $this->assertTrue( $processor->get_attribute( 'match' ) ); + } + + /** + * Data provider. + * + * @return array + */ + public static function data_selectors(): array { + return array( + 'simple type' => array( '

', 'div' ), + 'any type' => array( '', '*' ), + 'simple class' => array( '
', '.x' ), + 'simple id' => array( '
', '#x' ), + 'simple attribute' => array( '
', '[att]' ), + 'attribute value' => array( '
', '[att=val]' ), + 'attribute quoted value' => array( '
', '[att="::"]' ), + + 'list' => array( '

', 'a, p' ), + 'compound' => array( '

', 'section[att~="bar"]' ), + ); + } + + /** + * @ticket TBD + */ + public function test_select_all() { + $processor = new WP_HTML_Tag_Processor( '

' ); + $count = 0; + foreach ( $processor->select_all( 'div, .x, rect, #y' ) as $_ ) { + ++$count; + $this->assertTrue( $processor->get_attribute( 'match' ) ); + } + $this->assertSame( 4, $count ); + } + + /** + * @ticket TBD + * + * @expectedIncorrectUsage WP_HTML_Tag_Processor::select_all + * + * @dataProvider data_invalid_selectors + */ + public function test_invalid_selector( string $selector ) { + $processor = new WP_HTML_Tag_Processor( 'irrelevant' ); + $this->assertFalse( $processor->select( $selector ) ); + } + + /** + * Data provider. + * + * @return array + */ + public static function data_invalid_selectors(): array { + return array( + 'complex descendant' => array( 'div *' ), + 'complex child' => array( 'div > *' ), + 'invalid selector' => array( '[invalid!selector]' ), + ); + } +} From 2036a83f77a419fd1f3df89c7c7a316d4a42d5bb Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 4 Dec 2024 21:36:19 +0100 Subject: [PATCH 080/634] Simplify whitspace splitting function --- .../html-api/class-wp-css-attribute-selector.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-attribute-selector.php b/src/wp-includes/html-api/class-wp-css-attribute-selector.php index 76ccdf3804b36..1a7a9ffb37716 100644 --- a/src/wp-includes/html-api/class-wp-css-attribute-selector.php +++ b/src/wp-includes/html-api/class-wp-css-attribute-selector.php @@ -78,16 +78,15 @@ public function matches( WP_HTML_Tag_Processor $processor ): bool { * @return Generator */ private function whitespace_delimited_list( string $input ): Generator { + // Start by skipping whitespace. $offset = strspn( $input, self::WHITESPACE_CHARACTERS ); while ( $offset < strlen( $input ) ) { // Find the byte length until the next boundary. $length = strcspn( $input, self::WHITESPACE_CHARACTERS, $offset ); - if ( 0 === $length ) { - return; - } + $value = substr( $input, $offset, $length ); - $value = substr( $input, $offset, $length ); + // Move past trailing whitespace. $offset += $length + strspn( $input, self::WHITESPACE_CHARACTERS, $offset + $length ); yield $value; From 3421a4e0d634686fd820db906eb6077503985fe8 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 4 Dec 2024 21:41:15 +0100 Subject: [PATCH 081/634] Remove unreachable code --- src/wp-includes/html-api/class-wp-css-attribute-selector.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-attribute-selector.php b/src/wp-includes/html-api/class-wp-css-attribute-selector.php index 1a7a9ffb37716..17787dd70815b 100644 --- a/src/wp-includes/html-api/class-wp-css-attribute-selector.php +++ b/src/wp-includes/html-api/class-wp-css-attribute-selector.php @@ -68,8 +68,6 @@ public function matches( WP_HTML_Tag_Processor $processor ): bool { : strpos( $att_value, $this->value ) ); } - - throw new Exception( 'Unreachable' ); } /** From 784b2d913cbf469a3847b93a46c9c202f19091b7 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 4 Dec 2024 21:41:25 +0100 Subject: [PATCH 082/634] Add a lot of selector integration tests --- .../html-api/wpHtmlTagProcessor-select.php | 44 +++++++++++++++---- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php index c42c69ff0a095..66f32f905c04f 100644 --- a/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php +++ b/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php @@ -39,16 +39,42 @@ public function test_select( string $html, string $selector ) { */ public static function data_selectors(): array { return array( - 'simple type' => array( '

', 'div' ), - 'any type' => array( '', '*' ), - 'simple class' => array( '
', '.x' ), - 'simple id' => array( '
', '#x' ), - 'simple attribute' => array( '
', '[att]' ), - 'attribute value' => array( '
', '[att=val]' ), - 'attribute quoted value' => array( '
', '[att="::"]' ), + 'simple type' => array( '

', 'div' ), + 'any type' => array( '
', '*' ), + 'simple class' => array( '
', '.x' ), + 'simple id' => array( '
', '#x' ), + 'boolean attribute' => array( '
', '[att]' ), + 'boolean attribute with string match' => array( '
', '[att=""]' ), - 'list' => array( '

', 'a, p' ), - 'compound' => array( '

', 'section[att~="bar"]' ), + 'attribute value' => array( '
', '[att=val]' ), + 'attribute quoted value' => array( '
', '[att="::"]' ), + 'attribute case insensitive' => array( '
', '[att="VAL"i]' ), + 'attribute case sensitive mod' => array( '
', '[att="val"s]' ), + + 'attribute one of' => array( '
', '[att~="b"]' ), + 'attribute one of insensitive' => array( '
', '[att~="b"i]' ), + 'attribute one of mod sensitive' => array( '
', '[att~="b"s]' ), + 'attribute one of whitespace cases' => array( "
", '[att~="b"]' ), + + 'attribute with-hyphen (no hyphen)' => array( '

', '[att|="special"]' ), + 'attribute with-hyphen (hyphen prefix)' => array( '

', '[att|="special"]' ), + 'attribute with-hyphen insensitive' => array( '

', '[att|="special"i]' ), + 'attribute with-hyphen sensitive mod' => array( '

', '[att|="special"s]' ), + + 'attribute prefixed' => array( '

', '[att^="p"]' ), + 'attribute prefixed insensitive' => array( '

', '[att^="p"i]' ), + 'attribute prefixed sensitive mod' => array( '

', '[att^="p"s]' ), + + 'attribute suffixed' => array( '

', '[att$="x"]' ), + 'attribute suffixed insensitive' => array( '

', '[att$="x"i]' ), + 'attribute suffixed sensitive mod' => array( '

', '[att$="x"s]' ), + + 'attribute contains' => array( '

', '[att*="x"]' ), + 'attribute contains insensitive' => array( '

', '[att*="x"i]' ), + 'attribute contains sensitive mod' => array( '

', '[att*="x"s]' ), + + 'list' => array( '

', 'a, p' ), + 'compound' => array( '

', 'section[att="bar"]' ), ); } From 4d4c5fe2db713a4a85a8c4073e3e39f44731d140 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 4 Dec 2024 21:48:39 +0100 Subject: [PATCH 083/634] Extract normalize input method --- .../class-wp-css-complex-selector-list.php | 16 +------ .../class-wp-css-compound-selector-list.php | 43 +++++++++++++------ 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php index f3769a035f6e5..59b08532868a8 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php @@ -43,26 +43,12 @@ class WP_CSS_Complex_Selector_List extends WP_CSS_Compound_Selector_List impleme * @return static|null */ public static function from_selectors( string $input ) { - // > A selector string is a list of one or more complex selectors ([SELECTORS4], section 3.1) that may be surrounded by whitespace… - $input = trim( $input, " \t\r\n\r" ); + $input = self::normalize_selector_input( $input ); if ( '' === $input ) { return null; } - /* - * > The input stream consists of the filtered code points pushed into it as the input byte stream is decoded. - * > - * > To filter code points from a stream of (unfiltered) code points input: - * > Replace any U+000D CARRIAGE RETURN (CR) code points, U+000C FORM FEED (FF) code points, or pairs of U+000D CARRIAGE RETURN (CR) followed by U+000A LINE FEED (LF) in input by a single U+000A LINE FEED (LF) code point. - * > Replace any U+0000 NULL or surrogate code points in input with U+FFFD REPLACEMENT CHARACTER (�). - * - * https://www.w3.org/TR/css-syntax-3/#input-preprocessing - */ - $input = str_replace( array( "\r\n" ), "\n", $input ); - $input = str_replace( array( "\r", "\f" ), "\n", $input ); - $input = str_replace( "\0", "\u{FFFD}", $input ); - $offset = 0; $selector = self::parse_complex_selector( $input, $offset ); diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php index 2aae51d671f6b..a41b0ac9cd530 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php @@ -120,25 +120,12 @@ protected function __construct( array $selectors ) { * @return static|null */ public static function from_selectors( string $input ) { - $input = trim( $input, " \t\r\n\r" ); + $input = self::normalize_selector_input( $input ); if ( '' === $input ) { return null; } - /* - * > The input stream consists of the filtered code points pushed into it as the input byte stream is decoded. - * > - * > To filter code points from a stream of (unfiltered) code points input: - * > Replace any U+000D CARRIAGE RETURN (CR) code points, U+000C FORM FEED (FF) code points, or pairs of U+000D CARRIAGE RETURN (CR) followed by U+000A LINE FEED (LF) in input by a single U+000A LINE FEED (LF) code point. - * > Replace any U+0000 NULL or surrogate code points in input with U+FFFD REPLACEMENT CHARACTER (�). - * - * https://www.w3.org/TR/css-syntax-3/#input-preprocessing - */ - $input = str_replace( array( "\r\n" ), "\n", $input ); - $input = str_replace( array( "\r", "\f" ), "\n", $input ); - $input = str_replace( "\0", "\u{FFFD}", $input ); - $offset = 0; $selector = self::parse_compound_selector( $input, $offset ); @@ -842,4 +829,32 @@ final protected static function check_if_three_code_points_would_start_an_ident_ // > Return false. return self::is_ident_start_codepoint( $input, $offset ); } + + /** + * @todo doc… + */ + final protected static function normalize_selector_input( string $input ): string { + /* + * > A selector string is a list of one or more complex selectors ([SELECTORS4], section 3.1) that may be surrounded by whitespace… + * + * This list includes \f. + * A later step would normalize it to a known whitespace character, but it can be trimmed here as well. + */ + $input = trim( $input, " \t\r\n\r\f" ); + + /* + * > The input stream consists of the filtered code points pushed into it as the input byte stream is decoded. + * > + * > To filter code points from a stream of (unfiltered) code points input: + * > Replace any U+000D CARRIAGE RETURN (CR) code points, U+000C FORM FEED (FF) code points, or pairs of U+000D CARRIAGE RETURN (CR) followed by U+000A LINE FEED (LF) in input by a single U+000A LINE FEED (LF) code point. + * > Replace any U+0000 NULL or surrogate code points in input with U+FFFD REPLACEMENT CHARACTER (�). + * + * https://www.w3.org/TR/css-syntax-3/#input-preprocessing + */ + $input = str_replace( array( "\r\n" ), "\n", $input ); + $input = str_replace( array( "\r", "\f" ), "\n", $input ); + $input = str_replace( "\0", "\u{FFFD}", $input ); + + return $input; + } } From dbc37fc2d819057c9678364021d1d14ee8f91292 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 4 Dec 2024 21:52:54 +0100 Subject: [PATCH 084/634] tests --- tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php index d94b61d49c14e..2a20e317338bd 100644 --- a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php +++ b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php @@ -366,6 +366,7 @@ public static function data_attribute_selectors(): array { 'Invalid: [att s]' => array( '[att s]' ), "Invalid: [att='val\\n']" => array( "[att='val\n']" ), 'Invalid: [att=val i ' => array( '[att=val i ' ), + 'Invalid: [att="val"ix' => array( '[att="val"ix' ), ); } From d241f31643a14f70ed3469121d6f45ce0db143d0 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 4 Dec 2024 21:57:08 +0100 Subject: [PATCH 085/634] Add nonfinal subclass selector test --- .../html-api/class-wp-css-complex-selector-list.php | 8 ++++++-- .../tests/html-api/wpCssComplexSelectorList.php | 10 ++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php index 59b08532868a8..0413b8dea426a 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php @@ -134,9 +134,13 @@ final protected static function parse_complex_selector( string $input, int &$off return null; } - // `div > .className` is valid, but `.className > div` is not. + /* + * Subclass selectors in non-final position is not supported: + * - `div > .className` is valid + * - `.className > div` is not + */ if ( $has_preceding_subclass_selector ) { - throw new Exception( 'Unsupported non-final subclass selector.' ); + return null; } $has_preceding_subclass_selector = null !== $selector->subclass_selectors; diff --git a/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php b/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php index 5b485a5029db5..5cceddbdddd30 100644 --- a/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php +++ b/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php @@ -59,6 +59,16 @@ public function test_parse_invalid_complex_selector() { $this->assertNull( $result ); } + /** + * @ticket TBD + */ + public function test_parse_invalid_complex_selector_nonfinal_subclass() { + $input = 'el.foo#bar[baz=quux] > final, rest'; + $offset = 0; + $result = $this->test_class::test_parse_complex_selector( $input, $offset ); + $this->assertNull( $result ); + } + /** * @ticket TBD */ From 663070b34b7b9b04413a6d8b7cf0f20645d7eadb Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 5 Dec 2024 12:38:54 +0100 Subject: [PATCH 086/634] Fix logic bug in child selector exploration --- src/wp-includes/html-api/class-wp-css-complex-selector.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector.php b/src/wp-includes/html-api/class-wp-css-complex-selector.php index 520f3bf3d8fde..ed4d2e7a6e662 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector.php @@ -46,7 +46,7 @@ private function explore_matches( array $selectors, array $breadcrumbs ): bool { if ( '*' === $selector->type_selector->ident || strcasecmp( $breadcrumbs[0], $selector->type_selector->ident ) === 0 ) { return $this->explore_matches( array_slice( $selectors, 2 ), array_slice( $breadcrumbs, 1 ) ); } - return $this->explore_matches( $selectors, array_slice( $breadcrumbs, 1 ) ); + return false; case self::COMBINATOR_DESCENDANT: // Find _all_ the breadcrumbs that match and recurse from each of them. From 5478af99a8ecbbff54503f3230f247bc06f56fdf Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 5 Dec 2024 12:54:58 +0100 Subject: [PATCH 087/634] Improve selector integration tests --- .../tests/html-api/wpHtmlProcessor-select.php | 62 +++++++------- .../html-api/wpHtmlTagProcessor-select.php | 83 +++++++++---------- 2 files changed, 72 insertions(+), 73 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php index 733a7135f1b17..8515be63d83f8 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php @@ -26,54 +26,60 @@ public function test_select_miss() { * * @dataProvider data_selectors */ - public function test_select( string $html, string $selector ) { + public function test_select_all( string $html, string $selector, int $match_count ) { $processor = WP_HTML_Processor::create_full_parser( $html ); - $this->assertTrue( $processor->select( $selector ) ); - $this->assertTrue( $processor->get_attribute( 'match' ) ); + $count = 0; + foreach ( $processor->select_all( $selector ) as $_ ) { + $breadcrumb_string = implode( ', ', $processor->get_breadcrumbs() ); + $this->assertTrue( + $processor->get_attribute( 'match' ), + "Matched unexpected tag {$processor->get_tag()} @ {$breadcrumb_string}" + ); + ++$count; + } + $this->assertSame( $match_count, $count, 'Did not match expected number of tags.' ); } /** * Data provider. * + * Most selectors are covered by the tag processor selector tests. + * This suite should focus on complex selectors. + * * @return array */ public static function data_selectors(): array { return array( - 'simple type' => array( '
', 'div' ), - 'any type' => array( '', '*' ), - 'simple class' => array( '
', '.x' ), - 'simple id' => array( '
', '#x' ), - 'simple attribute' => array( '
', '[att]' ), - 'attribute value' => array( '
', '[att=val]' ), - 'attribute quoted value' => array( '
', '[att="::"]' ), - 'complex any descendant' => array( '
', 'section *' ), - 'complex any child' => array( '
', 'section > *' ), - - 'list' => array( '

', 'a, p' ), - 'compound' => array( '

', 'section[att~="bar"]' ), + 'any descendant' => array( '

', 'section *', 4 ), + 'any child 1' => array( '

', 'section > *', 2 ), + 'any child 2' => array( '

', 'div > *', 1 ), ); } /** * @ticket TBD + * + * @expectedIncorrectUsage WP_HTML_Processor::select_all + * + * @dataProvider data_invalid_selectors */ - public function test_select_all() { - $processor = WP_HTML_Processor::create_full_parser( '

' ); - $count = 0; - foreach ( $processor->select_all( 'div, .x, svg>rect, #y' ) as $_ ) { - ++$count; - $this->assertTrue( $processor->get_attribute( 'match' ) ); - } - $this->assertSame( 4, $count ); + public function test_invalid_selector( string $selector ) { + $processor = WP_HTML_Processor::create_fragment( 'irrelevant' ); + $this->assertFalse( $processor->select( $selector ) ); } /** - * @ticket TBD + * Data provider. * - * @expectedIncorrectUsage WP_HTML_Processor::select_all + * @return array */ - public function test_invalid_selector() { - $processor = WP_HTML_Processor::create_fragment( 'irrelevant' ); - $this->assertFalse( $processor->select( '[invalid!selector]' ) ); + public static function data_invalid_selectors(): array { + return array( + 'invalid selector' => array( '[invalid!selector]' ), + + // The class selectors below are not allowed in non-final position. + 'unsupported child selector' => array( '.parent > .child' ), + 'unsupported descendant selector' => array( '.ancestor .descendant' ), + ); } } diff --git a/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php index 66f32f905c04f..6bc6ba1e6edbc 100644 --- a/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php +++ b/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php @@ -26,10 +26,17 @@ public function test_select_miss() { * * @dataProvider data_selectors */ - public function test_select( string $html, string $selector ) { + public function test_select( string $html, string $selector, int $match_count ) { $processor = new WP_HTML_Tag_Processor( $html ); - $this->assertTrue( $processor->select( $selector ) ); - $this->assertTrue( $processor->get_attribute( 'match' ) ); + $count = 0; + foreach ( $processor->select_all( $selector ) as $_ ) { + $this->assertTrue( + $processor->get_attribute( 'match' ), + "Matched unexpected tag {$processor->get_tag()}" + ); + ++$count; + } + $this->assertSame( $match_count, $count, 'Did not match expected number of tags.' ); } /** @@ -39,58 +46,44 @@ public function test_select( string $html, string $selector ) { */ public static function data_selectors(): array { return array( - 'simple type' => array( '

', 'div' ), - 'any type' => array( '
', '*' ), - 'simple class' => array( '
', '.x' ), - 'simple id' => array( '
', '#x' ), - 'boolean attribute' => array( '
', '[att]' ), - 'boolean attribute with string match' => array( '
', '[att=""]' ), + 'simple type' => array( '
', 'div', 2 ), + 'any type' => array( '
', '*', 2 ), + 'simple class' => array( '
', '.x', 2 ), + 'simple id' => array( '
', '#x', 2 ), - 'attribute value' => array( '
', '[att=val]' ), - 'attribute quoted value' => array( '
', '[att="::"]' ), - 'attribute case insensitive' => array( '
', '[att="VAL"i]' ), - 'attribute case sensitive mod' => array( '
', '[att="val"s]' ), + 'attribute presence' => array( '
', '[att]', 2 ), + 'attribute empty string match' => array( '
', '[att=""]', 2 ), + 'attribute value' => array( '

', '[att=val]', 2 ), + 'attribute quoted value' => array( '

', '[att="::"]', 2 ), + 'attribute case insensitive' => array( '

', '[att="VAL"i]', 2 ), + 'attribute case sensitive mod' => array( '

', '[att="val"s]', 2 ), - 'attribute one of' => array( '

', '[att~="b"]' ), - 'attribute one of insensitive' => array( '
', '[att~="b"i]' ), - 'attribute one of mod sensitive' => array( '
', '[att~="b"s]' ), - 'attribute one of whitespace cases' => array( "
", '[att~="b"]' ), + 'attribute one of' => array( '

', '[att~="b"]', 3 ), + 'attribute one of insensitive' => array( '

', '[att~="b"i]', 1 ), + 'attribute one of mod sensitive' => array( '
', '[att~="b"s]', 1 ), + 'attribute one of whitespace cases' => array( "
", '[att~="b"]', 1 ), - 'attribute with-hyphen (no hyphen)' => array( '

', '[att|="special"]' ), - 'attribute with-hyphen (hyphen prefix)' => array( '

', '[att|="special"]' ), - 'attribute with-hyphen insensitive' => array( '

', '[att|="special"i]' ), - 'attribute with-hyphen sensitive mod' => array( '

', '[att|="special"s]' ), + 'attribute with-hyphen' => array( '

', '[att|="special"]', 2 ), + 'attribute with-hyphen insensitive' => array( '

', '[att|="special" i]', 2 ), + 'attribute with-hyphen sensitive mod' => array( '

', '[att|="special"s]', 1 ), - 'attribute prefixed' => array( '

', '[att^="p"]' ), - 'attribute prefixed insensitive' => array( '

', '[att^="p"i]' ), - 'attribute prefixed sensitive mod' => array( '

', '[att^="p"s]' ), + 'attribute prefixed' => array( '

', '[att^="p"]', 2 ), + 'attribute prefixed insensitive' => array( '

', '[att^="p"i]', 1 ), + 'attribute prefixed sensitive mod' => array( '

', '[att^="p"s]', 1 ), - 'attribute suffixed' => array( '

', '[att$="x"]' ), - 'attribute suffixed insensitive' => array( '

', '[att$="x"i]' ), - 'attribute suffixed sensitive mod' => array( '

', '[att$="x"s]' ), + 'attribute suffixed' => array( '

', '[att$="x"]', 2 ), + 'attribute suffixed insensitive' => array( '

', '[att$="x"i]', 1 ), + 'attribute suffixed sensitive mod' => array( '

', '[att$="x"s]', 1 ), - 'attribute contains' => array( '

', '[att*="x"]' ), - 'attribute contains insensitive' => array( '

', '[att*="x"i]' ), - 'attribute contains sensitive mod' => array( '

', '[att*="x"s]' ), + 'attribute contains' => array( '

', '[att*="x"]', 2 ), + 'attribute contains insensitive' => array( '

', '[att*="x"i]', 1 ), + 'attribute contains sensitive mod' => array( '

', '[att*="x"s]', 1 ), - 'list' => array( '

', 'a, p' ), - 'compound' => array( '

', 'section[att="bar"]' ), + 'list' => array( '

', 'a, p, .class, #id, [att]', 2 ), + 'compound' => array( '

', 'custom-el[att="bar"][ fruit ~= "banana" i]', 1 ), ); } - /** - * @ticket TBD - */ - public function test_select_all() { - $processor = new WP_HTML_Tag_Processor( '

' ); - $count = 0; - foreach ( $processor->select_all( 'div, .x, rect, #y' ) as $_ ) { - ++$count; - $this->assertTrue( $processor->get_attribute( 'match' ) ); - } - $this->assertSame( 4, $count ); - } - /** * @ticket TBD * From 4f6bf948404cae07425b676048109be3a52d8853 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 5 Dec 2024 13:13:03 +0100 Subject: [PATCH 088/634] Try abstract class instead of interface --- src/wp-includes/html-api/class-wp-css-attribute-selector.php | 2 +- src/wp-includes/html-api/class-wp-css-class-selector.php | 2 +- .../html-api/class-wp-css-complex-selector-list.php | 2 +- src/wp-includes/html-api/class-wp-css-complex-selector.php | 2 +- .../html-api/class-wp-css-compound-selector-list.php | 2 +- src/wp-includes/html-api/class-wp-css-compound-selector.php | 2 +- src/wp-includes/html-api/class-wp-css-id-selector.php | 2 +- src/wp-includes/html-api/class-wp-css-type-selector.php | 2 +- .../html-api/interface-wp-css-html-processor-matcher.php | 4 ++-- .../html-api/interface-wp-css-html-tag-processor-matcher.php | 4 ++-- 10 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-attribute-selector.php b/src/wp-includes/html-api/class-wp-css-attribute-selector.php index 17787dd70815b..4cf554c10eca9 100644 --- a/src/wp-includes/html-api/class-wp-css-attribute-selector.php +++ b/src/wp-includes/html-api/class-wp-css-attribute-selector.php @@ -1,6 +1,6 @@ has_class( $this->ident ); } diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php index 0413b8dea426a..669139097fa75 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php @@ -32,7 +32,7 @@ * * @access private */ -class WP_CSS_Complex_Selector_List extends WP_CSS_Compound_Selector_List implements WP_CSS_HTML_Processor_Matcher { +class WP_CSS_Complex_Selector_List extends WP_CSS_Compound_Selector_List { /** * Takes a CSS selector string and returns an instance of itself or `null` if the selector * string is invalid or unsupported. diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector.php b/src/wp-includes/html-api/class-wp-css-complex-selector.php index ed4d2e7a6e662..4f83476898ec0 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector.php @@ -5,7 +5,7 @@ * * > = [ ? ] * */ -final class WP_CSS_Complex_Selector implements WP_CSS_HTML_Processor_Matcher { +final class WP_CSS_Complex_Selector extends WP_CSS_HTML_Processor_Matcher { public function matches( WP_HTML_Processor $processor ): bool { // First selector must match this location. if ( ! $this->selectors[0]->matches( $processor ) ) { diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php index a41b0ac9cd530..0095b22977b0a 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php @@ -76,7 +76,7 @@ * @link https://www.w3.org/TR/selectors-api2/ * @link https://www.w3.org/TR/selectors-4/ */ -class WP_CSS_Compound_Selector_List implements WP_CSS_HTML_Tag_Processor_Matcher { +class WP_CSS_Compound_Selector_List extends WP_CSS_HTML_Tag_Processor_Matcher { /** * @param WP_HTML_Tag_Processor $processor * @return bool diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector.php b/src/wp-includes/html-api/class-wp-css-compound-selector.php index e64695abe9ab3..3340515569bdd 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector.php @@ -5,7 +5,7 @@ * * > = [ ? * ]! */ -final class WP_CSS_Compound_Selector implements WP_CSS_HTML_Tag_Processor_Matcher { +final class WP_CSS_Compound_Selector extends WP_CSS_HTML_Tag_Processor_Matcher { public function matches( WP_HTML_Tag_Processor $processor ): bool { if ( $this->type_selector ) { if ( ! $this->type_selector->matches( $processor ) ) { diff --git a/src/wp-includes/html-api/class-wp-css-id-selector.php b/src/wp-includes/html-api/class-wp-css-id-selector.php index 83339ff839317..15cb2745ede9e 100644 --- a/src/wp-includes/html-api/class-wp-css-id-selector.php +++ b/src/wp-includes/html-api/class-wp-css-id-selector.php @@ -1,6 +1,6 @@ get_tag(); if ( null === $tag_name ) { diff --git a/src/wp-includes/html-api/interface-wp-css-html-processor-matcher.php b/src/wp-includes/html-api/interface-wp-css-html-processor-matcher.php index 2ae29413b35d2..aa280ddefa696 100644 --- a/src/wp-includes/html-api/interface-wp-css-html-processor-matcher.php +++ b/src/wp-includes/html-api/interface-wp-css-html-processor-matcher.php @@ -1,8 +1,8 @@ Date: Thu, 5 Dec 2024 13:13:06 +0100 Subject: [PATCH 089/634] Revert "Try abstract class instead of interface" This reverts commit 74881651faf991eabceb090707ce8b43c2a25316. --- src/wp-includes/html-api/class-wp-css-attribute-selector.php | 2 +- src/wp-includes/html-api/class-wp-css-class-selector.php | 2 +- .../html-api/class-wp-css-complex-selector-list.php | 2 +- src/wp-includes/html-api/class-wp-css-complex-selector.php | 2 +- .../html-api/class-wp-css-compound-selector-list.php | 2 +- src/wp-includes/html-api/class-wp-css-compound-selector.php | 2 +- src/wp-includes/html-api/class-wp-css-id-selector.php | 2 +- src/wp-includes/html-api/class-wp-css-type-selector.php | 2 +- .../html-api/interface-wp-css-html-processor-matcher.php | 4 ++-- .../html-api/interface-wp-css-html-tag-processor-matcher.php | 4 ++-- 10 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-attribute-selector.php b/src/wp-includes/html-api/class-wp-css-attribute-selector.php index 4cf554c10eca9..17787dd70815b 100644 --- a/src/wp-includes/html-api/class-wp-css-attribute-selector.php +++ b/src/wp-includes/html-api/class-wp-css-attribute-selector.php @@ -1,6 +1,6 @@ has_class( $this->ident ); } diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php index 669139097fa75..0413b8dea426a 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php @@ -32,7 +32,7 @@ * * @access private */ -class WP_CSS_Complex_Selector_List extends WP_CSS_Compound_Selector_List { +class WP_CSS_Complex_Selector_List extends WP_CSS_Compound_Selector_List implements WP_CSS_HTML_Processor_Matcher { /** * Takes a CSS selector string and returns an instance of itself or `null` if the selector * string is invalid or unsupported. diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector.php b/src/wp-includes/html-api/class-wp-css-complex-selector.php index 4f83476898ec0..ed4d2e7a6e662 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector.php @@ -5,7 +5,7 @@ * * > = [ ? ] * */ -final class WP_CSS_Complex_Selector extends WP_CSS_HTML_Processor_Matcher { +final class WP_CSS_Complex_Selector implements WP_CSS_HTML_Processor_Matcher { public function matches( WP_HTML_Processor $processor ): bool { // First selector must match this location. if ( ! $this->selectors[0]->matches( $processor ) ) { diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php index 0095b22977b0a..a41b0ac9cd530 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php @@ -76,7 +76,7 @@ * @link https://www.w3.org/TR/selectors-api2/ * @link https://www.w3.org/TR/selectors-4/ */ -class WP_CSS_Compound_Selector_List extends WP_CSS_HTML_Tag_Processor_Matcher { +class WP_CSS_Compound_Selector_List implements WP_CSS_HTML_Tag_Processor_Matcher { /** * @param WP_HTML_Tag_Processor $processor * @return bool diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector.php b/src/wp-includes/html-api/class-wp-css-compound-selector.php index 3340515569bdd..e64695abe9ab3 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector.php @@ -5,7 +5,7 @@ * * > = [ ? * ]! */ -final class WP_CSS_Compound_Selector extends WP_CSS_HTML_Tag_Processor_Matcher { +final class WP_CSS_Compound_Selector implements WP_CSS_HTML_Tag_Processor_Matcher { public function matches( WP_HTML_Tag_Processor $processor ): bool { if ( $this->type_selector ) { if ( ! $this->type_selector->matches( $processor ) ) { diff --git a/src/wp-includes/html-api/class-wp-css-id-selector.php b/src/wp-includes/html-api/class-wp-css-id-selector.php index 15cb2745ede9e..83339ff839317 100644 --- a/src/wp-includes/html-api/class-wp-css-id-selector.php +++ b/src/wp-includes/html-api/class-wp-css-id-selector.php @@ -1,6 +1,6 @@ get_tag(); if ( null === $tag_name ) { diff --git a/src/wp-includes/html-api/interface-wp-css-html-processor-matcher.php b/src/wp-includes/html-api/interface-wp-css-html-processor-matcher.php index aa280ddefa696..2ae29413b35d2 100644 --- a/src/wp-includes/html-api/interface-wp-css-html-processor-matcher.php +++ b/src/wp-includes/html-api/interface-wp-css-html-processor-matcher.php @@ -1,8 +1,8 @@ Date: Thu, 5 Dec 2024 14:51:39 +0100 Subject: [PATCH 090/634] Clean up and document attribute selector --- .../class-wp-css-attribute-selector.php | 214 ++++++++++-------- 1 file changed, 122 insertions(+), 92 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-attribute-selector.php b/src/wp-includes/html-api/class-wp-css-attribute-selector.php index 17787dd70815b..7036dd3775cc1 100644 --- a/src/wp-includes/html-api/class-wp-css-attribute-selector.php +++ b/src/wp-includes/html-api/class-wp-css-attribute-selector.php @@ -1,96 +1,23 @@ get_attribute( $this->name ); - if ( null === $att_value ) { - return false; - } - - if ( null === $this->value ) { - return true; - } - - if ( true === $att_value ) { - $att_value = ''; - } - - $case_insensitive = self::MODIFIER_CASE_INSENSITIVE === $this->modifier; - - switch ( $this->matcher ) { - case self::MATCH_EXACT: - return $case_insensitive - ? 0 === strcasecmp( $att_value, $this->value ) - : $att_value === $this->value; - - case self::MATCH_ONE_OF_EXACT: - foreach ( $this->whitespace_delimited_list( $att_value ) as $val ) { - if ( - $case_insensitive - ? 0 === strcasecmp( $val, $this->value ) - : $val === $this->value - ) { - return true; - } - } - return false; - - case self::MATCH_EXACT_OR_EXACT_WITH_HYPHEN: - // Attempt the full match first - if ( - $case_insensitive - ? 0 === strcasecmp( $att_value, $this->value ) - : $att_value === $this->value - ) { - return true; - } - - // Partial match - if ( strlen( $att_value ) < strlen( $this->value ) + 1 ) { - return false; - } - - $starts_with = "{$this->value}-"; - return 0 === substr_compare( $att_value, $starts_with, 0, strlen( $starts_with ), $case_insensitive ); - - case self::MATCH_PREFIXED_BY: - return 0 === substr_compare( $att_value, $this->value, 0, strlen( $this->value ), $case_insensitive ); - - case self::MATCH_SUFFIXED_BY: - return 0 === substr_compare( $att_value, $this->value, -strlen( $this->value ), null, $case_insensitive ); - - case self::MATCH_CONTAINS: - return false !== ( - $case_insensitive - ? stripos( $att_value, $this->value ) - : strpos( $att_value, $this->value ) - ); - } - } - - /** - * @param string $input - * - * @return Generator - */ - private function whitespace_delimited_list( string $input ): Generator { - // Start by skipping whitespace. - $offset = strspn( $input, self::WHITESPACE_CHARACTERS ); - - while ( $offset < strlen( $input ) ) { - // Find the byte length until the next boundary. - $length = strcspn( $input, self::WHITESPACE_CHARACTERS, $offset ); - $value = substr( $input, $offset, $length ); - - // Move past trailing whitespace. - $offset += $length + strspn( $input, self::WHITESPACE_CHARACTERS, $offset + $length ); - - yield $value; - } - } - /** * [att=val] * Represents an element with the att attribute whose value is exactly "val". @@ -145,11 +72,11 @@ private function whitespace_delimited_list( string $input ): Generator { */ const MODIFIER_CASE_INSENSITIVE = 'case-insensitive'; - /** * The attribute name. * * @var string + * @readonly */ public $name; @@ -157,6 +84,7 @@ private function whitespace_delimited_list( string $input ): Generator { * The attribute matcher. * * @var null|self::MATCH_* + * @readonly */ public $matcher; @@ -164,6 +92,7 @@ private function whitespace_delimited_list( string $input ): Generator { * The attribute value. * * @var string|null + * @readonly */ public $value; @@ -171,10 +100,13 @@ private function whitespace_delimited_list( string $input ): Generator { * The attribute modifier. * * @var null|self::MODIFIER_* + * @readonly */ public $modifier; /** + * Constructor. + * * @param string $name * @param null|self::MATCH_* $matcher * @param null|string $value @@ -186,4 +118,102 @@ public function __construct( string $name, ?string $matcher = null, ?string $val $this->value = $value; $this->modifier = $modifier; } + + /** + * Determines if the processor's current position matches the selector. + * + * @param WP_HTML_Tag_Processor $processor + * @return bool True if the processor's current position matches the selector. + */ + public function matches( WP_HTML_Tag_Processor $processor ): bool { + $att_value = $processor->get_attribute( $this->name ); + if ( null === $att_value ) { + return false; + } + + if ( null === $this->value ) { + return true; + } + + if ( true === $att_value ) { + $att_value = ''; + } + + $case_insensitive = self::MODIFIER_CASE_INSENSITIVE === $this->modifier; + + switch ( $this->matcher ) { + case self::MATCH_EXACT: + return $case_insensitive + ? 0 === strcasecmp( $att_value, $this->value ) + : $att_value === $this->value; + + case self::MATCH_ONE_OF_EXACT: + foreach ( $this->whitespace_delimited_list( $att_value ) as $val ) { + if ( + $case_insensitive + ? 0 === strcasecmp( $val, $this->value ) + : $val === $this->value + ) { + return true; + } + } + return false; + + case self::MATCH_EXACT_OR_EXACT_WITH_HYPHEN: + // Attempt the full match first + if ( + $case_insensitive + ? 0 === strcasecmp( $att_value, $this->value ) + : $att_value === $this->value + ) { + return true; + } + + // Partial match + if ( strlen( $att_value ) < strlen( $this->value ) + 1 ) { + return false; + } + + $starts_with = "{$this->value}-"; + return 0 === substr_compare( $att_value, $starts_with, 0, strlen( $starts_with ), $case_insensitive ); + + case self::MATCH_PREFIXED_BY: + return 0 === substr_compare( $att_value, $this->value, 0, strlen( $this->value ), $case_insensitive ); + + case self::MATCH_SUFFIXED_BY: + return 0 === substr_compare( $att_value, $this->value, -strlen( $this->value ), null, $case_insensitive ); + + case self::MATCH_CONTAINS: + return false !== ( + $case_insensitive + ? stripos( $att_value, $this->value ) + : strpos( $att_value, $this->value ) + ); + } + } + + /** + * Splits a string into a list of whitespace delimited values. + * + * This is useful for the {@see WP_CSS_Attribute_Selector::MATCH_ONE_OF_EXACT} matcher. + * + * @param string $input + * + * @return Generator + */ + private function whitespace_delimited_list( string $input ): Generator { + // Start by skipping whitespace. + $offset = strspn( $input, " \t\r\n\f" ); + + while ( $offset < strlen( $input ) ) { + // Find the byte length until the next boundary. + $length = strcspn( $input, " \t\r\n\f", $offset ); + $value = substr( $input, $offset, $length ); + + // Move past trailing whitespace. + $offset += $length + strspn( $input, " \t\r\n\f", $offset + $length ); + + yield $value; + } + } } From 32ee2a71197572ea713b6a9a3ee1a9e6b53c0d09 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 5 Dec 2024 19:43:08 +0100 Subject: [PATCH 091/634] Update ticket number in tests --- .../html-api/wpCssComplexSelectorList.php | 16 ++++++------ .../html-api/wpCssCompoundSelectorList.php | 26 +++++++++---------- .../tests/html-api/wpHtmlProcessor-select.php | 6 ++--- .../html-api/wpHtmlTagProcessor-select.php | 6 ++--- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php b/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php index 5cceddbdddd30..0b17e57847662 100644 --- a/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php +++ b/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php @@ -27,7 +27,7 @@ public static function test_parse_complex_selector( string $input, int &$offset } /** - * @ticket TBD + * @ticket 62653 */ public function test_parse_complex_selector() { $input = 'el1 > .child#bar[baz=quux] , rest'; @@ -50,7 +50,7 @@ public function test_parse_complex_selector() { } /** - * @ticket TBD + * @ticket 62653 */ public function test_parse_invalid_complex_selector() { $input = 'el.foo#bar[baz=quux] > , rest'; @@ -60,7 +60,7 @@ public function test_parse_invalid_complex_selector() { } /** - * @ticket TBD + * @ticket 62653 */ public function test_parse_invalid_complex_selector_nonfinal_subclass() { $input = 'el.foo#bar[baz=quux] > final, rest'; @@ -70,7 +70,7 @@ public function test_parse_invalid_complex_selector_nonfinal_subclass() { } /** - * @ticket TBD + * @ticket 62653 */ public function test_parse_empty_complex_selector() { $input = ''; @@ -80,7 +80,7 @@ public function test_parse_empty_complex_selector() { } /** - * @ticket TBD + * @ticket 62653 */ public function test_parse_complex_selector_list() { $input = 'el1 el2 el.foo#bar[baz=quux], second > selector'; @@ -89,7 +89,7 @@ public function test_parse_complex_selector_list() { } /** - * @ticket TBD + * @ticket 62653 */ public function test_parse_invalid_selector_list() { $input = 'el,,'; @@ -98,7 +98,7 @@ public function test_parse_invalid_selector_list() { } /** - * @ticket TBD + * @ticket 62653 */ public function test_parse_invalid_selector_list2() { $input = 'el!'; @@ -107,7 +107,7 @@ public function test_parse_invalid_selector_list2() { } /** - * @ticket TBD + * @ticket 62653 */ public function test_parse_empty_selector_list() { $input = " \t \t\n\r\f"; diff --git a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php index 2a20e317338bd..b5a2d9956679d 100644 --- a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php +++ b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php @@ -114,7 +114,7 @@ public static function data_idents(): array { } /** - * @ticket TBD + * @ticket 62653 */ public function test_is_ident_and_is_ident_start() { $this->assertFalse( $this->test_class::test_is_ident_codepoint( '[', 0 ) ); @@ -124,7 +124,7 @@ public function test_is_ident_and_is_ident_start() { } /** - * @ticket TBD + * @ticket 62653 * * @dataProvider data_idents */ @@ -141,7 +141,7 @@ public function test_parse_ident( string $input, ?string $expected = null, ?stri } /** - * @ticket TBD + * @ticket 62653 * * @dataProvider data_strings */ @@ -192,7 +192,7 @@ public static function data_strings(): array { } /** - * @ticket TBD + * @ticket 62653 * * @dataProvider data_id_selectors */ @@ -226,7 +226,7 @@ public static function data_id_selectors(): array { } /** - * @ticket TBD + * @ticket 62653 * * @dataProvider data_class_selectors */ @@ -260,7 +260,7 @@ public static function data_class_selectors(): array { } /** - * @ticket TBD + * @ticket 62653 * * @dataProvider data_type_selectors */ @@ -296,7 +296,7 @@ public static function data_type_selectors(): array { } /** - * @ticket TBD + * @ticket 62653 * * @dataProvider data_attribute_selectors */ @@ -371,7 +371,7 @@ public static function data_attribute_selectors(): array { } /** - * @ticket TBD + * @ticket 62653 */ public function test_parse_selector() { $input = 'el.foo#bar[baz=quux] > .child'; @@ -389,7 +389,7 @@ public function test_parse_selector() { } /** - * @ticket TBD + * @ticket 62653 */ public function test_parse_empty_selector() { $input = ''; @@ -400,7 +400,7 @@ public function test_parse_empty_selector() { } /** - * @ticket TBD + * @ticket 62653 */ public function test_parse_selector_list() { $input = 'el1, el2, el.foo#bar[baz=quux]'; @@ -409,7 +409,7 @@ public function test_parse_selector_list() { } /** - * @ticket TBD + * @ticket 62653 */ public function test_parse_invalid_selector_list() { $input = 'el,,'; @@ -418,7 +418,7 @@ public function test_parse_invalid_selector_list() { } /** - * @ticket TBD + * @ticket 62653 */ public function test_parse_invalid_selector_list2() { $input = 'el!'; @@ -427,7 +427,7 @@ public function test_parse_invalid_selector_list2() { } /** - * @ticket TBD + * @ticket 62653 */ public function test_parse_empty_selector_list() { $input = " \t \t\n\r\f"; diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php index 8515be63d83f8..40e1d96978afe 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php @@ -14,7 +14,7 @@ */ class Tests_HtmlApi_WpHtmlProcessor_Select extends WP_UnitTestCase { /** - * @ticket TBD + * @ticket 62653 */ public function test_select_miss() { $processor = WP_HTML_Processor::create_full_parser( '' ); @@ -22,7 +22,7 @@ public function test_select_miss() { } /** - * @ticket TBD + * @ticket 62653 * * @dataProvider data_selectors */ @@ -57,7 +57,7 @@ public static function data_selectors(): array { } /** - * @ticket TBD + * @ticket 62653 * * @expectedIncorrectUsage WP_HTML_Processor::select_all * diff --git a/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php index 6bc6ba1e6edbc..586e38b4bafb2 100644 --- a/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php +++ b/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php @@ -14,7 +14,7 @@ */ class Tests_HtmlApi_WpHtmlTagProcessor_Select extends WP_UnitTestCase { /** - * @ticket TBD + * @ticket 62653 */ public function test_select_miss() { $processor = new WP_HTML_Tag_Processor( '' ); @@ -22,7 +22,7 @@ public function test_select_miss() { } /** - * @ticket TBD + * @ticket 62653 * * @dataProvider data_selectors */ @@ -85,7 +85,7 @@ public static function data_selectors(): array { } /** - * @ticket TBD + * @ticket 62653 * * @expectedIncorrectUsage WP_HTML_Tag_Processor::select_all * From 5922494030b000bf4d229975a5fd1968c14b20fc Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 5 Dec 2024 21:28:24 +0100 Subject: [PATCH 092/634] Improve some types --- .../html-api/class-wp-css-complex-selector.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector.php b/src/wp-includes/html-api/class-wp-css-complex-selector.php index ed4d2e7a6e662..a4cfd46622560 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector.php @@ -16,7 +16,7 @@ public function matches( WP_HTML_Processor $processor ): bool { return true; } - /** @var array $breadcrumbs */ + /** @var string[] */ $breadcrumbs = array_slice( array_reverse( $processor->get_breadcrumbs() ), 1 ); $selectors = array_slice( $this->selectors, 1 ); return $this->explore_matches( $selectors, $breadcrumbs ); @@ -26,7 +26,7 @@ public function matches( WP_HTML_Processor $processor ): bool { * This only looks at breadcrumbs and can therefore only support type selectors. * * @param array $selectors - * @param array $breadcrumbs + * @param string[] $breadcrumbs */ private function explore_matches( array $selectors, array $breadcrumbs ): bool { if ( array() === $selectors ) { @@ -36,9 +36,9 @@ private function explore_matches( array $selectors, array $breadcrumbs ): bool { return false; } - /** @var self::COMBINATOR_* $combinator */ + /** @var self::COMBINATOR_* */ $combinator = $selectors[0]; - /** @var WP_CSS_Compound_Selector $selector */ + /** @var WP_CSS_Compound_Selector */ $selector = $selectors[1]; switch ( $combinator ) { From e492aa60e2db167ec87a048f64fab13378ec4694 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 5 Dec 2024 22:16:57 +0100 Subject: [PATCH 093/634] Fix and improve string token parsing --- .../class-wp-css-compound-selector-list.php | 19 +++++++++++++------ .../html-api/wpCssCompoundSelectorList.php | 9 ++++++--- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php index a41b0ac9cd530..8cca2e27c9ec3 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php @@ -548,7 +548,7 @@ final protected static function parse_ident( string $input, int &$offset ): ?str * @return string|null */ final protected static function parse_string( string $input, int &$offset ): ?string { - if ( $offset + 1 >= strlen( $input ) ) { + if ( $offset >= strlen( $input ) ) { return null; } @@ -559,8 +559,19 @@ final protected static function parse_string( string $input, int &$offset ): ?st $string_token = ''; - $updated_offset = $offset + 1; + $updated_offset = $offset + 1; + $anything_else_mask = "\\\n{$ending_code_point}"; while ( $updated_offset < strlen( $input ) ) { + $anything_else_length = strcspn( $input, $anything_else_mask, $updated_offset ); + if ( $anything_else_length > 0 ) { + $string_token .= substr( $input, $updated_offset, $anything_else_length ); + $updated_offset += $anything_else_length; + + if ( $updated_offset >= strlen( $input ) ) { + break; + } + } + switch ( $input[ $updated_offset ] ) { case '\\': ++$updated_offset; @@ -587,10 +598,6 @@ final protected static function parse_string( string $input, int &$offset ): ?st case $ending_code_point: ++$updated_offset; break 2; - - default: - $string_token .= $input[ $updated_offset ]; - ++$updated_offset; } } diff --git a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php index b5a2d9956679d..715e0e26bc9cd 100644 --- a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php +++ b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php @@ -181,13 +181,16 @@ public static function data_strings(): array { "'foo\\" => array( "'foo\\", 'foo', '' ), + '"' => array( '"', '', '' ), + '"\\"' => array( '"\\"', '"', '' ), + '"missing close' => array( '"missing close', 'missing close', '' ), + // Invalid 'Invalid: (empty string)' => array( '' ), - "Invalid: 'newline\\n'" => array( "'newline\n'" ), - 'Invalid: foo' => array( 'foo' ), - 'Invalid: \\"' => array( '\\"' ), 'Invalid: .foo' => array( '.foo' ), 'Invalid: #foo' => array( '#foo' ), + "Invalid: 'newline\\n'" => array( "'newline\n'" ), + 'Invalid: foo' => array( 'foo' ), ); } From 81c67582deef44766e188482586538cdbe84272d Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 5 Dec 2024 22:17:11 +0100 Subject: [PATCH 094/634] Update attribute selector tests --- .../html-api/wpCssCompoundSelectorList.php | 82 ++++++++++--------- 1 file changed, 45 insertions(+), 37 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php index 715e0e26bc9cd..6d1b142c17ea9 100644 --- a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php +++ b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php @@ -331,45 +331,53 @@ public function test_parse_attribute( */ public static function data_attribute_selectors(): array { return array( - '[href]' => array( '[href]', 'href', null, null, null, '' ), - '[href] type' => array( '[href] type', 'href', null, null, null, ' type' ), - '[href]#id' => array( '[href]#id', 'href', null, null, null, '#id' ), - '[href].class' => array( '[href].class', 'href', null, null, null, '.class' ), - '[href][href2]' => array( '[href][href2]', 'href', null, null, null, '[href2]' ), - '[\n href\t\r]' => array( "[\n href\t\r]", 'href', null, null, null, '' ), - '[href=foo]' => array( '[href=foo]', 'href', WP_CSS_Attribute_Selector::MATCH_EXACT, 'foo', null, '' ), - '[href \n = bar ]' => array( "[href \n = bar ]", 'href', WP_CSS_Attribute_Selector::MATCH_EXACT, 'bar', null, '' ), - '[href \n ^= baz ]' => array( "[href \n ^= baz ]", 'href', WP_CSS_Attribute_Selector::MATCH_PREFIXED_BY, 'baz', null, '' ), - - '[match $= insensitive i]' => array( '[match $= insensitive i]', 'match', WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY, 'insensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), - '[match|=sensitive s]' => array( '[match|=sensitive s]', 'match', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'sensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), - '[att=val I]' => array( '[att=val I]', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'val', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), - '[att=val S]' => array( '[att=val S]', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'val', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), - - '[match~="quoted[][]"]' => array( '[match~="quoted[][]"]', 'match', WP_CSS_Attribute_Selector::MATCH_ONE_OF_EXACT, 'quoted[][]', null, '' ), - "[match$='quoted!{}']" => array( "[match$='quoted!{}']", 'match', WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY, 'quoted!{}', null, '' ), - "[match*='quoted's]" => array( "[match*='quoted's]", 'match', WP_CSS_Attribute_Selector::MATCH_CONTAINS, 'quoted', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), - - '[escape-nl="foo\\nbar"]' => array( "[escape-nl='foo\\\nbar']", 'escape-nl', WP_CSS_Attribute_Selector::MATCH_EXACT, 'foobar', null, '' ), - '[escape-seq="\\31 23"]' => array( "[escape-seq='\\31 23']", 'escape-seq', WP_CSS_Attribute_Selector::MATCH_EXACT, '123', null, '' ), + '[href]' => array( '[href]', 'href', null, null, null, '' ), + '[href] type' => array( '[href] type', 'href', null, null, null, ' type' ), + '[href]#id' => array( '[href]#id', 'href', null, null, null, '#id' ), + '[href].class' => array( '[href].class', 'href', null, null, null, '.class' ), + '[href][href2]' => array( '[href][href2]', 'href', null, null, null, '[href2]' ), + '[\n href\t\r]' => array( "[\n href\t\r]", 'href', null, null, null, '' ), + '[href=foo]' => array( '[href=foo]', 'href', WP_CSS_Attribute_Selector::MATCH_EXACT, 'foo', null, '' ), + '[href \n = bar ]' => array( "[href \n = bar ]", 'href', WP_CSS_Attribute_Selector::MATCH_EXACT, 'bar', null, '' ), + '[href \n ^= baz ]' => array( "[href \n ^= baz ]", 'href', WP_CSS_Attribute_Selector::MATCH_PREFIXED_BY, 'baz', null, '' ), + + '[match $= insensitive i]' => array( '[match $= insensitive i]', 'match', WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY, 'insensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), + '[match|=sensitive s]' => array( '[match|=sensitive s]', 'match', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'sensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), + '[att=val I]' => array( '[att=val I]', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'val', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), + '[att=val S]' => array( '[att=val S]', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'val', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), + + '[match~="quoted[][]"]' => array( '[match~="quoted[][]"]', 'match', WP_CSS_Attribute_Selector::MATCH_ONE_OF_EXACT, 'quoted[][]', null, '' ), + "[match$='quoted!{}']" => array( "[match$='quoted!{}']", 'match', WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY, 'quoted!{}', null, '' ), + "[match*='quoted's]" => array( "[match*='quoted's]", 'match', WP_CSS_Attribute_Selector::MATCH_CONTAINS, 'quoted', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), + + '[escape-nl="foo\\nbar"]' => array( "[escape-nl='foo\\\nbar']", 'escape-nl', WP_CSS_Attribute_Selector::MATCH_EXACT, 'foobar', null, '' ), + '[escape-seq="\\31 23"]' => array( "[escape-seq='\\31 23']", 'escape-seq', WP_CSS_Attribute_Selector::MATCH_EXACT, '123', null, '' ), + + 'Unterminated: [att' => array( '[att', 'att', null, null, null, '' ), + 'Unterminated: [att="' => array( '[att="', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, '', null, '' ), + 'Unterminated: [att="\\"' => array( '[att="\\"', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, '"', null, '' ), + 'Unterminated: [att="x"' => array( '[att="x"', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'x', null, '' ), + 'Unterminated: [att="x\\"i]' => array( '[att="x\\"i]', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'x"i]', null, '' ), + 'Unterminated: [att="x" i' => array( '[att="x" i', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'x', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), + 'Unterminated: [att = x i' => array( '[att = x i', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'x', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), // Invalid - 'Invalid: (empty string)' => array( '' ), - 'Invalid: foo' => array( 'foo' ), - 'Invalid: [foo' => array( '[foo' ), - 'Invalid: [#foo]' => array( '[#foo]' ), - 'Invalid: [*|*]' => array( '[*|*]' ), - 'Invalid: [ns|*]' => array( '[ns|*]' ), - 'Invalid: [* |att]' => array( '[* |att]' ), - 'Invalid: [*| att]' => array( '[*| att]' ), - 'Invalid: [att * =]' => array( '[att * =]' ), - 'Invalid: [att+=val]' => array( '[att+=val]' ), - 'Invalid: [att=val ' => array( '[att=val ' ), - 'Invalid: [att i]' => array( '[att i]' ), - 'Invalid: [att s]' => array( '[att s]' ), - "Invalid: [att='val\\n']" => array( "[att='val\n']" ), - 'Invalid: [att=val i ' => array( '[att=val i ' ), - 'Invalid: [att="val"ix' => array( '[att="val"ix' ), + 'Invalid: (empty string)' => array( '' ), + 'Invalid: foo' => array( 'foo' ), + 'Invalid: [foo' => array( '[foo' ), + 'Invalid: [#foo]' => array( '[#foo]' ), + 'Invalid: [*|*]' => array( '[*|*]' ), + 'Invalid: [ns|*]' => array( '[ns|*]' ), + 'Invalid: [* |att]' => array( '[* |att]' ), + 'Invalid: [*| att]' => array( '[*| att]' ), + 'Invalid: [att * =]' => array( '[att * =]' ), + 'Invalid: [att+=val]' => array( '[att+=val]' ), + 'Invalid: [att=val ' => array( '[att=val ' ), + 'Invalid: [att i]' => array( '[att i]' ), + 'Invalid: [att s]' => array( '[att s]' ), + "Invalid: [att='val\\n']" => array( "[att='val\n']" ), + 'Invalid: [att=val i ' => array( '[att=val i ' ), + 'Invalid: [att="val"ix' => array( '[att="val"ix' ), ); } From 7bccf3eada582c8b66ec24781dc151a1afbfe9b6 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 5 Dec 2024 22:36:26 +0100 Subject: [PATCH 095/634] Revert "Update attribute selector tests" This reverts commit 7df9ed91a1360d80c1dcb87980af941010b926ba. --- .../html-api/wpCssCompoundSelectorList.php | 82 +++++++++---------- 1 file changed, 37 insertions(+), 45 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php index 6d1b142c17ea9..715e0e26bc9cd 100644 --- a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php +++ b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php @@ -331,53 +331,45 @@ public function test_parse_attribute( */ public static function data_attribute_selectors(): array { return array( - '[href]' => array( '[href]', 'href', null, null, null, '' ), - '[href] type' => array( '[href] type', 'href', null, null, null, ' type' ), - '[href]#id' => array( '[href]#id', 'href', null, null, null, '#id' ), - '[href].class' => array( '[href].class', 'href', null, null, null, '.class' ), - '[href][href2]' => array( '[href][href2]', 'href', null, null, null, '[href2]' ), - '[\n href\t\r]' => array( "[\n href\t\r]", 'href', null, null, null, '' ), - '[href=foo]' => array( '[href=foo]', 'href', WP_CSS_Attribute_Selector::MATCH_EXACT, 'foo', null, '' ), - '[href \n = bar ]' => array( "[href \n = bar ]", 'href', WP_CSS_Attribute_Selector::MATCH_EXACT, 'bar', null, '' ), - '[href \n ^= baz ]' => array( "[href \n ^= baz ]", 'href', WP_CSS_Attribute_Selector::MATCH_PREFIXED_BY, 'baz', null, '' ), - - '[match $= insensitive i]' => array( '[match $= insensitive i]', 'match', WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY, 'insensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), - '[match|=sensitive s]' => array( '[match|=sensitive s]', 'match', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'sensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), - '[att=val I]' => array( '[att=val I]', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'val', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), - '[att=val S]' => array( '[att=val S]', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'val', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), - - '[match~="quoted[][]"]' => array( '[match~="quoted[][]"]', 'match', WP_CSS_Attribute_Selector::MATCH_ONE_OF_EXACT, 'quoted[][]', null, '' ), - "[match$='quoted!{}']" => array( "[match$='quoted!{}']", 'match', WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY, 'quoted!{}', null, '' ), - "[match*='quoted's]" => array( "[match*='quoted's]", 'match', WP_CSS_Attribute_Selector::MATCH_CONTAINS, 'quoted', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), - - '[escape-nl="foo\\nbar"]' => array( "[escape-nl='foo\\\nbar']", 'escape-nl', WP_CSS_Attribute_Selector::MATCH_EXACT, 'foobar', null, '' ), - '[escape-seq="\\31 23"]' => array( "[escape-seq='\\31 23']", 'escape-seq', WP_CSS_Attribute_Selector::MATCH_EXACT, '123', null, '' ), - - 'Unterminated: [att' => array( '[att', 'att', null, null, null, '' ), - 'Unterminated: [att="' => array( '[att="', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, '', null, '' ), - 'Unterminated: [att="\\"' => array( '[att="\\"', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, '"', null, '' ), - 'Unterminated: [att="x"' => array( '[att="x"', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'x', null, '' ), - 'Unterminated: [att="x\\"i]' => array( '[att="x\\"i]', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'x"i]', null, '' ), - 'Unterminated: [att="x" i' => array( '[att="x" i', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'x', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), - 'Unterminated: [att = x i' => array( '[att = x i', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'x', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), + '[href]' => array( '[href]', 'href', null, null, null, '' ), + '[href] type' => array( '[href] type', 'href', null, null, null, ' type' ), + '[href]#id' => array( '[href]#id', 'href', null, null, null, '#id' ), + '[href].class' => array( '[href].class', 'href', null, null, null, '.class' ), + '[href][href2]' => array( '[href][href2]', 'href', null, null, null, '[href2]' ), + '[\n href\t\r]' => array( "[\n href\t\r]", 'href', null, null, null, '' ), + '[href=foo]' => array( '[href=foo]', 'href', WP_CSS_Attribute_Selector::MATCH_EXACT, 'foo', null, '' ), + '[href \n = bar ]' => array( "[href \n = bar ]", 'href', WP_CSS_Attribute_Selector::MATCH_EXACT, 'bar', null, '' ), + '[href \n ^= baz ]' => array( "[href \n ^= baz ]", 'href', WP_CSS_Attribute_Selector::MATCH_PREFIXED_BY, 'baz', null, '' ), + + '[match $= insensitive i]' => array( '[match $= insensitive i]', 'match', WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY, 'insensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), + '[match|=sensitive s]' => array( '[match|=sensitive s]', 'match', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'sensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), + '[att=val I]' => array( '[att=val I]', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'val', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), + '[att=val S]' => array( '[att=val S]', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'val', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), + + '[match~="quoted[][]"]' => array( '[match~="quoted[][]"]', 'match', WP_CSS_Attribute_Selector::MATCH_ONE_OF_EXACT, 'quoted[][]', null, '' ), + "[match$='quoted!{}']" => array( "[match$='quoted!{}']", 'match', WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY, 'quoted!{}', null, '' ), + "[match*='quoted's]" => array( "[match*='quoted's]", 'match', WP_CSS_Attribute_Selector::MATCH_CONTAINS, 'quoted', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), + + '[escape-nl="foo\\nbar"]' => array( "[escape-nl='foo\\\nbar']", 'escape-nl', WP_CSS_Attribute_Selector::MATCH_EXACT, 'foobar', null, '' ), + '[escape-seq="\\31 23"]' => array( "[escape-seq='\\31 23']", 'escape-seq', WP_CSS_Attribute_Selector::MATCH_EXACT, '123', null, '' ), // Invalid - 'Invalid: (empty string)' => array( '' ), - 'Invalid: foo' => array( 'foo' ), - 'Invalid: [foo' => array( '[foo' ), - 'Invalid: [#foo]' => array( '[#foo]' ), - 'Invalid: [*|*]' => array( '[*|*]' ), - 'Invalid: [ns|*]' => array( '[ns|*]' ), - 'Invalid: [* |att]' => array( '[* |att]' ), - 'Invalid: [*| att]' => array( '[*| att]' ), - 'Invalid: [att * =]' => array( '[att * =]' ), - 'Invalid: [att+=val]' => array( '[att+=val]' ), - 'Invalid: [att=val ' => array( '[att=val ' ), - 'Invalid: [att i]' => array( '[att i]' ), - 'Invalid: [att s]' => array( '[att s]' ), - "Invalid: [att='val\\n']" => array( "[att='val\n']" ), - 'Invalid: [att=val i ' => array( '[att=val i ' ), - 'Invalid: [att="val"ix' => array( '[att="val"ix' ), + 'Invalid: (empty string)' => array( '' ), + 'Invalid: foo' => array( 'foo' ), + 'Invalid: [foo' => array( '[foo' ), + 'Invalid: [#foo]' => array( '[#foo]' ), + 'Invalid: [*|*]' => array( '[*|*]' ), + 'Invalid: [ns|*]' => array( '[ns|*]' ), + 'Invalid: [* |att]' => array( '[* |att]' ), + 'Invalid: [*| att]' => array( '[*| att]' ), + 'Invalid: [att * =]' => array( '[att * =]' ), + 'Invalid: [att+=val]' => array( '[att+=val]' ), + 'Invalid: [att=val ' => array( '[att=val ' ), + 'Invalid: [att i]' => array( '[att i]' ), + 'Invalid: [att s]' => array( '[att s]' ), + "Invalid: [att='val\\n']" => array( "[att='val\n']" ), + 'Invalid: [att=val i ' => array( '[att=val i ' ), + 'Invalid: [att="val"ix' => array( '[att="val"ix' ), ); } From 3949cc53b4bebdc8324a07a8ce49bd6ede291e53 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 5 Dec 2024 22:51:04 +0100 Subject: [PATCH 096/634] Improve some complex selector match tests --- .../tests/html-api/wpHtmlProcessor-select.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php index 40e1d96978afe..d94190ff91077 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php @@ -43,16 +43,18 @@ public function test_select_all( string $html, string $selector, int $match_coun /** * Data provider. * - * Most selectors are covered by the tag processor selector tests. - * This suite should focus on complex selectors. - * * @return array */ public static function data_selectors(): array { return array( - 'any descendant' => array( '

', 'section *', 4 ), - 'any child 1' => array( '

', 'section > *', 2 ), - 'any child 2' => array( '

', 'div > *', 1 ), + 'any' => array( '

', '*', 5 ), + 'quirks mode ID' => array( '

In quirks mode, ID matching is case-insensitive.', '#id', 2 ), + 'quirks mode class' => array( '

In quirks mode, class matching is case-insensitive.', '.c', 2 ), + 'no-quirks mode ID' => array( '

In no-quirks mode, ID matching is case-sensitive.', '#id', 1 ), + 'no-quirks mode class' => array( '

In no-quirks mode, class matching is case-sensitive.', '.c', 1 ), + 'any descendant' => array( '

', 'section *', 4 ), + 'any child 1' => array( '

', 'section > *', 2 ), + 'any child 2' => array( '

', 'div > *', 1 ), ); } From c696889197fab2308490cab7b47bf654eed63a61 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 9 Dec 2024 15:45:55 +0100 Subject: [PATCH 097/634] Add and use matches_tag type selector method --- .../html-api/class-wp-css-complex-selector.php | 4 ++-- src/wp-includes/html-api/class-wp-css-type-selector.php | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector.php b/src/wp-includes/html-api/class-wp-css-complex-selector.php index a4cfd46622560..a532e87ecc15d 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector.php @@ -43,7 +43,7 @@ private function explore_matches( array $selectors, array $breadcrumbs ): bool { switch ( $combinator ) { case self::COMBINATOR_CHILD: - if ( '*' === $selector->type_selector->ident || strcasecmp( $breadcrumbs[0], $selector->type_selector->ident ) === 0 ) { + if ( $selector->type_selector->matches_tag( $breadcrumbs[0] ) ) { return $this->explore_matches( array_slice( $selectors, 2 ), array_slice( $breadcrumbs, 1 ) ); } return false; @@ -51,7 +51,7 @@ private function explore_matches( array $selectors, array $breadcrumbs ): bool { case self::COMBINATOR_DESCENDANT: // Find _all_ the breadcrumbs that match and recurse from each of them. for ( $i = 0; $i < count( $breadcrumbs ); $i++ ) { - if ( '*' === $selector->type_selector->ident || strcasecmp( $breadcrumbs[ $i ], $selector->type_selector->ident ) === 0 ) { + if ( $selector->type_selector->matches_tag( $breadcrumbs[ $i ] ) ) { $next_crumbs = array_slice( $breadcrumbs, $i + 1 ); if ( $this->explore_matches( array_slice( $selectors, 2 ), $next_crumbs ) ) { return true; diff --git a/src/wp-includes/html-api/class-wp-css-type-selector.php b/src/wp-includes/html-api/class-wp-css-type-selector.php index c65adce14047d..2a6bb952f5448 100644 --- a/src/wp-includes/html-api/class-wp-css-type-selector.php +++ b/src/wp-includes/html-api/class-wp-css-type-selector.php @@ -6,6 +6,14 @@ public function matches( WP_HTML_Tag_Processor $processor ): bool { if ( null === $tag_name ) { return false; } + return $this->matches_tag( $tag_name ); + } + + /** + * @param string $tag_name + * @return bool + */ + public function matches_tag( string $tag_name ): bool { if ( '*' === $this->ident ) { return true; } From c19355151ee667b055d3414c9272907e37069b82 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 9 Dec 2024 16:00:36 +0100 Subject: [PATCH 098/634] Improve complex selector structure Separate the self selector from relative selectors --- .../class-wp-css-complex-selector-list.php | 50 ++++---- .../class-wp-css-complex-selector.php | 110 ++++++++++++------ .../class-wp-css-compound-selector.php | 2 +- .../html-api/wpCssComplexSelectorList.php | 25 ++-- .../tests/html-api/wpHtmlProcessor-select.php | 17 +-- 5 files changed, 123 insertions(+), 81 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php index 0413b8dea426a..4a9fc03f582f8 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php @@ -95,16 +95,18 @@ final protected static function parse_complex_selector( string $input, int &$off } $updated_offset = $offset; - $selector = self::parse_compound_selector( $input, $updated_offset ); - if ( null === $selector ) { + $self_selector = self::parse_compound_selector( $input, $updated_offset ); + if ( null === $self_selector ) { return null; } - - $selectors = array( $selector ); - $has_preceding_subclass_selector = null !== $selector->subclass_selectors; + /** @var array{WP_CSS_Compound_Selector, string}[] */ + $selectors = array(); $found_whitespace = self::parse_whitespace( $input, $updated_offset ); while ( $updated_offset < strlen( $input ) ) { + $combinator = null; + $next_selector = null; + if ( WP_CSS_Complex_Selector::COMBINATOR_CHILD === $input[ $updated_offset ] || WP_CSS_Complex_Selector::COMBINATOR_NEXT_SIBLING === $input[ $updated_offset ] || @@ -114,42 +116,40 @@ final protected static function parse_complex_selector( string $input, int &$off ++$updated_offset; self::parse_whitespace( $input, $updated_offset ); - // Failure to find a selector here is a parse error - $selector = self::parse_compound_selector( $input, $updated_offset ); + // A combinator has been found, failure to find a selector here is a parse error. + $next_selector = self::parse_compound_selector( $input, $updated_offset ); + if ( null === $next_selector ) { + return null; + } } elseif ( $found_whitespace ) { /* * Whitespace is ambiguous, it could be a descendant combinator or * insignificant whitespace. */ - $selector = self::parse_compound_selector( $input, $updated_offset ); - if ( null === $selector ) { - break; + $next_selector = self::parse_compound_selector( $input, $updated_offset ); + if ( null !== $next_selector ) { + $combinator = WP_CSS_Complex_Selector::COMBINATOR_DESCENDANT; } - $combinator = WP_CSS_Complex_Selector::COMBINATOR_DESCENDANT; - } else { - break; } - if ( null === $selector ) { - return null; + if ( null === $next_selector ) { + break; } - /* - * Subclass selectors in non-final position is not supported: - * - `div > .className` is valid - * - `.className > div` is not - */ - if ( $has_preceding_subclass_selector ) { + // $self_selector will pass to a relative selector where only the type selector is allowed. + if ( null !== $self_selector->subclass_selectors || null === $self_selector->type_selector ) { return null; } - $has_preceding_subclass_selector = null !== $selector->subclass_selectors; - $selectors[] = $combinator; - $selectors[] = $selector; + /** @var array{WP_CSS_Compound_Selector, string} */ + $selector_pair = array( $self_selector->type_selector, $combinator ); + $selectors[] = $selector_pair; + $self_selector = $next_selector; $found_whitespace = self::parse_whitespace( $input, $updated_offset ); } $offset = $updated_offset; - return new WP_CSS_Complex_Selector( $selectors ); + + return new WP_CSS_Complex_Selector( $self_selector, array_reverse( $selectors ) ); } } diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector.php b/src/wp-includes/html-api/class-wp-css-complex-selector.php index a532e87ecc15d..9db2912d3ac16 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector.php @@ -6,26 +6,87 @@ * > = [ ? ] * */ final class WP_CSS_Complex_Selector implements WP_CSS_HTML_Processor_Matcher { + const COMBINATOR_CHILD = '>'; + const COMBINATOR_DESCENDANT = ' '; + const COMBINATOR_NEXT_SIBLING = '+'; + const COMBINATOR_SUBSEQUENT_SIBLING = '~'; + + /** + * This is the selector in the final position of the complex selector. This corresponds to the + * selected element. + * + * @example + * + * $self_selector + * ┏━━━━┻━━━━┓ + * .heading h1 > el.selected + * + * @readonly + * @var WP_CSS_Compound_Selector + */ + public $self_selector; + + /** + * This is the selector in the final position of the complex selector. This corresponds to the + * selected element. + * + * @example + * + * $relative_selectors + * ┏━━━━━━┻━━━━┓ + * .heading h1 > el.selected + * + * The example would have the following relative selectors (note that the order is reversed): + * + * @example + * + * array ( + * array( + * WP_CSS_Type_Selector( 'ident' => 'h1' ), + * '>', // WP_CSS_Complex_Selector::COMBINATOR_CHILD + * ), + * array( + * new WP_CSS_Type_Selector( 'header' ), + * ' ', // WP_CSS_Complex_Selector::COMBINATOR_DESCENDANT + * ), + * ) + * + * @readonly + * @var array{WP_CSS_Type_Selector, string}[] + */ + public $relative_selectors; + + /** + * @param WP_CSS_Compound_Selector $self_selector + * @param array{WP_CSS_Type_Selector, string}[] $selectors + */ + public function __construct( + WP_CSS_Compound_Selector $self_selector, + ?array $relative_selectors + ) { + $this->self_selector = $self_selector; + $this->relative_selectors = $relative_selectors; + } + public function matches( WP_HTML_Processor $processor ): bool { // First selector must match this location. - if ( ! $this->selectors[0]->matches( $processor ) ) { + if ( ! $this->self_selector->matches( $processor ) ) { return false; } - if ( count( $this->selectors ) === 1 ) { + if ( null === $this->relative_selectors || array() === $this->relative_selectors ) { return true; } /** @var string[] */ $breadcrumbs = array_slice( array_reverse( $processor->get_breadcrumbs() ), 1 ); - $selectors = array_slice( $this->selectors, 1 ); - return $this->explore_matches( $selectors, $breadcrumbs ); + return $this->explore_matches( $this->relative_selectors, $breadcrumbs ); } /** * This only looks at breadcrumbs and can therefore only support type selectors. * - * @param array $selectors + * @param array{WP_CSS_Type_Selector, string}[] $selectors * @param string[] $breadcrumbs */ private function explore_matches( array $selectors, array $breadcrumbs ): bool { @@ -36,24 +97,22 @@ private function explore_matches( array $selectors, array $breadcrumbs ): bool { return false; } - /** @var self::COMBINATOR_* */ - $combinator = $selectors[0]; - /** @var WP_CSS_Compound_Selector */ - $selector = $selectors[1]; + $selector = $selectors[0][0]; + $combinator = $selectors[0][1]; switch ( $combinator ) { case self::COMBINATOR_CHILD: - if ( $selector->type_selector->matches_tag( $breadcrumbs[0] ) ) { - return $this->explore_matches( array_slice( $selectors, 2 ), array_slice( $breadcrumbs, 1 ) ); + if ( $selector->matches_tag( $breadcrumbs[0] ) ) { + return $this->explore_matches( array_slice( $selectors, 1 ), array_slice( $breadcrumbs, 1 ) ); } return false; case self::COMBINATOR_DESCENDANT: // Find _all_ the breadcrumbs that match and recurse from each of them. for ( $i = 0; $i < count( $breadcrumbs ); $i++ ) { - if ( $selector->type_selector->matches_tag( $breadcrumbs[ $i ] ) ) { - $next_crumbs = array_slice( $breadcrumbs, $i + 1 ); - if ( $this->explore_matches( array_slice( $selectors, 2 ), $next_crumbs ) ) { + if ( $selector->matches_tag( $breadcrumbs[ $i ] ) ) { + $next_breadcrumbs = array_slice( $breadcrumbs, $i + 1 ); + if ( $this->explore_matches( array_slice( $selectors, 1 ), $next_breadcrumbs ) ) { return true; } } @@ -61,28 +120,7 @@ private function explore_matches( array $selectors, array $breadcrumbs ): bool { return false; default: - throw new Exception( "Combinator '{$combinator}' is not supported yet." ); + throw new Exception( "Unsupported combinator '{$combinator}' found." ); } } - - const COMBINATOR_CHILD = '>'; - const COMBINATOR_DESCENDANT = ' '; - const COMBINATOR_NEXT_SIBLING = '+'; - const COMBINATOR_SUBSEQUENT_SIBLING = '~'; - - /** - * even indexes are WP_CSS_Compound_Selector, odd indexes are string combinators. - * In reverse order to match the current element and then work up the tree. - * Any non-final selector is a type selector. - * - * @var array - */ - public $selectors = array(); - - /** - * @param array $selectors - */ - public function __construct( array $selectors ) { - $this->selectors = array_reverse( $selectors ); - } } diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector.php b/src/wp-includes/html-api/class-wp-css-compound-selector.php index e64695abe9ab3..2ef2051880936 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector.php @@ -25,7 +25,7 @@ public function matches( WP_HTML_Tag_Processor $processor ): bool { /** @var WP_CSS_Type_Selector|null */ public $type_selector; - /** @var array|null */ + /** @var (WP_CSS_ID_Selector|WP_CSS_Class_Selector|WP_CSS_Attribute_Selector)[]|null */ public $subclass_selectors; /** diff --git a/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php b/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php index 0b17e57847662..795e230033cdb 100644 --- a/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php +++ b/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php @@ -20,7 +20,7 @@ public function __construct() { parent::__construct( array() ); } - public static function test_parse_complex_selector( string $input, int &$offset ) { + public static function test_parse_complex_selector( string $input, int &$offset ): ?WP_CSS_Complex_Selector { return self::parse_complex_selector( $input, $offset ); } }; @@ -30,21 +30,24 @@ public static function test_parse_complex_selector( string $input, int &$offset * @ticket 62653 */ public function test_parse_complex_selector() { - $input = 'el1 > .child#bar[baz=quux] , rest'; + $input = 'el1 el2 > .child#bar[baz=quux] , rest'; $offset = 0; - $sel = $this->test_class::test_parse_complex_selector( $input, $offset ); - $this->assertSame( 3, count( $sel->selectors ) ); + /** @var WP_CSS_Complex_Selector|null */ + $sel = $this->test_class::test_parse_complex_selector( $input, $offset ); - $this->assertSame( 'el1', $sel->selectors[2]->type_selector->ident ); - $this->assertNull( $sel->selectors[2]->subclass_selectors ); + $this->assertSame( 2, count( $sel->relative_selectors ) ); - $this->assertSame( WP_CSS_Complex_Selector::COMBINATOR_CHILD, $sel->selectors[1] ); + // Relative selectors should be reverse ordered. + $this->assertSame( 'el2', $sel->relative_selectors[0][0]->ident ); + $this->assertSame( WP_CSS_Complex_Selector::COMBINATOR_CHILD, $sel->relative_selectors[0][1] ); - $this->assertSame( 3, count( $sel->selectors[0]->subclass_selectors ) ); - $this->assertNull( $sel->selectors[0]->type_selector ); - $this->assertSame( 3, count( $sel->selectors[0]->subclass_selectors ) ); - $this->assertSame( 'child', $sel->selectors[0]->subclass_selectors[0]->ident ); + $this->assertSame( 'el1', $sel->relative_selectors[1][0]->ident ); + $this->assertSame( WP_CSS_Complex_Selector::COMBINATOR_DESCENDANT, $sel->relative_selectors[1][1] ); + + $this->assertSame( 3, count( $sel->self_selector->subclass_selectors ) ); + $this->assertNull( $sel->self_selector->type_selector ); + $this->assertSame( 'child', $sel->self_selector->subclass_selectors[0]->ident ); $this->assertSame( ', rest', substr( $input, $offset ) ); } diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php index d94190ff91077..21828faf42e80 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php @@ -47,14 +47,15 @@ public function test_select_all( string $html, string $selector, int $match_coun */ public static function data_selectors(): array { return array( - 'any' => array( '

', '*', 5 ), - 'quirks mode ID' => array( '

In quirks mode, ID matching is case-insensitive.', '#id', 2 ), - 'quirks mode class' => array( '

In quirks mode, class matching is case-insensitive.', '.c', 2 ), - 'no-quirks mode ID' => array( '

In no-quirks mode, ID matching is case-sensitive.', '#id', 1 ), - 'no-quirks mode class' => array( '

In no-quirks mode, class matching is case-sensitive.', '.c', 1 ), - 'any descendant' => array( '

', 'section *', 4 ), - 'any child 1' => array( '

', 'section > *', 2 ), - 'any child 2' => array( '

', 'div > *', 1 ), + 'any' => array( '

', '*', 5 ), + 'quirks mode ID' => array( '

In quirks mode, ID matching is case-insensitive.', '#id', 2 ), + 'quirks mode class' => array( '

In quirks mode, class matching is case-insensitive.', '.c', 2 ), + 'no-quirks mode ID' => array( '

In no-quirks mode, ID matching is case-sensitive.', '#id', 1 ), + 'no-quirks mode class' => array( '

In no-quirks mode, class matching is case-sensitive.', '.c', 1 ), + 'any descendant' => array( '

', 'section *', 4 ), + 'any child matches all children' => array( '

', 'section > *', 2 ), + + 'multiple complex selectors' => array( '

', 'section > div p > i', 1 ), ); } From 9dd811432a685b4efa15692a9d5d5dae43b475c0 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 9 Dec 2024 16:10:05 +0100 Subject: [PATCH 099/634] Rework structure of complex_selector class --- .../class-wp-css-complex-selector.php | 32 ++++++++++++------- .../html-api/wpCssComplexSelectorList.php | 10 +++--- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector.php b/src/wp-includes/html-api/class-wp-css-complex-selector.php index 9db2912d3ac16..1f03f133c8806 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector.php @@ -12,7 +12,7 @@ final class WP_CSS_Complex_Selector implements WP_CSS_HTML_Processor_Matcher { const COMBINATOR_SUBSEQUENT_SIBLING = '~'; /** - * This is the selector in the final position of the complex selector. This corresponds to the + * The "self selector" is the last element in a complex selector, it corresponds to the * selected element. * * @example @@ -27,12 +27,20 @@ final class WP_CSS_Complex_Selector implements WP_CSS_HTML_Processor_Matcher { public $self_selector; /** - * This is the selector in the final position of the complex selector. This corresponds to the - * selected element. + * The "context selectors" are zero or more elements that provide additional constraints for + * the "self selector." + * + * In this example selector, and element like `` is selected iff: + * - it is a child of an `H1` element + * - *and* that `H1` element is a descendant of a `HEADING` element. + * + * The `H1` and `HEADING` parts of this selector are the "context selectors." Note that this + * terminology is used for purposes of this class but does not correspond to language in the + * CSS or selector specifications. * * @example * - * $relative_selectors + * $context_selectors * ┏━━━━━━┻━━━━┓ * .heading h1 > el.selected * @@ -52,20 +60,20 @@ final class WP_CSS_Complex_Selector implements WP_CSS_HTML_Processor_Matcher { * ) * * @readonly - * @var array{WP_CSS_Type_Selector, string}[] + * @var array{WP_CSS_Type_Selector, string}[]|null */ - public $relative_selectors; + public $context_selectors; /** * @param WP_CSS_Compound_Selector $self_selector - * @param array{WP_CSS_Type_Selector, string}[] $selectors + * @param array{WP_CSS_Type_Selector, string}[]|null $selectors */ public function __construct( WP_CSS_Compound_Selector $self_selector, - ?array $relative_selectors + ?array $context_selectors ) { - $this->self_selector = $self_selector; - $this->relative_selectors = $relative_selectors; + $this->self_selector = $self_selector; + $this->context_selectors = $context_selectors; } public function matches( WP_HTML_Processor $processor ): bool { @@ -74,13 +82,13 @@ public function matches( WP_HTML_Processor $processor ): bool { return false; } - if ( null === $this->relative_selectors || array() === $this->relative_selectors ) { + if ( null === $this->context_selectors || array() === $this->context_selectors ) { return true; } /** @var string[] */ $breadcrumbs = array_slice( array_reverse( $processor->get_breadcrumbs() ), 1 ); - return $this->explore_matches( $this->relative_selectors, $breadcrumbs ); + return $this->explore_matches( $this->context_selectors, $breadcrumbs ); } /** diff --git a/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php b/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php index 795e230033cdb..dc89869ea2e66 100644 --- a/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php +++ b/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php @@ -36,14 +36,14 @@ public function test_parse_complex_selector() { /** @var WP_CSS_Complex_Selector|null */ $sel = $this->test_class::test_parse_complex_selector( $input, $offset ); - $this->assertSame( 2, count( $sel->relative_selectors ) ); + $this->assertSame( 2, count( $sel->context_selectors ) ); // Relative selectors should be reverse ordered. - $this->assertSame( 'el2', $sel->relative_selectors[0][0]->ident ); - $this->assertSame( WP_CSS_Complex_Selector::COMBINATOR_CHILD, $sel->relative_selectors[0][1] ); + $this->assertSame( 'el2', $sel->context_selectors[0][0]->ident ); + $this->assertSame( WP_CSS_Complex_Selector::COMBINATOR_CHILD, $sel->context_selectors[0][1] ); - $this->assertSame( 'el1', $sel->relative_selectors[1][0]->ident ); - $this->assertSame( WP_CSS_Complex_Selector::COMBINATOR_DESCENDANT, $sel->relative_selectors[1][1] ); + $this->assertSame( 'el1', $sel->context_selectors[1][0]->ident ); + $this->assertSame( WP_CSS_Complex_Selector::COMBINATOR_DESCENDANT, $sel->context_selectors[1][1] ); $this->assertSame( 3, count( $sel->self_selector->subclass_selectors ) ); $this->assertNull( $sel->self_selector->type_selector ); From b134308e4017f53d40d55df4aa0b03842d51974f Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 9 Dec 2024 16:54:08 +0100 Subject: [PATCH 100/634] Improve documentation --- .../html-api/class-wp-css-complex-selector.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector.php b/src/wp-includes/html-api/class-wp-css-complex-selector.php index 1f03f133c8806..2d4d0212b24f2 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector.php @@ -30,7 +30,11 @@ final class WP_CSS_Complex_Selector implements WP_CSS_HTML_Processor_Matcher { * The "context selectors" are zero or more elements that provide additional constraints for * the "self selector." * - * In this example selector, and element like `` is selected iff: + * These selectors are represented as 2-tuples where the element at index 0 is the selector and + * the element at index 1 is the combinator string constant from this class, + * e.g. `WP_CSS_Complex_Selector::COMBINATOR_CHILD`. + * + * In the example selector below, an element like `` is selected iff: * - it is a child of an `H1` element * - *and* that `H1` element is a descendant of a `HEADING` element. * @@ -44,7 +48,7 @@ final class WP_CSS_Complex_Selector implements WP_CSS_HTML_Processor_Matcher { * ┏━━━━━━┻━━━━┓ * .heading h1 > el.selected * - * The example would have the following relative selectors (note that the order is reversed): + * The example would have the following relative selectors: * * @example * @@ -59,6 +63,10 @@ final class WP_CSS_Complex_Selector implements WP_CSS_HTML_Processor_Matcher { * ), * ) * + * Note that the order of context selectors is reversed. This is to match the self selector + * first and then match the context selectors beginning with the selector closest to the self + * selector. + * * @readonly * @var array{WP_CSS_Type_Selector, string}[]|null */ From 94c06ef32fd69eecd7ccddd40714edef1a79f493 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 9 Dec 2024 18:11:55 +0100 Subject: [PATCH 101/634] Document complex selector class --- .../class-wp-css-complex-selector.php | 52 ++++++++++++++++--- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector.php b/src/wp-includes/html-api/class-wp-css-complex-selector.php index 2d4d0212b24f2..bd51884901d93 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector.php @@ -1,14 +1,47 @@ in the grammar. + * CSS complex selector. + * + * This class implements a CSS complex selector and is used to test for matching HTML tags + * in a {@see WP_HTML_Tag_Processor}. + * + * A complex selector is a selector with zero or more combinator-selector pairs. + * + * @since TBD * - * > = [ ? ] * + * @access private */ final class WP_CSS_Complex_Selector implements WP_CSS_HTML_Processor_Matcher { - const COMBINATOR_CHILD = '>'; - const COMBINATOR_DESCENDANT = ' '; - const COMBINATOR_NEXT_SIBLING = '+'; + /** + * Child combinator. + */ + const COMBINATOR_CHILD = '>'; + + /** + * Descendant combinator. + */ + const COMBINATOR_DESCENDANT = ' '; + + /** + * Next sibling combinator. + * + * This combinator is not currently supported. + */ + const COMBINATOR_NEXT_SIBLING = '+'; + + /** + * Subsequent sibling combinator. + * + * This combinator is not currently supported. + */ const COMBINATOR_SUBSEQUENT_SIBLING = '~'; /** @@ -84,6 +117,12 @@ public function __construct( $this->context_selectors = $context_selectors; } + /** + * Determines if the processor's current position matches the selector. + * + * @param WP_HTML_Processor $processor The processor. + * @return bool True if the processor's current position matches the selector. + */ public function matches( WP_HTML_Processor $processor ): bool { // First selector must match this location. if ( ! $this->self_selector->matches( $processor ) ) { @@ -100,10 +139,11 @@ public function matches( WP_HTML_Processor $processor ): bool { } /** - * This only looks at breadcrumbs and can therefore only support type selectors. + * Checks for matches recursively comparing context selectors with breadcrumbs. * * @param array{WP_CSS_Type_Selector, string}[] $selectors * @param string[] $breadcrumbs + * @return bool True if a match is found, otherwise false. */ private function explore_matches( array $selectors, array $breadcrumbs ): bool { if ( array() === $selectors ) { From f46fceda45dd38676191126761fb3c4c4439d0be Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 9 Dec 2024 18:17:39 +0100 Subject: [PATCH 102/634] Document matches functions --- .../html-api/class-wp-css-attribute-selector.php | 2 +- src/wp-includes/html-api/class-wp-css-class-selector.php | 6 ++++++ .../html-api/class-wp-css-compound-selector-list.php | 6 ++++-- src/wp-includes/html-api/class-wp-css-compound-selector.php | 6 ++++++ src/wp-includes/html-api/class-wp-css-id-selector.php | 6 ++++++ src/wp-includes/html-api/class-wp-css-type-selector.php | 6 ++++++ .../html-api/interface-wp-css-html-processor-matcher.php | 5 ++++- .../interface-wp-css-html-tag-processor-matcher.php | 5 ++++- 8 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-attribute-selector.php b/src/wp-includes/html-api/class-wp-css-attribute-selector.php index 7036dd3775cc1..dae71c4295348 100644 --- a/src/wp-includes/html-api/class-wp-css-attribute-selector.php +++ b/src/wp-includes/html-api/class-wp-css-attribute-selector.php @@ -122,7 +122,7 @@ public function __construct( string $name, ?string $matcher = null, ?string $val /** * Determines if the processor's current position matches the selector. * - * @param WP_HTML_Tag_Processor $processor + * @param WP_HTML_Tag_Processor $processor The processor. * @return bool True if the processor's current position matches the selector. */ public function matches( WP_HTML_Tag_Processor $processor ): bool { diff --git a/src/wp-includes/html-api/class-wp-css-class-selector.php b/src/wp-includes/html-api/class-wp-css-class-selector.php index c3e7ced008a6e..c9ab061578025 100644 --- a/src/wp-includes/html-api/class-wp-css-class-selector.php +++ b/src/wp-includes/html-api/class-wp-css-class-selector.php @@ -1,6 +1,12 @@ has_class( $this->ident ); } diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php index 8cca2e27c9ec3..ce116a236e171 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php @@ -78,8 +78,10 @@ */ class WP_CSS_Compound_Selector_List implements WP_CSS_HTML_Tag_Processor_Matcher { /** - * @param WP_HTML_Tag_Processor $processor - * @return bool + * Determines if the processor's current position matches the selector. + * + * @param WP_HTML_Tag_Processor $processor The processor. + * @return bool True if the processor's current position matches the selector. */ public function matches( $processor ): bool { if ( $processor->get_token_type() !== '#tag' ) { diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector.php b/src/wp-includes/html-api/class-wp-css-compound-selector.php index 2ef2051880936..0ae507803c42f 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector.php @@ -6,6 +6,12 @@ * > = [ ? * ]! */ final class WP_CSS_Compound_Selector implements WP_CSS_HTML_Tag_Processor_Matcher { + /** + * Determines if the processor's current position matches the selector. + * + * @param WP_HTML_Tag_Processor $processor The processor. + * @return bool True if the processor's current position matches the selector. + */ public function matches( WP_HTML_Tag_Processor $processor ): bool { if ( $this->type_selector ) { if ( ! $this->type_selector->matches( $processor ) ) { diff --git a/src/wp-includes/html-api/class-wp-css-id-selector.php b/src/wp-includes/html-api/class-wp-css-id-selector.php index 83339ff839317..7e64432430409 100644 --- a/src/wp-includes/html-api/class-wp-css-id-selector.php +++ b/src/wp-includes/html-api/class-wp-css-id-selector.php @@ -8,6 +8,12 @@ public function __construct( string $ident ) { $this->ident = $ident; } + /** + * Determines if the processor's current position matches the selector. + * + * @param WP_HTML_Tag_Processor $processor The processor. + * @return bool True if the processor's current position matches the selector. + */ public function matches( WP_HTML_Tag_Processor $processor ): bool { $id = $processor->get_attribute( 'id' ); if ( ! is_string( $id ) ) { diff --git a/src/wp-includes/html-api/class-wp-css-type-selector.php b/src/wp-includes/html-api/class-wp-css-type-selector.php index 2a6bb952f5448..6bba9f7e2450e 100644 --- a/src/wp-includes/html-api/class-wp-css-type-selector.php +++ b/src/wp-includes/html-api/class-wp-css-type-selector.php @@ -1,6 +1,12 @@ get_tag(); if ( null === $tag_name ) { diff --git a/src/wp-includes/html-api/interface-wp-css-html-processor-matcher.php b/src/wp-includes/html-api/interface-wp-css-html-processor-matcher.php index 2ae29413b35d2..b77ef40931d83 100644 --- a/src/wp-includes/html-api/interface-wp-css-html-processor-matcher.php +++ b/src/wp-includes/html-api/interface-wp-css-html-processor-matcher.php @@ -2,7 +2,10 @@ interface WP_CSS_HTML_Processor_Matcher { /** - * @return bool + * Determines if the processor's current position matches the selector. + * + * @param WP_HTML_Processor $processor The processor. + * @return bool True if the processor's current position matches the selector. */ public function matches( WP_HTML_Processor $processor ): bool; } diff --git a/src/wp-includes/html-api/interface-wp-css-html-tag-processor-matcher.php b/src/wp-includes/html-api/interface-wp-css-html-tag-processor-matcher.php index 73d108150bb95..302ee8972a162 100644 --- a/src/wp-includes/html-api/interface-wp-css-html-tag-processor-matcher.php +++ b/src/wp-includes/html-api/interface-wp-css-html-tag-processor-matcher.php @@ -2,7 +2,10 @@ interface WP_CSS_HTML_Tag_Processor_Matcher { /** - * @return bool + * Determines if the processor's current position matches the selector. + * + * @param WP_HTML_Tag_Processor $processor The processor. + * @return bool True if the processor's current position matches the selector. */ public function matches( WP_HTML_Tag_Processor $processor ): bool; } From 1bacfd71810f4e39bcb5fd0eb83688c82878ea4a Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 9 Dec 2024 18:17:58 +0100 Subject: [PATCH 103/634] Simplify condition in compound::matches --- src/wp-includes/html-api/class-wp-css-compound-selector.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector.php b/src/wp-includes/html-api/class-wp-css-compound-selector.php index 0ae507803c42f..f281146110f30 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector.php @@ -13,10 +13,8 @@ final class WP_CSS_Compound_Selector implements WP_CSS_HTML_Tag_Processor_Matche * @return bool True if the processor's current position matches the selector. */ public function matches( WP_HTML_Tag_Processor $processor ): bool { - if ( $this->type_selector ) { - if ( ! $this->type_selector->matches( $processor ) ) { - return false; - } + if ( $this->type_selector && ! $this->type_selector->matches( $processor ) ) { + return false; } if ( null !== $this->subclass_selectors ) { foreach ( $this->subclass_selectors as $subclass_selector ) { From a274ea0ffaed3785d12909c657b91594b76b13f4 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 9 Dec 2024 18:20:19 +0100 Subject: [PATCH 104/634] Change class require order --- src/wp-settings.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp-settings.php b/src/wp-settings.php index b1f25042aa7d6..b52fe8ab6181c 100644 --- a/src/wp-settings.php +++ b/src/wp-settings.php @@ -267,10 +267,10 @@ require ABSPATH . WPINC . '/html-api/class-wp-html-processor.php'; require ABSPATH . WPINC . '/html-api/interface-wp-css-html-tag-processor-matcher.php'; require ABSPATH . WPINC . '/html-api/interface-wp-css-html-processor-matcher.php'; +require ABSPATH . WPINC . '/html-api/class-wp-css-attribute-selector.php'; +require ABSPATH . WPINC . '/html-api/class-wp-css-class-selector.php'; require ABSPATH . WPINC . '/html-api/class-wp-css-id-selector.php'; require ABSPATH . WPINC . '/html-api/class-wp-css-type-selector.php'; -require ABSPATH . WPINC . '/html-api/class-wp-css-class-selector.php'; -require ABSPATH . WPINC . '/html-api/class-wp-css-attribute-selector.php'; require ABSPATH . WPINC . '/html-api/class-wp-css-compound-selector.php'; require ABSPATH . WPINC . '/html-api/class-wp-css-complex-selector.php'; require ABSPATH . WPINC . '/html-api/class-wp-css-compound-selector-list.php'; From 12a0a99d4c4e7e51fcb18cae4b384dfe41f137a2 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 9 Dec 2024 18:21:12 +0100 Subject: [PATCH 105/634] Annotate matches processor argument type --- .../html-api/class-wp-css-compound-selector-list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php index ce116a236e171..27900d40a238c 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php @@ -83,7 +83,7 @@ class WP_CSS_Compound_Selector_List implements WP_CSS_HTML_Tag_Processor_Matcher * @param WP_HTML_Tag_Processor $processor The processor. * @return bool True if the processor's current position matches the selector. */ - public function matches( $processor ): bool { + public function matches( WP_HTML_Tag_Processor $processor ): bool { if ( $processor->get_token_type() !== '#tag' ) { return false; } From 0e2b34aba90e3dad4354c362efe363ec8bb63532 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 9 Dec 2024 18:28:06 +0100 Subject: [PATCH 106/634] Document class selector and update class_name property --- .../html-api/class-wp-css-class-selector.php | 42 +++++++++++++++---- .../html-api/wpCssComplexSelectorList.php | 2 +- .../html-api/wpCssCompoundSelectorList.php | 4 +- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-class-selector.php b/src/wp-includes/html-api/class-wp-css-class-selector.php index c9ab061578025..cdd38d951e45c 100644 --- a/src/wp-includes/html-api/class-wp-css-class-selector.php +++ b/src/wp-includes/html-api/class-wp-css-class-selector.php @@ -1,6 +1,39 @@ class_name = $class_name; + } + /** * Determines if the processor's current position matches the selector. * @@ -8,13 +41,6 @@ final class WP_CSS_Class_Selector implements WP_CSS_HTML_Tag_Processor_Matcher { * @return bool True if the processor's current position matches the selector. */ public function matches( WP_HTML_Tag_Processor $processor ): bool { - return (bool) $processor->has_class( $this->ident ); - } - - /** @var string */ - public $ident; - - public function __construct( string $ident ) { - $this->ident = $ident; + return (bool) $processor->has_class( $this->class_name ); } } diff --git a/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php b/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php index dc89869ea2e66..1bf77f8c60317 100644 --- a/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php +++ b/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php @@ -47,7 +47,7 @@ public function test_parse_complex_selector() { $this->assertSame( 3, count( $sel->self_selector->subclass_selectors ) ); $this->assertNull( $sel->self_selector->type_selector ); - $this->assertSame( 'child', $sel->self_selector->subclass_selectors[0]->ident ); + $this->assertSame( 'child', $sel->self_selector->subclass_selectors[0]->class_name ); $this->assertSame( ', rest', substr( $input, $offset ) ); } diff --git a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php index 715e0e26bc9cd..fa45ed767d5ca 100644 --- a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php +++ b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php @@ -239,7 +239,7 @@ public function test_parse_class( string $input, ?string $expected = null, ?stri if ( null === $expected ) { $this->assertNull( $result ); } else { - $this->assertSame( $expected, $result->ident ); + $this->assertSame( $expected, $result->class_name ); $this->assertSame( $rest, substr( $input, $offset ) ); } } @@ -383,7 +383,7 @@ public function test_parse_selector() { $this->assertSame( 'el', $sel->type_selector->ident ); $this->assertSame( 3, count( $sel->subclass_selectors ) ); - $this->assertSame( 'foo', $sel->subclass_selectors[0]->ident, 'foo' ); + $this->assertSame( 'foo', $sel->subclass_selectors[0]->class_name, 'foo' ); $this->assertSame( 'bar', $sel->subclass_selectors[1]->ident, 'bar' ); $this->assertSame( 'baz', $sel->subclass_selectors[2]->name, 'baz' ); $this->assertSame( WP_CSS_Attribute_Selector::MATCH_EXACT, $sel->subclass_selectors[2]->matcher ); From dea10291c67b55512658af04bc483385965acc08 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 9 Dec 2024 18:33:24 +0100 Subject: [PATCH 107/634] Document ID selector class, rename id property --- .../html-api/class-wp-css-id-selector.php | 38 ++++++++++++++++--- .../html-api/wpCssCompoundSelectorList.php | 4 +- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-id-selector.php b/src/wp-includes/html-api/class-wp-css-id-selector.php index 7e64432430409..5bb6438df6eb3 100644 --- a/src/wp-includes/html-api/class-wp-css-id-selector.php +++ b/src/wp-includes/html-api/class-wp-css-id-selector.php @@ -1,11 +1,37 @@ ident = $ident; + /** + * Constructor. + * + * @param string $id The ID to match. + */ + public function __construct( string $id ) { + $this->id = $id; } /** @@ -23,7 +49,7 @@ public function matches( WP_HTML_Tag_Processor $processor ): bool { $case_insensitive = $processor->is_quirks_mode(); return $case_insensitive - ? 0 === strcasecmp( $id, $this->ident ) - : $processor->get_attribute( 'id' ) === $this->ident; + ? 0 === strcasecmp( $id, $this->id ) + : $processor->get_attribute( 'id' ) === $this->id; } } diff --git a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php index fa45ed767d5ca..8334ebd5a3a75 100644 --- a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php +++ b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php @@ -205,7 +205,7 @@ public function test_parse_id( string $input, ?string $expected = null, ?string if ( null === $expected ) { $this->assertNull( $result ); } else { - $this->assertSame( $expected, $result->ident ); + $this->assertSame( $expected, $result->id ); $this->assertSame( $rest, substr( $input, $offset ) ); } } @@ -384,7 +384,7 @@ public function test_parse_selector() { $this->assertSame( 'el', $sel->type_selector->ident ); $this->assertSame( 3, count( $sel->subclass_selectors ) ); $this->assertSame( 'foo', $sel->subclass_selectors[0]->class_name, 'foo' ); - $this->assertSame( 'bar', $sel->subclass_selectors[1]->ident, 'bar' ); + $this->assertSame( 'bar', $sel->subclass_selectors[1]->id, 'bar' ); $this->assertSame( 'baz', $sel->subclass_selectors[2]->name, 'baz' ); $this->assertSame( WP_CSS_Attribute_Selector::MATCH_EXACT, $sel->subclass_selectors[2]->matcher ); $this->assertSame( 'quux', $sel->subclass_selectors[2]->value ); From d268f4cfe03a3872865c94b5e03c2e815f106576 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 9 Dec 2024 18:38:47 +0100 Subject: [PATCH 108/634] Document type selector class and rename type property --- .../html-api/class-wp-css-type-selector.php | 49 ++++++++++++++----- .../html-api/wpCssComplexSelectorList.php | 4 +- .../html-api/wpCssCompoundSelectorList.php | 4 +- 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-type-selector.php b/src/wp-includes/html-api/class-wp-css-type-selector.php index 6bba9f7e2450e..66d6a1f2db48f 100644 --- a/src/wp-includes/html-api/class-wp-css-type-selector.php +++ b/src/wp-includes/html-api/class-wp-css-type-selector.php @@ -1,6 +1,38 @@ type = $type; + } + /** * Determines if the processor's current position matches the selector. * @@ -16,24 +48,15 @@ public function matches( WP_HTML_Tag_Processor $processor ): bool { } /** + * Checks whether the selector matches the provided tag name. + * * @param string $tag_name * @return bool */ public function matches_tag( string $tag_name ): bool { - if ( '*' === $this->ident ) { + if ( '*' === $this->type ) { return true; } - return 0 === strcasecmp( $tag_name, $this->ident ); - } - - /** - * @var string - * - * The type identifier string or '*'. - */ - public $ident; - - public function __construct( string $ident ) { - $this->ident = $ident; + return 0 === strcasecmp( $tag_name, $this->type ); } } diff --git a/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php b/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php index 1bf77f8c60317..076d5b6f65ee6 100644 --- a/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php +++ b/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php @@ -39,10 +39,10 @@ public function test_parse_complex_selector() { $this->assertSame( 2, count( $sel->context_selectors ) ); // Relative selectors should be reverse ordered. - $this->assertSame( 'el2', $sel->context_selectors[0][0]->ident ); + $this->assertSame( 'el2', $sel->context_selectors[0][0]->type ); $this->assertSame( WP_CSS_Complex_Selector::COMBINATOR_CHILD, $sel->context_selectors[0][1] ); - $this->assertSame( 'el1', $sel->context_selectors[1][0]->ident ); + $this->assertSame( 'el1', $sel->context_selectors[1][0]->type ); $this->assertSame( WP_CSS_Complex_Selector::COMBINATOR_DESCENDANT, $sel->context_selectors[1][1] ); $this->assertSame( 3, count( $sel->self_selector->subclass_selectors ) ); diff --git a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php index 8334ebd5a3a75..1dfdc79714e2c 100644 --- a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php +++ b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php @@ -273,7 +273,7 @@ public function test_parse_type( string $input, ?string $expected = null, ?strin if ( null === $expected ) { $this->assertNull( $result ); } else { - $this->assertSame( $expected, $result->ident ); + $this->assertSame( $expected, $result->type ); $this->assertSame( $rest, substr( $input, $offset ) ); } } @@ -381,7 +381,7 @@ public function test_parse_selector() { $offset = 0; $sel = $this->test_class::test_parse_compound_selector( $input, $offset ); - $this->assertSame( 'el', $sel->type_selector->ident ); + $this->assertSame( 'el', $sel->type_selector->type ); $this->assertSame( 3, count( $sel->subclass_selectors ) ); $this->assertSame( 'foo', $sel->subclass_selectors[0]->class_name, 'foo' ); $this->assertSame( 'bar', $sel->subclass_selectors[1]->id, 'bar' ); From d89fbd989d86fb16f2d34eb896031d32db817055 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 9 Dec 2024 19:03:35 +0100 Subject: [PATCH 109/634] Document compound selector --- .../class-wp-css-compound-selector.php | 63 ++++++++++++++----- 1 file changed, 46 insertions(+), 17 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector.php b/src/wp-includes/html-api/class-wp-css-compound-selector.php index f281146110f30..19aad862db7e2 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector.php @@ -1,11 +1,55 @@ in the grammar. + * CSS compound selector. + * + * This class is used to test for matching HTML tags in a {@see WP_HTML_Tag_Processor}. + * + * A compound selector is a combination of: + * - An optional type selector. + * - Zero or more subclass selectors (ID, class, or attribute selectors). + * - At least one of the above. * - * > = [ ? * ]! + * @since TBD + * + * @access private */ final class WP_CSS_Compound_Selector implements WP_CSS_HTML_Tag_Processor_Matcher { + /** + * The type selector. + * + * @var WP_CSS_Type_Selector|null + */ + public $type_selector; + + /** + * The subclass selectors. + * + * Subclass selectors are ID, class, or attribute selectors. + * + * @var (WP_CSS_ID_Selector|WP_CSS_Class_Selector|WP_CSS_Attribute_Selector)[]|null + */ + public $subclass_selectors; + + /** + * Constructor. + * + * @param WP_CSS_Type_Selector|null $type_selector The type selector or null. + * @param (WP_CSS_ID_Selector|WP_CSS_Class_Selector|WP_CSS_Attribute_Selector)[]|null $subclass_selectors + * The array of subclass selectors or null. + */ + public function __construct( ?WP_CSS_Type_Selector $type_selector, ?array $subclass_selectors ) { + $this->type_selector = $type_selector; + $this->subclass_selectors = array() === $subclass_selectors ? null : $subclass_selectors; + } + /** * Determines if the processor's current position matches the selector. * @@ -25,19 +69,4 @@ public function matches( WP_HTML_Tag_Processor $processor ): bool { } return true; } - - /** @var WP_CSS_Type_Selector|null */ - public $type_selector; - - /** @var (WP_CSS_ID_Selector|WP_CSS_Class_Selector|WP_CSS_Attribute_Selector)[]|null */ - public $subclass_selectors; - - /** - * @param WP_CSS_Type_Selector|null $type_selector - * @param array $subclass_selectors - */ - public function __construct( ?WP_CSS_Type_Selector $type_selector, array $subclass_selectors ) { - $this->type_selector = $type_selector; - $this->subclass_selectors = array() === $subclass_selectors ? null : $subclass_selectors; - } } From 8ced3aa2da7f1c77a12b344516c9dae8eaad9be5 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 9 Dec 2024 19:03:59 +0100 Subject: [PATCH 110/634] Improve attribute selector docs and types --- .../class-wp-css-attribute-selector.php | 111 +++++++++++------- .../class-wp-css-compound-selector-list.php | 2 +- .../class-wp-css-compound-selector.php | 2 +- .../html-api/wpCssCompoundSelectorList.php | 2 +- 4 files changed, 73 insertions(+), 44 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-attribute-selector.php b/src/wp-includes/html-api/class-wp-css-attribute-selector.php index dae71c4295348..b64efea0bb45c 100644 --- a/src/wp-includes/html-api/class-wp-css-attribute-selector.php +++ b/src/wp-includes/html-api/class-wp-css-attribute-selector.php @@ -19,98 +19,127 @@ */ final class WP_CSS_Attribute_Selector implements WP_CSS_HTML_Tag_Processor_Matcher { /** - * [att=val] - * Represents an element with the att attribute whose value is exactly "val". + * The attribute value is matched exactly. + * + * @example + * + * [att=val] */ - const MATCH_EXACT = 'MATCH_EXACT'; + const MATCH_EXACT = 'exact'; /** - * [attr~=value] - * Represents elements with an attribute name of attr whose value is a - * whitespace-separated list of words, one of which is exactly value. + * The attribute value matches any value in a whitespace separated list of words exactly. + * + * @example + * + * [attr~=value] */ - const MATCH_ONE_OF_EXACT = 'MATCH_ONE_OF_EXACT'; + const MATCH_ONE_OF_EXACT = 'one-of'; /** - * [attr|=value] - * Represents elements with an attribute name of attr whose value can be exactly value or - * can begin with value immediately followed by a hyphen, - (U+002D). It is often used for - * language subcode matches. + * The attribute value is matched exactly or matches the beginning of the attribute + * immediately followed by a hyphen. + * + * @example + * + * [attr|=value] */ - const MATCH_EXACT_OR_EXACT_WITH_HYPHEN = 'MATCH_EXACT_OR_EXACT_WITH_HYPHEN'; + const MATCH_EXACT_OR_HYPHEN_PREFIXED = 'exact-or-hyphen-prefixed'; /** - * [attr^=value] - * Represents elements with an attribute name of attr whose value is prefixed (preceded) - * by value. + * The attribute value matches the start of the attribute. + * + * @example + * + * [attr^=value] */ - const MATCH_PREFIXED_BY = 'MATCH_PREFIXED_BY'; + const MATCH_PREFIXED_BY = 'prefixed'; /** - * [attr$=value] - * Represents elements with an attribute name of attr whose value is suffixed (followed) - * by value. + * The attribute value matches the end of the attribute. + * + * @example + * + * [attr$=value] */ - const MATCH_SUFFIXED_BY = 'MATCH_SUFFIXED_BY'; + const MATCH_SUFFIXED_BY = 'suffixed'; /** - * [attr*=value] - * Represents elements with an attribute name of attr whose value contains at least one - * occurrence of value within the string. + * The attribute value is contained in the attribute. + * + * @example + * + * [attr*=value] */ - const MATCH_CONTAINS = 'MATCH_CONTAINS'; + const MATCH_CONTAINS = 'contains'; /** - * Modifier for case sensitive matching - * [attr=value s] + * Modifier for case sensitive matching. + * + * @example + * + * [attr=value s] */ const MODIFIER_CASE_SENSITIVE = 'case-sensitive'; /** - * Modifier for case insensitive matching - * [attr=value i] + * Modifier for case insensitive matching. + * + * @example + * + * [attr=value i] */ const MODIFIER_CASE_INSENSITIVE = 'case-insensitive'; /** - * The attribute name. + * The name of the attribute to match. * * @var string - * @readonly */ public $name; /** * The attribute matcher. * - * @var null|self::MATCH_* - * @readonly + * Allowed string values are the class constants: + * - {@see WP_CSS_Attribute_Selector::MATCH_EXACT} + * - {@see WP_CSS_Attribute_Selector::MATCH_ONE_OF_EXACT} + * - {@see WP_CSS_Attribute_Selector::MATCH_EXACT_OR_HYPHEN_PREFIXED} + * - {@see WP_CSS_Attribute_Selector::MATCH_PREFIXED_BY} + * - {@see WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY} + * - {@see WP_CSS_Attribute_Selector::MATCH_CONTAINS} + * + * @var string|null */ public $matcher; /** - * The attribute value. + * The attribute value to match. * * @var string|null - * @readonly */ public $value; /** * The attribute modifier. * - * @var null|self::MODIFIER_* - * @readonly + * Allowed string values are the class constants: + * - {@see WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE} + * - {@see WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE} + * + * @var string|null */ public $modifier; /** * Constructor. * - * @param string $name - * @param null|self::MATCH_* $matcher - * @param null|string $value - * @param null|self::MODIFIER_* $modifier + * @param string $name The attribute name. + * @param string|null $matcher The attribute matcher. + * Must be one of the class MATCH_* constants or null. + * @param string|null $value The attribute value to match. + * @param string|null $modifier The attribute case modifier. + * Must be one of the class MODIFIER_* constants or null. */ public function __construct( string $name, ?string $matcher = null, ?string $value = null, ?string $modifier = null ) { $this->name = $name; @@ -159,7 +188,7 @@ public function matches( WP_HTML_Tag_Processor $processor ): bool { } return false; - case self::MATCH_EXACT_OR_EXACT_WITH_HYPHEN: + case self::MATCH_EXACT_OR_HYPHEN_PREFIXED: // Attempt the full match first if ( $case_insensitive diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php index 27900d40a238c..02a958e647ef1 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php @@ -294,7 +294,7 @@ final protected static function parse_attribute_selector( string $input, int &$o $updated_offset += 2; break; case '|': - $attr_matcher = WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN; + $attr_matcher = WP_CSS_Attribute_Selector::MATCH_EXACT_OR_HYPHEN_PREFIXED; $updated_offset += 2; break; case '^': diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector.php b/src/wp-includes/html-api/class-wp-css-compound-selector.php index 19aad862db7e2..414d36301ec5d 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector.php @@ -1,6 +1,6 @@ array( "[href \n ^= baz ]", 'href', WP_CSS_Attribute_Selector::MATCH_PREFIXED_BY, 'baz', null, '' ), '[match $= insensitive i]' => array( '[match $= insensitive i]', 'match', WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY, 'insensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), - '[match|=sensitive s]' => array( '[match|=sensitive s]', 'match', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_EXACT_WITH_HYPHEN, 'sensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), + '[match|=sensitive s]' => array( '[match|=sensitive s]', 'match', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_HYPHEN_PREFIXED, 'sensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), '[att=val I]' => array( '[att=val I]', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'val', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), '[att=val S]' => array( '[att=val S]', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'val', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), From ca1a12973819a7d7b3ea05b4bff160ced33532dd Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 9 Dec 2024 19:04:11 +0100 Subject: [PATCH 111/634] Update matches docs --- src/wp-includes/html-api/class-wp-css-attribute-selector.php | 3 +-- src/wp-includes/html-api/class-wp-css-class-selector.php | 3 +-- src/wp-includes/html-api/class-wp-css-id-selector.php | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-attribute-selector.php b/src/wp-includes/html-api/class-wp-css-attribute-selector.php index b64efea0bb45c..fbdef5ce930be 100644 --- a/src/wp-includes/html-api/class-wp-css-attribute-selector.php +++ b/src/wp-includes/html-api/class-wp-css-attribute-selector.php @@ -10,8 +10,7 @@ /** * CSS attribute selector. * - * This class implements a CSS attribute selector and is used to test for matching HTML tags - * in a {@see WP_HTML_Tag_Processor}. + * This class is used to test for matching HTML tags in a {@see WP_HTML_Tag_Processor}. * * @since TBD * diff --git a/src/wp-includes/html-api/class-wp-css-class-selector.php b/src/wp-includes/html-api/class-wp-css-class-selector.php index cdd38d951e45c..02410546a4b52 100644 --- a/src/wp-includes/html-api/class-wp-css-class-selector.php +++ b/src/wp-includes/html-api/class-wp-css-class-selector.php @@ -10,8 +10,7 @@ /** * CSS class selector. * - * This class implements a CSS class selector and is used to test for matching HTML tags - * in a {@see WP_HTML_Tag_Processor}. + * This class is used to test for matching HTML tags in a {@see WP_HTML_Tag_Processor}. * * @since TBD * diff --git a/src/wp-includes/html-api/class-wp-css-id-selector.php b/src/wp-includes/html-api/class-wp-css-id-selector.php index 5bb6438df6eb3..ca61f00bb7e67 100644 --- a/src/wp-includes/html-api/class-wp-css-id-selector.php +++ b/src/wp-includes/html-api/class-wp-css-id-selector.php @@ -10,8 +10,7 @@ /** * CSS ID selector. * - * This class implements a CSS ID selector and is used to test for matching HTML tags - * in a {@see WP_HTML_Tag_Processor}. + * This class is used to test for matching HTML tags in a {@see WP_HTML_Tag_Processor}. * * @since TBD * From 71fd62aa9d5f8342ed221ec674c420753b838e14 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 9 Dec 2024 19:15:27 +0100 Subject: [PATCH 112/634] Document complex selector class --- .../class-wp-css-complex-selector.php | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector.php b/src/wp-includes/html-api/class-wp-css-complex-selector.php index bd51884901d93..c6795254ea7b8 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector.php @@ -10,10 +10,10 @@ /** * CSS complex selector. * - * This class implements a CSS complex selector and is used to test for matching HTML tags - * in a {@see WP_HTML_Tag_Processor}. + * This class is used to test for matching HTML tags in a {@see WP_HTML_Processor}. * - * A complex selector is a selector with zero or more combinator-selector pairs. + * A compound selector is at least a single compound selector. There may be additional selectors + * with combinators. * * @since TBD * @@ -106,8 +106,10 @@ final class WP_CSS_Complex_Selector implements WP_CSS_HTML_Processor_Matcher { public $context_selectors; /** - * @param WP_CSS_Compound_Selector $self_selector - * @param array{WP_CSS_Type_Selector, string}[]|null $selectors + * Constructor. + * + * @param WP_CSS_Compound_Selector $self_selector The selector in the final position. + * @param array{WP_CSS_Type_Selector, string}[]|null $selectors The context selectors. */ public function __construct( WP_CSS_Compound_Selector $self_selector, @@ -133,16 +135,15 @@ public function matches( WP_HTML_Processor $processor ): bool { return true; } - /** @var string[] */ $breadcrumbs = array_slice( array_reverse( $processor->get_breadcrumbs() ), 1 ); return $this->explore_matches( $this->context_selectors, $breadcrumbs ); } /** - * Checks for matches recursively comparing context selectors with breadcrumbs. + * Checks for matches by recursively comparing context selectors with breadcrumbs. * - * @param array{WP_CSS_Type_Selector, string}[] $selectors - * @param string[] $breadcrumbs + * @param array{WP_CSS_Type_Selector, string}[] $selectors Selectors to match. + * @param string[] $breadcrumbs Breadcrumbs. * @return bool True if a match is found, otherwise false. */ private function explore_matches( array $selectors, array $breadcrumbs ): bool { @@ -176,7 +177,16 @@ private function explore_matches( array $selectors, array $breadcrumbs ): bool { return false; default: - throw new Exception( "Unsupported combinator '{$combinator}' found." ); + _doing_it_wrong( + __METHOD__, + sprintf( + // translators: %s: A CSS selector combinator like ">" or "+". + __( 'Unsupported combinator "%s" found.' ), + $combinator + ), + '6.8.0' + ); + return false; } } } From 25dbb198cbfa081931b9a60dbda7e5f682d4b8d4 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 9 Dec 2024 19:23:28 +0100 Subject: [PATCH 113/634] PHP < 7.4 does not like this annotation --- .../html-api/class-wp-css-compound-selector-list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php index 02a958e647ef1..a74ffe0f45fc9 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php @@ -83,7 +83,7 @@ class WP_CSS_Compound_Selector_List implements WP_CSS_HTML_Tag_Processor_Matcher * @param WP_HTML_Tag_Processor $processor The processor. * @return bool True if the processor's current position matches the selector. */ - public function matches( WP_HTML_Tag_Processor $processor ): bool { + public function matches( $processor ): bool { if ( $processor->get_token_type() !== '#tag' ) { return false; } From 70cf7f7584b15ac2934dc90a86b030a21e2ad2d4 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 9 Dec 2024 19:47:52 +0100 Subject: [PATCH 114/634] Update since annotations to 6.8.0 --- .../html-api/class-wp-css-attribute-selector.php | 4 ++-- src/wp-includes/html-api/class-wp-css-class-selector.php | 4 ++-- .../html-api/class-wp-css-complex-selector-list.php | 6 +++--- src/wp-includes/html-api/class-wp-css-complex-selector.php | 4 ++-- .../html-api/class-wp-css-compound-selector-list.php | 6 +++--- src/wp-includes/html-api/class-wp-css-compound-selector.php | 4 ++-- src/wp-includes/html-api/class-wp-css-id-selector.php | 4 ++-- src/wp-includes/html-api/class-wp-css-type-selector.php | 4 ++-- src/wp-includes/html-api/class-wp-html-processor.php | 4 ++-- src/wp-includes/html-api/class-wp-html-tag-processor.php | 4 ++-- tests/phpunit/tests/html-api/wpCssComplexSelectorList.php | 2 +- tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php | 2 +- tests/phpunit/tests/html-api/wpHtmlProcessor-select.php | 2 +- tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php | 2 +- 14 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-attribute-selector.php b/src/wp-includes/html-api/class-wp-css-attribute-selector.php index fbdef5ce930be..7543cb834e820 100644 --- a/src/wp-includes/html-api/class-wp-css-attribute-selector.php +++ b/src/wp-includes/html-api/class-wp-css-attribute-selector.php @@ -4,7 +4,7 @@ * * @package WordPress * @subpackage HTML-API - * @since TBD + * @since 6.8.0 */ /** @@ -12,7 +12,7 @@ * * This class is used to test for matching HTML tags in a {@see WP_HTML_Tag_Processor}. * - * @since TBD + * @since 6.8.0 * * @access private */ diff --git a/src/wp-includes/html-api/class-wp-css-class-selector.php b/src/wp-includes/html-api/class-wp-css-class-selector.php index 02410546a4b52..fa287cdf5c580 100644 --- a/src/wp-includes/html-api/class-wp-css-class-selector.php +++ b/src/wp-includes/html-api/class-wp-css-class-selector.php @@ -4,7 +4,7 @@ * * @package WordPress * @subpackage HTML-API - * @since TBD + * @since 6.8.0 */ /** @@ -12,7 +12,7 @@ * * This class is used to test for matching HTML tags in a {@see WP_HTML_Tag_Processor}. * - * @since TBD + * @since 6.8.0 * * @access private */ diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php index 4a9fc03f582f8..fcc6032589584 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php @@ -4,7 +4,7 @@ * * @package WordPress * @subpackage HTML-API - * @since TBD + * @since 6.8.0 */ /** @@ -28,7 +28,7 @@ * - Next sibling (`el + el`) * - Subsequent sibling (`el ~ el`) * - * @since TBD + * @since 6.8.0 * * @access private */ @@ -37,7 +37,7 @@ class WP_CSS_Complex_Selector_List extends WP_CSS_Compound_Selector_List impleme * Takes a CSS selector string and returns an instance of itself or `null` if the selector * string is invalid or unsupported. * - * @since TBD + * @since 6.8.0 * * @param string $input CSS selectors. * @return static|null diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector.php b/src/wp-includes/html-api/class-wp-css-complex-selector.php index c6795254ea7b8..4461e4d7d92f3 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector.php @@ -4,7 +4,7 @@ * * @package WordPress * @subpackage HTML-API - * @since TBD + * @since 6.8.0 */ /** @@ -15,7 +15,7 @@ * A compound selector is at least a single compound selector. There may be additional selectors * with combinators. * - * @since TBD + * @since 6.8.0 * * @access private */ diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php index a74ffe0f45fc9..a2ff48e089f5d 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php @@ -4,7 +4,7 @@ * * @package WordPress * @subpackage HTML-API - * @since TBD + * @since 6.8.0 */ /** @@ -67,7 +67,7 @@ * - `svg|*` to select all SVG elements * - `html|title` to select only HTML TITLE elements. * - * @since TBD + * @since 6.8.0 * * @access private * @@ -116,7 +116,7 @@ protected function __construct( array $selectors ) { * Takes a CSS selector string and returns an instance of itself or `null` if the selector * string is invalid or unsupported. * - * @since TBD + * @since 6.8.0 * * @param string $input CSS selectors. * @return static|null diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector.php b/src/wp-includes/html-api/class-wp-css-compound-selector.php index 414d36301ec5d..9596876685212 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector.php @@ -4,7 +4,7 @@ * * @package WordPress * @subpackage HTML-API - * @since TBD + * @since 6.8.0 */ /** @@ -17,7 +17,7 @@ * - Zero or more subclass selectors (ID, class, or attribute selectors). * - At least one of the above. * - * @since TBD + * @since 6.8.0 * * @access private */ diff --git a/src/wp-includes/html-api/class-wp-css-id-selector.php b/src/wp-includes/html-api/class-wp-css-id-selector.php index ca61f00bb7e67..2a600923fa2a2 100644 --- a/src/wp-includes/html-api/class-wp-css-id-selector.php +++ b/src/wp-includes/html-api/class-wp-css-id-selector.php @@ -4,7 +4,7 @@ * * @package WordPress * @subpackage HTML-API - * @since TBD + * @since 6.8.0 */ /** @@ -12,7 +12,7 @@ * * This class is used to test for matching HTML tags in a {@see WP_HTML_Tag_Processor}. * - * @since TBD + * @since 6.8.0 * * @access private */ diff --git a/src/wp-includes/html-api/class-wp-css-type-selector.php b/src/wp-includes/html-api/class-wp-css-type-selector.php index 66d6a1f2db48f..3f7671851c375 100644 --- a/src/wp-includes/html-api/class-wp-css-type-selector.php +++ b/src/wp-includes/html-api/class-wp-css-type-selector.php @@ -4,7 +4,7 @@ * * @package WordPress * @subpackage HTML-API - * @since TBD + * @since 6.8.0 */ /** @@ -12,7 +12,7 @@ * * This class is used to test for matching HTML tags in a {@see WP_HTML_Tag_Processor}. * - * @since TBD + * @since 6.8.0 * * @access private */ diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index 7ad65cb9d03d4..6685eaaf79aea 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -652,7 +652,7 @@ public function get_unsupported_exception() { * ); * } * - * @since TBD + * @since 6.8.0 * * @param string $selector_string Selector string. * @return Generator A generator pausing on each tag matching the selector. @@ -692,7 +692,7 @@ public function select_all( $selector_string ): Generator { * $processor->get_attribute( 'charset' ), // string(5) "utf-8" * ); * - * @since TBD + * @since 6.8.0 * * @param string $selector_string * @return bool True if a matching tag was found, otherwise false. diff --git a/src/wp-includes/html-api/class-wp-html-tag-processor.php b/src/wp-includes/html-api/class-wp-html-tag-processor.php index a7633291b6bb2..8ea6e930f5b91 100644 --- a/src/wp-includes/html-api/class-wp-html-tag-processor.php +++ b/src/wp-includes/html-api/class-wp-html-tag-processor.php @@ -877,7 +877,7 @@ public function change_parsing_namespace( string $new_namespace ): bool { * ); * } * - * @since TBD + * @since 6.8.0 * * @param string $selector_string Selector string. * @return Generator A generator pausing on each tag matching the selector. @@ -917,7 +917,7 @@ public function select_all( $selector_string ): Generator { * $processor->get_attribute( 'charset' ), // string(5) "utf-8" * ); * - * @since TBD + * @since 6.8.0 * * @param string $selector_string * @return bool True if a matching tag was found, otherwise false. diff --git a/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php b/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php index 076d5b6f65ee6..829af95a55d5f 100644 --- a/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php +++ b/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php @@ -6,7 +6,7 @@ * * @subpackage HTML-API * - * @since TBD + * @since 6.8.0 * * @group html-api */ diff --git a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php index 2c7a4695f679e..c112585e622c8 100644 --- a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php +++ b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php @@ -6,7 +6,7 @@ * * @subpackage HTML-API * - * @since TBD + * @since 6.8.0 * * @group html-api */ diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php index 21828faf42e80..a8f6a7c949080 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php @@ -8,7 +8,7 @@ * @package WordPress * @subpackage HTML-API * - * @since TBD + * @since 6.8.0 * * @group html-api */ diff --git a/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php index 586e38b4bafb2..28f88778629ce 100644 --- a/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php +++ b/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php @@ -8,7 +8,7 @@ * @package WordPress * @subpackage HTML-API * - * @since TBD + * @since 6.8.0 * * @group html-api */ From 355c9a24e0d983813ae73e8cacc59287833d2846 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 9 Dec 2024 19:53:48 +0100 Subject: [PATCH 115/634] Update attr-modifier to match selectors grammar --- .../html-api/class-wp-css-compound-selector-list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php index a2ff48e089f5d..fa12519540cc5 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php @@ -36,7 +36,7 @@ * = '[' ']' | * '[' [ | ] ? ']' * = [ '~' | '|' | '^' | '$' | '*' ]? '=' - * = i | I | s | S + * = i | s * * @link https://www.w3.org/TR/selectors/#grammar Refer to the grammar for more details. * From 3206e0b02f2d7f77cc52a0a3710f0d18ec73b9c3 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 11 Dec 2024 18:25:36 +0100 Subject: [PATCH 116/634] Move parsing back to selector classes --- .../class-wp-css-attribute-selector.php | 122 ++- .../html-api/class-wp-css-class-selector.php | 28 +- .../class-wp-css-complex-selector-list.php | 96 +-- .../class-wp-css-complex-selector.php | 80 +- .../class-wp-css-compound-selector-list.php | 735 +----------------- .../class-wp-css-compound-selector.php | 60 +- .../html-api/class-wp-css-id-selector.php | 24 +- .../class-wp-css-selector-parser-matcher.php | 476 ++++++++++++ .../html-api/class-wp-css-type-selector.php | 30 +- ...nterface-wp-css-html-processor-matcher.php | 11 - ...face-wp-css-html-tag-processor-matcher.php | 11 - 11 files changed, 839 insertions(+), 834 deletions(-) create mode 100644 src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php delete mode 100644 src/wp-includes/html-api/interface-wp-css-html-processor-matcher.php delete mode 100644 src/wp-includes/html-api/interface-wp-css-html-tag-processor-matcher.php diff --git a/src/wp-includes/html-api/class-wp-css-attribute-selector.php b/src/wp-includes/html-api/class-wp-css-attribute-selector.php index 7543cb834e820..700a8cba9bb0c 100644 --- a/src/wp-includes/html-api/class-wp-css-attribute-selector.php +++ b/src/wp-includes/html-api/class-wp-css-attribute-selector.php @@ -16,7 +16,7 @@ * * @access private */ -final class WP_CSS_Attribute_Selector implements WP_CSS_HTML_Tag_Processor_Matcher { +final class WP_CSS_Attribute_Selector extends WP_CSS_Selector_Parser_Matcher { /** * The attribute value is matched exactly. * @@ -244,4 +244,124 @@ private function whitespace_delimited_list( string $input ): Generator { yield $value; } } + + /** + * Parses a selector string to create a selector instance. + * + * To create an instance of this class, use the {@see WP_CSS_Compound_Selector_List::from_selectors()} method. + * + * @param string $input The selector string. + * @param int $offset The offset into the string. The offset is passed by reference and + * will be updated if the parse is successful. + * @return static|null The selector instance, or null if the parse was unsuccessful. + */ + public static function parse( string $input, int &$offset ): ?static { + // Need at least 3 bytes [x] + if ( $offset + 2 >= strlen( $input ) ) { + return null; + } + + $updated_offset = $offset; + + if ( '[' !== $input[ $updated_offset ] ) { + return null; + } + ++$updated_offset; + + self::parse_whitespace( $input, $updated_offset ); + $attr_name = self::parse_ident( $input, $updated_offset ); + if ( null === $attr_name ) { + return null; + } + self::parse_whitespace( $input, $updated_offset ); + + if ( $updated_offset >= strlen( $input ) ) { + return null; + } + + if ( ']' === $input[ $updated_offset ] ) { + $offset = $updated_offset + 1; + return new WP_CSS_Attribute_Selector( $attr_name ); + } + + // need to match at least `=x]` at this point + if ( $updated_offset + 3 >= strlen( $input ) ) { + return null; + } + + if ( '=' === $input[ $updated_offset ] ) { + ++$updated_offset; + $attr_matcher = WP_CSS_Attribute_Selector::MATCH_EXACT; + } elseif ( '=' === $input[ $updated_offset + 1 ] ) { + switch ( $input[ $updated_offset ] ) { + case '~': + $attr_matcher = WP_CSS_Attribute_Selector::MATCH_ONE_OF_EXACT; + $updated_offset += 2; + break; + case '|': + $attr_matcher = WP_CSS_Attribute_Selector::MATCH_EXACT_OR_HYPHEN_PREFIXED; + $updated_offset += 2; + break; + case '^': + $attr_matcher = WP_CSS_Attribute_Selector::MATCH_PREFIXED_BY; + $updated_offset += 2; + break; + case '$': + $attr_matcher = WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY; + $updated_offset += 2; + break; + case '*': + $attr_matcher = WP_CSS_Attribute_Selector::MATCH_CONTAINS; + $updated_offset += 2; + break; + default: + return null; + } + } else { + return null; + } + + self::parse_whitespace( $input, $updated_offset ); + $attr_val = + self::parse_string( $input, $updated_offset ) ?? + self::parse_ident( $input, $updated_offset ); + + if ( null === $attr_val ) { + return null; + } + + self::parse_whitespace( $input, $updated_offset ); + if ( $updated_offset >= strlen( $input ) ) { + return null; + } + + $attr_modifier = null; + switch ( $input[ $updated_offset ] ) { + case 'i': + case 'I': + $attr_modifier = WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE; + ++$updated_offset; + break; + + case 's': + case 'S': + $attr_modifier = WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE; + ++$updated_offset; + break; + } + + if ( null !== $attr_modifier ) { + self::parse_whitespace( $input, $updated_offset ); + if ( $updated_offset >= strlen( $input ) ) { + return null; + } + } + + if ( ']' === $input[ $updated_offset ] ) { + $offset = $updated_offset + 1; + return new self( $attr_name, $attr_matcher, $attr_val, $attr_modifier ); + } + + return null; + } } diff --git a/src/wp-includes/html-api/class-wp-css-class-selector.php b/src/wp-includes/html-api/class-wp-css-class-selector.php index fa287cdf5c580..9abcb881ace49 100644 --- a/src/wp-includes/html-api/class-wp-css-class-selector.php +++ b/src/wp-includes/html-api/class-wp-css-class-selector.php @@ -16,7 +16,7 @@ * * @access private */ -final class WP_CSS_Class_Selector implements WP_CSS_HTML_Tag_Processor_Matcher { +final class WP_CSS_Class_Selector extends WP_CSS_Selector_Parser_Matcher { /** * The class name to match. * @@ -42,4 +42,30 @@ public function __construct( string $class_name ) { public function matches( WP_HTML_Tag_Processor $processor ): bool { return (bool) $processor->has_class( $this->class_name ); } + + /** + * Parses a selector string to create a selector instance. + * + * To create an instance of this class, use the {@see WP_CSS_Compound_Selector_List::from_selectors()} method. + * + * @param string $input The selector string. + * @param int $offset The offset into the string. The offset is passed by reference and + * will be updated if the parse is successful. + * @return static|null The selector instance, or null if the parse was unsuccessful. + */ + public static function parse( string $input, int &$offset ): ?static { + if ( $offset + 1 >= strlen( $input ) || '.' !== $input[ $offset ] ) { + return null; + } + + $updated_offset = $offset + 1; + $result = self::parse_ident( $input, $updated_offset ); + + if ( null === $result ) { + return null; + } + + $offset = $updated_offset; + return new self( $result ); + } } diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php index fcc6032589584..10af613174a35 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php @@ -32,17 +32,18 @@ * * @access private */ -class WP_CSS_Complex_Selector_List extends WP_CSS_Compound_Selector_List implements WP_CSS_HTML_Processor_Matcher { +class WP_CSS_Complex_Selector_List extends WP_CSS_Compound_Selector_List { /** - * Takes a CSS selector string and returns an instance of itself or `null` if the selector - * string is invalid or unsupported. + * Parses a selector string to create a selector instance. * - * @since 6.8.0 + * To create an instance of this class, use the {@see WP_CSS_Compound_Selector_List::from_selectors()} method. * - * @param string $input CSS selectors. - * @return static|null + * @param string $input The selector string. + * @param int $offset The offset into the string. The offset is passed by reference and + * will be updated if the parse is successful. + * @return static|null The selector instance, or null if the parse was unsuccessful. */ - public static function from_selectors( string $input ) { + public static function parse( string $input, int &$offset ): ?static { $input = self::normalize_selector_input( $input ); if ( '' === $input ) { @@ -51,7 +52,7 @@ public static function from_selectors( string $input ) { $offset = 0; - $selector = self::parse_complex_selector( $input, $offset ); + $selector = WP_CSS_Complex_Selector::parse( $input, $offset ); if ( null === $selector ) { return null; } @@ -65,7 +66,7 @@ public static function from_selectors( string $input ) { } ++$offset; self::parse_whitespace( $input, $offset ); - $selector = self::parse_complex_selector( $input, $offset ); + $selector = WP_CSS_Complex_Selector::parse( $input, $offset ); if ( null === $selector ) { return null; } @@ -75,81 +76,4 @@ public static function from_selectors( string $input ) { return new self( $selectors ); } - - /* - * ------------------------------ - * Selector parsing functionality - * ------------------------------ - */ - - /** - * Parses a complex selector. - * - * > = [ ? ]* - * - * @return WP_CSS_Complex_Selector|null - */ - final protected static function parse_complex_selector( string $input, int &$offset ): ?WP_CSS_Complex_Selector { - if ( $offset >= strlen( $input ) ) { - return null; - } - - $updated_offset = $offset; - $self_selector = self::parse_compound_selector( $input, $updated_offset ); - if ( null === $self_selector ) { - return null; - } - /** @var array{WP_CSS_Compound_Selector, string}[] */ - $selectors = array(); - - $found_whitespace = self::parse_whitespace( $input, $updated_offset ); - while ( $updated_offset < strlen( $input ) ) { - $combinator = null; - $next_selector = null; - - if ( - WP_CSS_Complex_Selector::COMBINATOR_CHILD === $input[ $updated_offset ] || - WP_CSS_Complex_Selector::COMBINATOR_NEXT_SIBLING === $input[ $updated_offset ] || - WP_CSS_Complex_Selector::COMBINATOR_SUBSEQUENT_SIBLING === $input[ $updated_offset ] - ) { - $combinator = $input[ $updated_offset ]; - ++$updated_offset; - self::parse_whitespace( $input, $updated_offset ); - - // A combinator has been found, failure to find a selector here is a parse error. - $next_selector = self::parse_compound_selector( $input, $updated_offset ); - if ( null === $next_selector ) { - return null; - } - } elseif ( $found_whitespace ) { - /* - * Whitespace is ambiguous, it could be a descendant combinator or - * insignificant whitespace. - */ - $next_selector = self::parse_compound_selector( $input, $updated_offset ); - if ( null !== $next_selector ) { - $combinator = WP_CSS_Complex_Selector::COMBINATOR_DESCENDANT; - } - } - - if ( null === $next_selector ) { - break; - } - - // $self_selector will pass to a relative selector where only the type selector is allowed. - if ( null !== $self_selector->subclass_selectors || null === $self_selector->type_selector ) { - return null; - } - - /** @var array{WP_CSS_Compound_Selector, string} */ - $selector_pair = array( $self_selector->type_selector, $combinator ); - $selectors[] = $selector_pair; - $self_selector = $next_selector; - - $found_whitespace = self::parse_whitespace( $input, $updated_offset ); - } - $offset = $updated_offset; - - return new WP_CSS_Complex_Selector( $self_selector, array_reverse( $selectors ) ); - } } diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector.php b/src/wp-includes/html-api/class-wp-css-complex-selector.php index 4461e4d7d92f3..7c997c62a80f7 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector.php @@ -19,7 +19,7 @@ * * @access private */ -final class WP_CSS_Complex_Selector implements WP_CSS_HTML_Processor_Matcher { +final class WP_CSS_Complex_Selector extends WP_CSS_Selector_Parser_Matcher { /** * Child combinator. */ @@ -111,7 +111,7 @@ final class WP_CSS_Complex_Selector implements WP_CSS_HTML_Processor_Matcher { * @param WP_CSS_Compound_Selector $self_selector The selector in the final position. * @param array{WP_CSS_Type_Selector, string}[]|null $selectors The context selectors. */ - public function __construct( + private function __construct( WP_CSS_Compound_Selector $self_selector, ?array $context_selectors ) { @@ -125,7 +125,7 @@ public function __construct( * @param WP_HTML_Processor $processor The processor. * @return bool True if the processor's current position matches the selector. */ - public function matches( WP_HTML_Processor $processor ): bool { + public function matches( $processor ): bool { // First selector must match this location. if ( ! $this->self_selector->matches( $processor ) ) { return false; @@ -189,4 +189,78 @@ private function explore_matches( array $selectors, array $breadcrumbs ): bool { return false; } } + + /** + * Parses a selector string to create a selector instance. + * + * To create an instance of this class, use the {@see WP_CSS_Compound_Selector_List::from_selectors()} method. + * + * @param string $input The selector string. + * @param int $offset The offset into the string. The offset is passed by reference and + * will be updated if the parse is successful. + * @return static|null The selector instance, or null if the parse was unsuccessful. + */ + public static function parse( string $input, int &$offset ): ?static { + if ( $offset >= strlen( $input ) ) { + return null; + } + + $updated_offset = $offset; + $self_selector = WP_CSS_Compound_Selector::parse( $input, $updated_offset ); + if ( null === $self_selector ) { + return null; + } + /** @var array{WP_CSS_Compound_Selector, string}[] */ + $selectors = array(); + + $found_whitespace = self::parse_whitespace( $input, $updated_offset ); + while ( $updated_offset < strlen( $input ) ) { + $combinator = null; + $next_selector = null; + + if ( + WP_CSS_Complex_Selector::COMBINATOR_CHILD === $input[ $updated_offset ] || + WP_CSS_Complex_Selector::COMBINATOR_NEXT_SIBLING === $input[ $updated_offset ] || + WP_CSS_Complex_Selector::COMBINATOR_SUBSEQUENT_SIBLING === $input[ $updated_offset ] + ) { + $combinator = $input[ $updated_offset ]; + ++$updated_offset; + self::parse_whitespace( $input, $updated_offset ); + + // A combinator has been found, failure to find a selector here is a parse error. + $next_selector = WP_CSS_Compound_Selector::parse( $input, $updated_offset ); + if ( null === $next_selector ) { + return null; + } + } elseif ( $found_whitespace ) { + /* + * Whitespace is ambiguous, it could be a descendant combinator or + * insignificant whitespace. + */ + $next_selector = WP_CSS_Compound_Selector::parse( $input, $updated_offset ); + if ( null !== $next_selector ) { + $combinator = WP_CSS_Complex_Selector::COMBINATOR_DESCENDANT; + } + } + + if ( null === $next_selector ) { + break; + } + + // $self_selector will pass to a relative selector where only the type selector is allowed. + if ( null !== $self_selector->subclass_selectors || null === $self_selector->type_selector ) { + return null; + } + + /** @var array{WP_CSS_Compound_Selector, string} */ + $selector_pair = array( $self_selector->type_selector, $combinator ); + $selectors[] = $selector_pair; + $self_selector = $next_selector; + + $found_whitespace = self::parse_whitespace( $input, $updated_offset ); + } + $offset = $updated_offset; + + return new self( $self_selector, array_reverse( $selectors ) ); + } } diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php index fa12519540cc5..a6f3b87409ff6 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php @@ -76,7 +76,7 @@ * @link https://www.w3.org/TR/selectors-api2/ * @link https://www.w3.org/TR/selectors-4/ */ -class WP_CSS_Compound_Selector_List implements WP_CSS_HTML_Tag_Processor_Matcher { +class WP_CSS_Compound_Selector_List extends WP_CSS_Selector_Parser_Matcher { /** * Determines if the processor's current position matches the selector. * @@ -121,7 +121,22 @@ protected function __construct( array $selectors ) { * @param string $input CSS selectors. * @return static|null */ - public static function from_selectors( string $input ) { + public static function from_selectors( string $input ): ?static { + $offset = 0; + return static::parse( $input, $offset ); + } + + /** + * Parses a selector string to create a selector instance. + * + * To create an instance of this class, use the {@see WP_CSS_Compound_Selector_List::from_selectors()} method. + * + * @param string $input The selector string. + * @param int $offset The offset into the string. The offset is passed by reference and + * will be updated if the parse is successful. + * @return static|null The selector instance, or null if the parse was unsuccessful. + */ + public static function parse( string $input, int &$offset ): ?static { $input = self::normalize_selector_input( $input ); if ( '' === $input ) { @@ -130,7 +145,7 @@ public static function from_selectors( string $input ) { $offset = 0; - $selector = self::parse_compound_selector( $input, $offset ); + $selector = WP_CSS_Compound_Selector::parse( $input, $offset ); if ( null === $selector ) { return null; } @@ -144,7 +159,7 @@ public static function from_selectors( string $input ) { } ++$offset; self::parse_whitespace( $input, $offset ); - $selector = self::parse_compound_selector( $input, $offset ); + $selector = WP_CSS_Compound_Selector::parse( $input, $offset ); if ( null === $selector ) { return null; } @@ -154,716 +169,4 @@ public static function from_selectors( string $input ) { return new self( $selectors ); } - - /* - * ------------------------------ - * Selector parsing functionality - * ------------------------------ - */ - - /** - * Parse an ID selector - * - * > = - * - * https://www.w3.org/TR/selectors/#grammar - * - * @return WP_CSS_ID_Selector|null - */ - final protected static function parse_id_selector( string $input, int &$offset ): ?WP_CSS_ID_Selector { - $ident = self::parse_hash_token( $input, $offset ); - if ( null === $ident ) { - return null; - } - return new WP_CSS_ID_Selector( $ident ); - } - - /** - * Parse a class selector - * - * > = '.' - * - * https://www.w3.org/TR/selectors/#grammar - * - * @return WP_CSS_Class_Selector|null - */ - final protected static function parse_class_selector( string $input, int &$offset ): ?WP_CSS_Class_Selector { - if ( $offset + 1 >= strlen( $input ) || '.' !== $input[ $offset ] ) { - return null; - } - - $updated_offset = $offset + 1; - $result = self::parse_ident( $input, $updated_offset ); - - if ( null === $result ) { - return null; - } - - $offset = $updated_offset; - return new WP_CSS_Class_Selector( $result ); - } - - /** - * Parse a type selector - * - * > = | ? '*' - * > = [ | '*' ]? '|' - * > = ? - * - * Namespaces (e.g. |div, *|div, or namespace|div) are not supported, - * so this selector effectively matches * or ident. - * - * https://www.w3.org/TR/selectors/#grammar - * - * @return WP_CSS_Type_Selector|null - */ - final protected static function parse_type_selector( string $input, int &$offset ): ?WP_CSS_Type_Selector { - if ( $offset >= strlen( $input ) ) { - return null; - } - - if ( '*' === $input[ $offset ] ) { - ++$offset; - return new WP_CSS_Type_Selector( '*' ); - } - - $result = self::parse_ident( $input, $offset ); - if ( null === $result ) { - return null; - } - - return new WP_CSS_Type_Selector( $result ); - } - - /** - * Parse an attribute selector - * - * > = '[' ']' | - * > '[' [ | ] ? ']' - * > = [ '~' | '|' | '^' | '$' | '*' ]? '=' - * > = i | s - * > = ? - * - * Namespaces are not supported, so attribute names are effectively identifiers. - * - * https://www.w3.org/TR/selectors/#grammar - * - * @return WP_CSS_Attribute_Selector|null - */ - final protected static function parse_attribute_selector( string $input, int &$offset ): ?WP_CSS_Attribute_Selector { - // Need at least 3 bytes [x] - if ( $offset + 2 >= strlen( $input ) ) { - return null; - } - - $updated_offset = $offset; - - if ( '[' !== $input[ $updated_offset ] ) { - return null; - } - ++$updated_offset; - - self::parse_whitespace( $input, $updated_offset ); - $attr_name = self::parse_ident( $input, $updated_offset ); - if ( null === $attr_name ) { - return null; - } - self::parse_whitespace( $input, $updated_offset ); - - if ( $updated_offset >= strlen( $input ) ) { - return null; - } - - if ( ']' === $input[ $updated_offset ] ) { - $offset = $updated_offset + 1; - return new WP_CSS_Attribute_Selector( $attr_name ); - } - - // need to match at least `=x]` at this point - if ( $updated_offset + 3 >= strlen( $input ) ) { - return null; - } - - if ( '=' === $input[ $updated_offset ] ) { - ++$updated_offset; - $attr_matcher = WP_CSS_Attribute_Selector::MATCH_EXACT; - } elseif ( '=' === $input[ $updated_offset + 1 ] ) { - switch ( $input[ $updated_offset ] ) { - case '~': - $attr_matcher = WP_CSS_Attribute_Selector::MATCH_ONE_OF_EXACT; - $updated_offset += 2; - break; - case '|': - $attr_matcher = WP_CSS_Attribute_Selector::MATCH_EXACT_OR_HYPHEN_PREFIXED; - $updated_offset += 2; - break; - case '^': - $attr_matcher = WP_CSS_Attribute_Selector::MATCH_PREFIXED_BY; - $updated_offset += 2; - break; - case '$': - $attr_matcher = WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY; - $updated_offset += 2; - break; - case '*': - $attr_matcher = WP_CSS_Attribute_Selector::MATCH_CONTAINS; - $updated_offset += 2; - break; - default: - return null; - } - } else { - return null; - } - - self::parse_whitespace( $input, $updated_offset ); - $attr_val = - self::parse_string( $input, $updated_offset ) ?? - self::parse_ident( $input, $updated_offset ); - - if ( null === $attr_val ) { - return null; - } - - self::parse_whitespace( $input, $updated_offset ); - if ( $updated_offset >= strlen( $input ) ) { - return null; - } - - $attr_modifier = null; - switch ( $input[ $updated_offset ] ) { - case 'i': - case 'I': - $attr_modifier = WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE; - ++$updated_offset; - break; - - case 's': - case 'S': - $attr_modifier = WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE; - ++$updated_offset; - break; - } - - if ( null !== $attr_modifier ) { - self::parse_whitespace( $input, $updated_offset ); - if ( $updated_offset >= strlen( $input ) ) { - return null; - } - } - - if ( ']' === $input[ $updated_offset ] ) { - $offset = $updated_offset + 1; - return new WP_CSS_Attribute_Selector( $attr_name, $attr_matcher, $attr_val, $attr_modifier ); - } - - return null; - } - - /** - * Parses a compound selector. - * - * > = [ ? * ]! - * - * @return WP_CSS_Compound_Selector|null - */ - final protected static function parse_compound_selector( string $input, int &$offset ): ?WP_CSS_Compound_Selector { - if ( $offset >= strlen( $input ) ) { - return null; - } - - $updated_offset = $offset; - $type_selector = self::parse_type_selector( $input, $updated_offset ); - - $subclass_selectors = array(); - $last_parsed_subclass_selector = self::parse_subclass_selector( $input, $updated_offset ); - while ( null !== $last_parsed_subclass_selector ) { - $subclass_selectors[] = $last_parsed_subclass_selector; - $last_parsed_subclass_selector = self::parse_subclass_selector( $input, $updated_offset ); - } - - if ( null !== $type_selector || array() !== $subclass_selectors ) { - $offset = $updated_offset; - return new WP_CSS_Compound_Selector( $type_selector, $subclass_selectors ); - } - return null; - } - - /** - * Parses a subclass selector. - * - * > = | | - * - * @return WP_CSS_ID_Selector|WP_CSS_Class_Selector|WP_CSS_Attribute_Selector|null - */ - private static function parse_subclass_selector( string $input, int &$offset ) { - if ( $offset >= strlen( $input ) ) { - return null; - } - - $next_char = $input[ $offset ]; - return '.' === $next_char - ? self::parse_class_selector( $input, $offset ) - : ( - '#' === $next_char - ? self::parse_id_selector( $input, $offset ) - : ( '[' === $next_char - ? self::parse_attribute_selector( $input, $offset ) - : null - ) - ); - } - - - /* - * ------------------------ - * Selector partial parsing - * ------------------------ - * - * These functions consume parts of a selector string input when successful - * and return meaningful values to be used by selectors. - */ - - const UTF8_MAX_CODEPOINT_VALUE = 0x10FFFF; - const WHITESPACE_CHARACTERS = " \t\r\n\f"; - - final public static function parse_whitespace( string $input, int &$offset ): bool { - $length = strspn( $input, self::WHITESPACE_CHARACTERS, $offset ); - $advanced = $length > 0; - $offset += $length; - return $advanced; - } - - /** - * Tokenization of hash tokens - * - * > U+0023 NUMBER SIGN (#) - * > If the next input code point is an ident code point or the next two input code points are a valid escape, then: - * > 1. Create a . - * > 2. If the next 3 input code points would start an ident sequence, set the - * > ’s type flag to "id". - * > 3. Consume an ident sequence, and set the ’s value to the - * > returned string. - * > 4. Return the . - * > Otherwise, return a with its value set to the current input code point. - * - * This implementation is not interested in the , a '#' delim token is not relevant for selectors. - */ - final protected static function parse_hash_token( string $input, int &$offset ): ?string { - if ( $offset + 1 >= strlen( $input ) || '#' !== $input[ $offset ] ) { - return null; - } - - $updated_offset = $offset + 1; - $result = self::parse_ident( $input, $updated_offset ); - - if ( null === $result ) { - return null; - } - - $offset = $updated_offset; - return $result; - } - - /** - * Parse an ident token - * - * CAUTION: This method is _not_ for parsing and ID selector! - * - * > 4.3.11. Consume an ident sequence - * > This section describes how to consume an ident sequence from a stream of code points. It returns a string containing the largest name that can be formed from adjacent code points in the stream, starting from the first. - * > - * > Note: This algorithm does not do the verification of the first few code points that are necessary to ensure the returned code points would constitute an . If that is the intended use, ensure that the stream starts with an ident sequence before calling this algorithm. - * > - * > Let result initially be an empty string. - * > - * > Repeatedly consume the next input code point from the stream: - * > - * > ident code point - * > Append the code point to result. - * > the stream starts with a valid escape - * > Consume an escaped code point. Append the returned code point to result. - * > anything else - * > Reconsume the current input code point. Return result. - * - * https://www.w3.org/TR/css-syntax-3/#consume-name - * - * @return string|null - */ - final protected static function parse_ident( string $input, int &$offset ): ?string { - if ( ! self::check_if_three_code_points_would_start_an_ident_sequence( $input, $offset ) ) { - return null; - } - - $ident = ''; - - while ( $offset < strlen( $input ) ) { - if ( self::next_two_are_valid_escape( $input, $offset ) ) { - // Move past the `\` character. - ++$offset; - $ident .= self::consume_escaped_codepoint( $input, $offset ); - continue; - } elseif ( self::is_ident_codepoint( $input, $offset ) ) { - // @todo this should append and advance the correct number of bytes. - $ident .= $input[ $offset ]; - ++$offset; - continue; - } - break; - } - - return $ident; - } - - /** - * Parse a string token - * - * > 4.3.5. Consume a string token - * > This section describes how to consume a string token from a stream of code points. It returns either a or . - * > - * > This algorithm may be called with an ending code point, which denotes the code point that ends the string. If an ending code point is not specified, the current input code point is used. - * > - * > Initially create a with its value set to the empty string. - * > - * > Repeatedly consume the next input code point from the stream: - * > - * > ending code point - * > Return the . - * > EOF - * > This is a parse error. Return the . - * > newline - * > This is a parse error. Reconsume the current input code point, create a , and return it. - * > U+005C REVERSE SOLIDUS (\) - * > If the next input code point is EOF, do nothing. - * > Otherwise, if the next input code point is a newline, consume it. - * > Otherwise, (the stream starts with a valid escape) consume an escaped code point and append the returned code point to the ’s value. - * > - * > anything else - * > Append the current input code point to the ’s value. - * - * https://www.w3.org/TR/css-syntax-3/#consume-string-token - * - * This implementation will never return a because - * the is not a part of the selector grammar. That - * case is treated as failure to parse and null is returned. - * - * @return string|null - */ - final protected static function parse_string( string $input, int &$offset ): ?string { - if ( $offset >= strlen( $input ) ) { - return null; - } - - $ending_code_point = $input[ $offset ]; - if ( '"' !== $ending_code_point && "'" !== $ending_code_point ) { - return null; - } - - $string_token = ''; - - $updated_offset = $offset + 1; - $anything_else_mask = "\\\n{$ending_code_point}"; - while ( $updated_offset < strlen( $input ) ) { - $anything_else_length = strcspn( $input, $anything_else_mask, $updated_offset ); - if ( $anything_else_length > 0 ) { - $string_token .= substr( $input, $updated_offset, $anything_else_length ); - $updated_offset += $anything_else_length; - - if ( $updated_offset >= strlen( $input ) ) { - break; - } - } - - switch ( $input[ $updated_offset ] ) { - case '\\': - ++$updated_offset; - if ( $updated_offset >= strlen( $input ) ) { - break; - } - if ( "\n" === $input[ $updated_offset ] ) { - ++$updated_offset; - break; - } else { - $string_token .= self::consume_escaped_codepoint( $input, $updated_offset ); - } - break; - - /* - * This case would return a . - * The is not a part of the selector grammar - * so we do not return it and instead treat this as a - * failure to parse a string token. - */ - case "\n": - return null; - - case $ending_code_point: - ++$updated_offset; - break 2; - } - } - - $offset = $updated_offset; - return $string_token; - } - - /** - * Consume an escaped code point. - * - * > 4.3.7. Consume an escaped code point - * > This section describes how to consume an escaped code point. It assumes that the U+005C - * > REVERSE SOLIDUS (\) has already been consumed and that the next input code point has - * > already been verified to be part of a valid escape. It will return a code point. - * > - * > Consume the next input code point. - * > - * > hex digit - * > Consume as many hex digits as possible, but no more than 5. Note that this means 1-6 - * > hex digits have been consumed in total. If the next input code point is whitespace, - * > consume it as well. Interpret the hex digits as a hexadecimal number. If this number is - * > zero, or is for a surrogate, or is greater than the maximum allowed code point, return - * > U+FFFD REPLACEMENT CHARACTER (�). Otherwise, return the code point with that value. - * > EOF - * > This is a parse error. Return U+FFFD REPLACEMENT CHARACTER (�). - * > anything else - * > Return the current input code point. - * - * @param string $input - * @param int $offset - * @return string - */ - final protected static function consume_escaped_codepoint( $input, &$offset ): string { - $hex_length = strspn( $input, '0123456789abcdefABCDEF', $offset, 6 ); - if ( $hex_length > 0 ) { - /** - * The 6-character hex string has a maximum value of 0xFFFFFF. - * It is likely to fit in an int value and not be a float. - * - * @var int - */ - $codepoint_value = hexdec( substr( $input, $offset, $hex_length ) ); - - /* - * > A surrogate is a leading surrogate or a trailing surrogate. - * > A leading surrogate is a code point that is in the range U+D800 to U+DBFF, inclusive. - * > A trailing surrogate is a code point that is in the range U+DC00 to U+DFFF, inclusive. - * - * The surrogate ranges are adjacent, so the complete range is 0xD800 to 0xDFFF, inclusive. - */ - $codepoint_char = ( - 0 === $codepoint_value || - $codepoint_value > self::UTF8_MAX_CODEPOINT_VALUE || - ( 0xD800 <= $codepoint_value && $codepoint_value <= 0xDFFF ) - ) - ? "\u{FFFD}" - : mb_chr( $codepoint_value, 'UTF-8' ); - - $offset += $hex_length; - - // If the next input code point is whitespace, consume it as well. - if ( - strlen( $input ) > $offset && - ( - "\n" === $input[ $offset ] || - "\t" === $input[ $offset ] || - ' ' === $input[ $offset ] - ) - ) { - ++$offset; - } - return $codepoint_char; - } - - $codepoint_char = mb_substr( $input, $offset, 1, 'UTF-8' ); - $offset += strlen( $codepoint_char ); - return $codepoint_char; - } - - /* - * --------------------------- - * Selector parsing utiltities - * --------------------------- - * - * The following functions are used for parsing but do not consume any input. - */ - - /** - * Checks for two valid escape codepoints. - * - * > 4.3.8. Check if two code points are a valid escape - * > This section describes how to check if two code points are a valid escape. The algorithm described here can be called explicitly with two code points, or can be called with the input stream itself. In the latter case, the two code points in question are the current input code point and the next input code point, in that order. - * > - * > Note: This algorithm will not consume any additional code point. - * > - * > If the first code point is not U+005C REVERSE SOLIDUS (\), return false. - * > - * > Otherwise, if the second code point is a newline, return false. - * > - * > Otherwise, return true. - * - * https://www.w3.org/TR/css-syntax-3/#starts-with-a-valid-escape - * - * @todo this does not check whether the second codepoint is valid. - * - * @param string $input The input string. - * @param int $offset The byte offset in the string. - * @return bool True if the next two codepoints are a valid escape, otherwise false. - */ - final protected static function next_two_are_valid_escape( string $input, int $offset ): bool { - if ( $offset + 1 >= strlen( $input ) ) { - return false; - } - return '\\' === $input[ $offset ] && "\n" !== $input[ $offset + 1 ]; - } - - /** - * Checks if the next code point is an "ident start code point". - * - * Caution! This method does not do any bounds checking, it should not be passed - * a string with an offset that is out of bounds. - * - * > ident-start code point - * > A letter, a non-ASCII code point, or U+005F LOW LINE (_). - * > uppercase letter - * > A code point between U+0041 LATIN CAPITAL LETTER A (A) and U+005A LATIN CAPITAL LETTER Z (Z) inclusive. - * > lowercase letter - * > A code point between U+0061 LATIN SMALL LETTER A (a) and U+007A LATIN SMALL LETTER Z (z) inclusive. - * > letter - * > An uppercase letter or a lowercase letter. - * > non-ASCII code point - * > A code point with a value equal to or greater than U+0080 . - * - * @link https://www.w3.org/TR/css-syntax-3/#ident-start-code-point - * - * @param string $input The input string. - * @param int $offset The byte offset in the string. - * @return bool True if the next codepoint is an ident start code point, otherwise false. - */ - final protected static function is_ident_start_codepoint( string $input, int $offset ): bool { - return ( - '_' === $input[ $offset ] || - ( 'a' <= $input[ $offset ] && $input[ $offset ] <= 'z' ) || - ( 'A' <= $input[ $offset ] && $input[ $offset ] <= 'Z' ) || - ord( $input[ $offset ] ) > 0x7F - ); - } - - /** - * Checks if the next code point is an "ident code point". - * - * Caution! This method does not do any bounds checking, it should not be passed - * a string with an offset that is out of bounds. - * - * > ident code point - * > An ident-start code point, a digit, or U+002D HYPHEN-MINUS (-). - * > digit - * > A code point between U+0030 DIGIT ZERO (0) and U+0039 DIGIT NINE (9) inclusive. - * - * @link https://www.w3.org/TR/css-syntax-3/#ident-code-point - * - * @param string $input The input string. - * @param int $offset The byte offset in the string. - * @return bool True if the next codepoint is an ident code point, otherwise false. - */ - final protected static function is_ident_codepoint( string $input, int $offset ): bool { - return '-' === $input[ $offset ] || - ( '0' <= $input[ $offset ] && $input[ $offset ] <= '9' ) || - self::is_ident_start_codepoint( $input, $offset ); - } - - /** - * Checks if three code points would start an ident sequence. - * - * > 4.3.9. Check if three code points would start an ident sequence - * > This section describes how to check if three code points would start an ident sequence. The algorithm described here can be called explicitly with three code points, or can be called with the input stream itself. In the latter case, the three code points in question are the current input code point and the next two input code points, in that order. - * > - * > Note: This algorithm will not consume any additional code points. - * > - * > Look at the first code point: - * > - * > U+002D HYPHEN-MINUS - * > If the second code point is an ident-start code point or a U+002D HYPHEN-MINUS, or the second and third code points are a valid escape, return true. Otherwise, return false. - * > ident-start code point - * > Return true. - * > U+005C REVERSE SOLIDUS (\) - * > If the first and second code points are a valid escape, return true. Otherwise, return false. - * > anything else - * > Return false. - * - * @link https://www.w3.org/TR/css-syntax-3/#would-start-an-identifier - * - * @param string $input The input string. - * @param int $offset The byte offset in the string. - * @return bool True if the next three codepoints would start an ident sequence, otherwise false. - */ - final protected static function check_if_three_code_points_would_start_an_ident_sequence( string $input, int $offset ): bool { - if ( $offset >= strlen( $input ) ) { - return false; - } - - // > U+005C REVERSE SOLIDUS (\) - if ( '\\' === $input[ $offset ] ) { - return self::next_two_are_valid_escape( $input, $offset ); - } - - // > U+002D HYPHEN-MINUS - if ( '-' === $input[ $offset ] ) { - $after_initial_hyphen_minus_offset = $offset + 1; - if ( $after_initial_hyphen_minus_offset >= strlen( $input ) ) { - return false; - } - - // > If the second code point is… U+002D HYPHEN-MINUS… return true - if ( '-' === $input[ $after_initial_hyphen_minus_offset ] ) { - return true; - } - - // > If the second and third code points are a valid escape… return true. - if ( self::next_two_are_valid_escape( $input, $after_initial_hyphen_minus_offset ) ) { - return true; - } - - // > If the second code point is an ident-start code point… return true. - if ( self::is_ident_start_codepoint( $input, $after_initial_hyphen_minus_offset ) ) { - return true; - } - - // > Otherwise, return false. - return false; - } - - // > ident-start code point - // > Return true. - // > anything else - // > Return false. - return self::is_ident_start_codepoint( $input, $offset ); - } - - /** - * @todo doc… - */ - final protected static function normalize_selector_input( string $input ): string { - /* - * > A selector string is a list of one or more complex selectors ([SELECTORS4], section 3.1) that may be surrounded by whitespace… - * - * This list includes \f. - * A later step would normalize it to a known whitespace character, but it can be trimmed here as well. - */ - $input = trim( $input, " \t\r\n\r\f" ); - - /* - * > The input stream consists of the filtered code points pushed into it as the input byte stream is decoded. - * > - * > To filter code points from a stream of (unfiltered) code points input: - * > Replace any U+000D CARRIAGE RETURN (CR) code points, U+000C FORM FEED (FF) code points, or pairs of U+000D CARRIAGE RETURN (CR) followed by U+000A LINE FEED (LF) in input by a single U+000A LINE FEED (LF) code point. - * > Replace any U+0000 NULL or surrogate code points in input with U+FFFD REPLACEMENT CHARACTER (�). - * - * https://www.w3.org/TR/css-syntax-3/#input-preprocessing - */ - $input = str_replace( array( "\r\n" ), "\n", $input ); - $input = str_replace( array( "\r", "\f" ), "\n", $input ); - $input = str_replace( "\0", "\u{FFFD}", $input ); - - return $input; - } } diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector.php b/src/wp-includes/html-api/class-wp-css-compound-selector.php index 9596876685212..68aca4d880e0d 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector.php @@ -21,7 +21,7 @@ * * @access private */ -final class WP_CSS_Compound_Selector implements WP_CSS_HTML_Tag_Processor_Matcher { +final class WP_CSS_Compound_Selector extends WP_CSS_Selector_Parser_Matcher { /** * The type selector. * @@ -69,4 +69,62 @@ public function matches( WP_HTML_Tag_Processor $processor ): bool { } return true; } + + /** + * Parses a selector string to create a selector instance. + * + * To create an instance of this class, use the {@see WP_CSS_Compound_Selector_List::from_selectors()} method. + * + * @param string $input The selector string. + * @param int $offset The offset into the string. The offset is passed by reference and + * will be updated if the parse is successful. + * @return static|null The selector instance, or null if the parse was unsuccessful. + */ + public static function parse( string $input, int &$offset ): ?static { + if ( $offset >= strlen( $input ) ) { + return null; + } + + $updated_offset = $offset; + $type_selector = WP_CSS_Type_Selector::parse( $input, $updated_offset ); + + $subclass_selectors = array(); + $last_parsed_subclass_selector = self::parse_subclass_selector( $input, $updated_offset ); + while ( null !== $last_parsed_subclass_selector ) { + $subclass_selectors[] = $last_parsed_subclass_selector; + $last_parsed_subclass_selector = self::parse_subclass_selector( $input, $updated_offset ); + } + + // @todo invert this condition + if ( null !== $type_selector || array() !== $subclass_selectors ) { + $offset = $updated_offset; + return new self( $type_selector, $subclass_selectors ); + } + return null; + } + + /** + * Parses a subclass selector. + * + * > = | | + * + * @return WP_CSS_ID_Selector|WP_CSS_Class_Selector|WP_CSS_Attribute_Selector|null + */ + private static function parse_subclass_selector( string $input, int &$offset ) { + if ( $offset >= strlen( $input ) ) { + return null; + } + + $next_char = $input[ $offset ]; + return '.' === $next_char + ? WP_CSS_Class_Selector::parse( $input, $offset ) + : ( + '#' === $next_char + ? WP_CSS_ID_Selector::parse( $input, $offset ) + : ( '[' === $next_char + ? WP_CSS_Attribute_Selector::parse( $input, $offset ) + : null + ) + ); + } } diff --git a/src/wp-includes/html-api/class-wp-css-id-selector.php b/src/wp-includes/html-api/class-wp-css-id-selector.php index 2a600923fa2a2..de854c37eea9f 100644 --- a/src/wp-includes/html-api/class-wp-css-id-selector.php +++ b/src/wp-includes/html-api/class-wp-css-id-selector.php @@ -16,7 +16,7 @@ * * @access private */ -final class WP_CSS_ID_Selector implements WP_CSS_HTML_Tag_Processor_Matcher { +final class WP_CSS_ID_Selector extends WP_CSS_Selector_Parser_Matcher { /** * The ID to match. * @@ -48,7 +48,25 @@ public function matches( WP_HTML_Tag_Processor $processor ): bool { $case_insensitive = $processor->is_quirks_mode(); return $case_insensitive - ? 0 === strcasecmp( $id, $this->id ) - : $processor->get_attribute( 'id' ) === $this->id; + ? 0 === strcasecmp( $id, $this->id ) + : $processor->get_attribute( 'id' ) === $this->id; + } + + /** + * Parses a selector string to create a selector instance. + * + * To create an instance of this class, use the {@see WP_CSS_Compound_Selector_List::from_selectors()} method. + * + * @param string $input The selector string. + * @param int $offset The offset into the string. The offset is passed by reference and + * will be updated if the parse is successful. + * @return static|null The selector instance, or null if the parse was unsuccessful. + */ + public static function parse( string $input, int &$offset ): ?static { + $ident = self::parse_hash_token( $input, $offset ); + if ( null === $ident ) { + return null; + } + return new self( $ident ); } } diff --git a/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php b/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php new file mode 100644 index 0000000000000..8820115f03cfb --- /dev/null +++ b/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php @@ -0,0 +1,476 @@ + 0; + $offset += $length; + return $advanced; + } + + /** + * Tokenization of hash tokens + * + * > U+0023 NUMBER SIGN (#) + * > If the next input code point is an ident code point or the next two input code points are a valid escape, then: + * > 1. Create a . + * > 2. If the next 3 input code points would start an ident sequence, set the + * > ’s type flag to "id". + * > 3. Consume an ident sequence, and set the ’s value to the + * > returned string. + * > 4. Return the . + * > Otherwise, return a with its value set to the current input code point. + * + * This implementation is not interested in the , a '#' delim token is not relevant for selectors. + */ + final protected static function parse_hash_token( string $input, int &$offset ): ?string { + if ( $offset + 1 >= strlen( $input ) || '#' !== $input[ $offset ] ) { + return null; + } + + $updated_offset = $offset + 1; + $result = self::parse_ident( $input, $updated_offset ); + + if ( null === $result ) { + return null; + } + + $offset = $updated_offset; + return $result; + } + + /** + * Parse a string token + * + * > 4.3.5. Consume a string token + * > This section describes how to consume a string token from a stream of code points. It returns either a or . + * > + * > This algorithm may be called with an ending code point, which denotes the code point that ends the string. If an ending code point is not specified, the current input code point is used. + * > + * > Initially create a with its value set to the empty string. + * > + * > Repeatedly consume the next input code point from the stream: + * > + * > ending code point + * > Return the . + * > EOF + * > This is a parse error. Return the . + * > newline + * > This is a parse error. Reconsume the current input code point, create a , and return it. + * > U+005C REVERSE SOLIDUS (\) + * > If the next input code point is EOF, do nothing. + * > Otherwise, if the next input code point is a newline, consume it. + * > Otherwise, (the stream starts with a valid escape) consume an escaped code point and append the returned code point to the ’s value. + * > + * > anything else + * > Append the current input code point to the ’s value. + * + * https://www.w3.org/TR/css-syntax-3/#consume-string-token + * + * This implementation will never return a because + * the is not a part of the selector grammar. That + * case is treated as failure to parse and null is returned. + * + * @return string|null + */ + final protected static function parse_string( string $input, int &$offset ): ?string { + if ( $offset >= strlen( $input ) ) { + return null; + } + + $ending_code_point = $input[ $offset ]; + if ( '"' !== $ending_code_point && "'" !== $ending_code_point ) { + return null; + } + + $string_token = ''; + + $updated_offset = $offset + 1; + $anything_else_mask = "\\\n{$ending_code_point}"; + while ( $updated_offset < strlen( $input ) ) { + $anything_else_length = strcspn( $input, $anything_else_mask, $updated_offset ); + if ( $anything_else_length > 0 ) { + $string_token .= substr( $input, $updated_offset, $anything_else_length ); + $updated_offset += $anything_else_length; + + if ( $updated_offset >= strlen( $input ) ) { + break; + } + } + + switch ( $input[ $updated_offset ] ) { + case '\\': + ++$updated_offset; + if ( $updated_offset >= strlen( $input ) ) { + break; + } + if ( "\n" === $input[ $updated_offset ] ) { + ++$updated_offset; + break; + } else { + $string_token .= self::consume_escaped_codepoint( $input, $updated_offset ); + } + break; + + /* + * This case would return a . + * The is not a part of the selector grammar + * so we do not return it and instead treat this as a + * failure to parse a string token. + */ + case "\n": + return null; + + case $ending_code_point: + ++$updated_offset; + break 2; + } + } + + $offset = $updated_offset; + return $string_token; + } + + /** + * Consume an escaped code point. + * + * > 4.3.7. Consume an escaped code point + * > This section describes how to consume an escaped code point. It assumes that the U+005C + * > REVERSE SOLIDUS (\) has already been consumed and that the next input code point has + * > already been verified to be part of a valid escape. It will return a code point. + * > + * > Consume the next input code point. + * > + * > hex digit + * > Consume as many hex digits as possible, but no more than 5. Note that this means 1-6 + * > hex digits have been consumed in total. If the next input code point is whitespace, + * > consume it as well. Interpret the hex digits as a hexadecimal number. If this number is + * > zero, or is for a surrogate, or is greater than the maximum allowed code point, return + * > U+FFFD REPLACEMENT CHARACTER (�). Otherwise, return the code point with that value. + * > EOF + * > This is a parse error. Return U+FFFD REPLACEMENT CHARACTER (�). + * > anything else + * > Return the current input code point. + * + * @param string $input + * @param int $offset + * @return string + */ + final protected static function consume_escaped_codepoint( $input, &$offset ): string { + $hex_length = strspn( $input, '0123456789abcdefABCDEF', $offset, 6 ); + if ( $hex_length > 0 ) { + /** + * The 6-character hex string has a maximum value of 0xFFFFFF. + * It is likely to fit in an int value and not be a float. + * + * @var int + */ + $codepoint_value = hexdec( substr( $input, $offset, $hex_length ) ); + + /* + * > A surrogate is a leading surrogate or a trailing surrogate. + * > A leading surrogate is a code point that is in the range U+D800 to U+DBFF, inclusive. + * > A trailing surrogate is a code point that is in the range U+DC00 to U+DFFF, inclusive. + * + * The surrogate ranges are adjacent, so the complete range is 0xD800 to 0xDFFF, inclusive. + */ + $codepoint_char = ( + 0 === $codepoint_value || + $codepoint_value > self::UTF8_MAX_CODEPOINT_VALUE || + ( 0xD800 <= $codepoint_value && $codepoint_value <= 0xDFFF ) + ) + ? "\u{FFFD}" + : mb_chr( $codepoint_value, 'UTF-8' ); + + $offset += $hex_length; + + // If the next input code point is whitespace, consume it as well. + if ( + strlen( $input ) > $offset && + ( + "\n" === $input[ $offset ] || + "\t" === $input[ $offset ] || + ' ' === $input[ $offset ] + ) + ) { + ++$offset; + } + return $codepoint_char; + } + + $codepoint_char = mb_substr( $input, $offset, 1, 'UTF-8' ); + $offset += strlen( $codepoint_char ); + return $codepoint_char; + } + + /** + * Parse an ident token + * + * CAUTION: This method is _not_ for parsing and ID selector! + * + * > 4.3.11. Consume an ident sequence + * > This section describes how to consume an ident sequence from a stream of code points. It returns a string containing the largest name that can be formed from adjacent code points in the stream, starting from the first. + * > + * > Note: This algorithm does not do the verification of the first few code points that are necessary to ensure the returned code points would constitute an . If that is the intended use, ensure that the stream starts with an ident sequence before calling this algorithm. + * > + * > Let result initially be an empty string. + * > + * > Repeatedly consume the next input code point from the stream: + * > + * > ident code point + * > Append the code point to result. + * > the stream starts with a valid escape + * > Consume an escaped code point. Append the returned code point to result. + * > anything else + * > Reconsume the current input code point. Return result. + * + * https://www.w3.org/TR/css-syntax-3/#consume-name + * + * @return string|null + */ + final protected static function parse_ident( string $input, int &$offset ): ?string { + if ( ! self::check_if_three_code_points_would_start_an_ident_sequence( $input, $offset ) ) { + return null; + } + + $ident = ''; + + while ( $offset < strlen( $input ) ) { + if ( self::next_two_are_valid_escape( $input, $offset ) ) { + // Move past the `\` character. + ++$offset; + $ident .= self::consume_escaped_codepoint( $input, $offset ); + continue; + } elseif ( self::is_ident_codepoint( $input, $offset ) ) { + // @todo this should append and advance the correct number of bytes. + $ident .= $input[ $offset ]; + ++$offset; + continue; + } + break; + } + + return $ident; + } + + /* + * -------------------------- + * Selector parsing utilities + * -------------------------- + * + * The following functions are used for parsing but do not consume any input. + */ + + /** + * Checks for two valid escape codepoints. + * + * > 4.3.8. Check if two code points are a valid escape + * > This section describes how to check if two code points are a valid escape. The algorithm described here can be called explicitly with two code points, or can be called with the input stream itself. In the latter case, the two code points in question are the current input code point and the next input code point, in that order. + * > + * > Note: This algorithm will not consume any additional code point. + * > + * > If the first code point is not U+005C REVERSE SOLIDUS (\), return false. + * > + * > Otherwise, if the second code point is a newline, return false. + * > + * > Otherwise, return true. + * + * https://www.w3.org/TR/css-syntax-3/#starts-with-a-valid-escape + * + * @todo this does not check whether the second codepoint is valid. + * + * @param string $input The input string. + * @param int $offset The byte offset in the string. + * @return bool True if the next two codepoints are a valid escape, otherwise false. + */ + final protected static function next_two_are_valid_escape( string $input, int $offset ): bool { + if ( $offset + 1 >= strlen( $input ) ) { + return false; + } + return '\\' === $input[ $offset ] && "\n" !== $input[ $offset + 1 ]; + } + + /** + * Checks if the next code point is an "ident start code point". + * + * Caution! This method does not do any bounds checking, it should not be passed + * a string with an offset that is out of bounds. + * + * > ident-start code point + * > A letter, a non-ASCII code point, or U+005F LOW LINE (_). + * > uppercase letter + * > A code point between U+0041 LATIN CAPITAL LETTER A (A) and U+005A LATIN CAPITAL LETTER Z (Z) inclusive. + * > lowercase letter + * > A code point between U+0061 LATIN SMALL LETTER A (a) and U+007A LATIN SMALL LETTER Z (z) inclusive. + * > letter + * > An uppercase letter or a lowercase letter. + * > non-ASCII code point + * > A code point with a value equal to or greater than U+0080 . + * + * @link https://www.w3.org/TR/css-syntax-3/#ident-start-code-point + * + * @param string $input The input string. + * @param int $offset The byte offset in the string. + * @return bool True if the next codepoint is an ident start code point, otherwise false. + */ + final protected static function is_ident_start_codepoint( string $input, int $offset ): bool { + return ( + '_' === $input[ $offset ] || + ( 'a' <= $input[ $offset ] && $input[ $offset ] <= 'z' ) || + ( 'A' <= $input[ $offset ] && $input[ $offset ] <= 'Z' ) || + ord( $input[ $offset ] ) > 0x7F + ); + } + + /** + * Checks if the next code point is an "ident code point". + * + * Caution! This method does not do any bounds checking, it should not be passed + * a string with an offset that is out of bounds. + * + * > ident code point + * > An ident-start code point, a digit, or U+002D HYPHEN-MINUS (-). + * > digit + * > A code point between U+0030 DIGIT ZERO (0) and U+0039 DIGIT NINE (9) inclusive. + * + * @link https://www.w3.org/TR/css-syntax-3/#ident-code-point + * + * @param string $input The input string. + * @param int $offset The byte offset in the string. + * @return bool True if the next codepoint is an ident code point, otherwise false. + */ + final protected static function is_ident_codepoint( string $input, int $offset ): bool { + return '-' === $input[ $offset ] || + ( '0' <= $input[ $offset ] && $input[ $offset ] <= '9' ) || + self::is_ident_start_codepoint( $input, $offset ); + } + + /** + * Checks if three code points would start an ident sequence. + * + * > 4.3.9. Check if three code points would start an ident sequence + * > This section describes how to check if three code points would start an ident sequence. The algorithm described here can be called explicitly with three code points, or can be called with the input stream itself. In the latter case, the three code points in question are the current input code point and the next two input code points, in that order. + * > + * > Note: This algorithm will not consume any additional code points. + * > + * > Look at the first code point: + * > + * > U+002D HYPHEN-MINUS + * > If the second code point is an ident-start code point or a U+002D HYPHEN-MINUS, or the second and third code points are a valid escape, return true. Otherwise, return false. + * > ident-start code point + * > Return true. + * > U+005C REVERSE SOLIDUS (\) + * > If the first and second code points are a valid escape, return true. Otherwise, return false. + * > anything else + * > Return false. + * + * @link https://www.w3.org/TR/css-syntax-3/#would-start-an-identifier + * + * @param string $input The input string. + * @param int $offset The byte offset in the string. + * @return bool True if the next three codepoints would start an ident sequence, otherwise false. + */ + final protected static function check_if_three_code_points_would_start_an_ident_sequence( string $input, int $offset ): bool { + if ( $offset >= strlen( $input ) ) { + return false; + } + + // > U+005C REVERSE SOLIDUS (\) + if ( '\\' === $input[ $offset ] ) { + return self::next_two_are_valid_escape( $input, $offset ); + } + + // > U+002D HYPHEN-MINUS + if ( '-' === $input[ $offset ] ) { + $after_initial_hyphen_minus_offset = $offset + 1; + if ( $after_initial_hyphen_minus_offset >= strlen( $input ) ) { + return false; + } + + // > If the second code point is… U+002D HYPHEN-MINUS… return true + if ( '-' === $input[ $after_initial_hyphen_minus_offset ] ) { + return true; + } + + // > If the second and third code points are a valid escape… return true. + if ( self::next_two_are_valid_escape( $input, $after_initial_hyphen_minus_offset ) ) { + return true; + } + + // > If the second code point is an ident-start code point… return true. + if ( self::is_ident_start_codepoint( $input, $after_initial_hyphen_minus_offset ) ) { + return true; + } + + // > Otherwise, return false. + return false; + } + + // > ident-start code point + // > Return true. + // > anything else + // > Return false. + return self::is_ident_start_codepoint( $input, $offset ); + } + + /** + * @todo doc… + */ + final protected static function normalize_selector_input( string $input ): string { + /* + * > A selector string is a list of one or more complex selectors ([SELECTORS4], section 3.1) that may be surrounded by whitespace… + * + * This list includes \f. + * A later step would normalize it to a known whitespace character, but it can be trimmed here as well. + */ + $input = trim( $input, " \t\r\n\r\f" ); + + /* + * > The input stream consists of the filtered code points pushed into it as the input byte stream is decoded. + * > + * > To filter code points from a stream of (unfiltered) code points input: + * > Replace any U+000D CARRIAGE RETURN (CR) code points, U+000C FORM FEED (FF) code points, or pairs of U+000D CARRIAGE RETURN (CR) followed by U+000A LINE FEED (LF) in input by a single U+000A LINE FEED (LF) code point. + * > Replace any U+0000 NULL or surrogate code points in input with U+FFFD REPLACEMENT CHARACTER (�). + * + * https://www.w3.org/TR/css-syntax-3/#input-preprocessing + */ + $input = str_replace( array( "\r\n" ), "\n", $input ); + $input = str_replace( array( "\r", "\f" ), "\n", $input ); + $input = str_replace( "\0", "\u{FFFD}", $input ); + + return $input; + } +} diff --git a/src/wp-includes/html-api/class-wp-css-type-selector.php b/src/wp-includes/html-api/class-wp-css-type-selector.php index 3f7671851c375..492569ee51d65 100644 --- a/src/wp-includes/html-api/class-wp-css-type-selector.php +++ b/src/wp-includes/html-api/class-wp-css-type-selector.php @@ -16,7 +16,7 @@ * * @access private */ -final class WP_CSS_Type_Selector implements WP_CSS_HTML_Tag_Processor_Matcher { +final class WP_CSS_Type_Selector extends WP_CSS_Selector_Parser_Matcher { /** * The element type (tag name) to match or '*' to match any element. * @@ -59,4 +59,32 @@ public function matches_tag( string $tag_name ): bool { } return 0 === strcasecmp( $tag_name, $this->type ); } + + /** + * Parses a selector string to create a selector instance. + * + * To create an instance of this class, use the {@see WP_CSS_Compound_Selector_List::from_selectors()} method. + * + * @param string $input The selector string. + * @param int $offset The offset into the string. The offset is passed by reference and + * will be updated if the parse is successful. + * @return static|null The selector instance, or null if the parse was unsuccessful. + */ + public static function parse( string $input, int &$offset ): ?static { + if ( $offset >= strlen( $input ) ) { + return null; + } + + if ( '*' === $input[ $offset ] ) { + ++$offset; + return new WP_CSS_Type_Selector( '*' ); + } + + $result = self::parse_ident( $input, $offset ); + if ( null === $result ) { + return null; + } + + return new self( $result ); + } } diff --git a/src/wp-includes/html-api/interface-wp-css-html-processor-matcher.php b/src/wp-includes/html-api/interface-wp-css-html-processor-matcher.php deleted file mode 100644 index b77ef40931d83..0000000000000 --- a/src/wp-includes/html-api/interface-wp-css-html-processor-matcher.php +++ /dev/null @@ -1,11 +0,0 @@ - Date: Wed, 11 Dec 2024 18:44:24 +0100 Subject: [PATCH 117/634] Update tests for class parsing --- .../tests/html-api/wpCssAttributeSelector.php | 90 ++++ .../tests/html-api/wpCssClassSelector.php | 49 +++ .../tests/html-api/wpCssComplexSelector.php | 71 ++++ .../html-api/wpCssComplexSelectorList.php | 73 +--- .../tests/html-api/wpCssCompoundSelector.php | 44 ++ .../html-api/wpCssCompoundSelectorList.php | 395 +----------------- .../tests/html-api/wpCssIdSelector.php | 50 +++ .../html-api/wpCssSelectorParserMatcher.php | 172 ++++++++ .../tests/html-api/wpCssTypeSelector.php | 51 +++ 9 files changed, 532 insertions(+), 463 deletions(-) create mode 100644 tests/phpunit/tests/html-api/wpCssAttributeSelector.php create mode 100644 tests/phpunit/tests/html-api/wpCssClassSelector.php create mode 100644 tests/phpunit/tests/html-api/wpCssComplexSelector.php create mode 100644 tests/phpunit/tests/html-api/wpCssCompoundSelector.php create mode 100644 tests/phpunit/tests/html-api/wpCssIdSelector.php create mode 100644 tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php create mode 100644 tests/phpunit/tests/html-api/wpCssTypeSelector.php diff --git a/tests/phpunit/tests/html-api/wpCssAttributeSelector.php b/tests/phpunit/tests/html-api/wpCssAttributeSelector.php new file mode 100644 index 0000000000000..d907ad7c07e5b --- /dev/null +++ b/tests/phpunit/tests/html-api/wpCssAttributeSelector.php @@ -0,0 +1,90 @@ +assertNull( $result ); + } else { + $this->assertSame( $expected_name, $result->name ); + $this->assertSame( $expected_matcher, $result->matcher ); + $this->assertSame( $expected_value, $result->value ); + $this->assertSame( $expected_modifier, $result->modifier ); + $this->assertSame( $rest, substr( $input, $offset ) ); + } + } + + /** + * Data provider. + * + * @return array + */ + public static function data_attribute_selectors(): array { + return array( + '[href]' => array( '[href]', 'href', null, null, null, '' ), + '[href] type' => array( '[href] type', 'href', null, null, null, ' type' ), + '[href]#id' => array( '[href]#id', 'href', null, null, null, '#id' ), + '[href].class' => array( '[href].class', 'href', null, null, null, '.class' ), + '[href][href2]' => array( '[href][href2]', 'href', null, null, null, '[href2]' ), + '[\n href\t\r]' => array( "[\n href\t\r]", 'href', null, null, null, '' ), + '[href=foo]' => array( '[href=foo]', 'href', WP_CSS_Attribute_Selector::MATCH_EXACT, 'foo', null, '' ), + '[href \n = bar ]' => array( "[href \n = bar ]", 'href', WP_CSS_Attribute_Selector::MATCH_EXACT, 'bar', null, '' ), + '[href \n ^= baz ]' => array( "[href \n ^= baz ]", 'href', WP_CSS_Attribute_Selector::MATCH_PREFIXED_BY, 'baz', null, '' ), + + '[match $= insensitive i]' => array( '[match $= insensitive i]', 'match', WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY, 'insensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), + '[match|=sensitive s]' => array( '[match|=sensitive s]', 'match', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_HYPHEN_PREFIXED, 'sensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), + '[att=val I]' => array( '[att=val I]', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'val', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), + '[att=val S]' => array( '[att=val S]', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'val', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), + + '[match~="quoted[][]"]' => array( '[match~="quoted[][]"]', 'match', WP_CSS_Attribute_Selector::MATCH_ONE_OF_EXACT, 'quoted[][]', null, '' ), + "[match$='quoted!{}']" => array( "[match$='quoted!{}']", 'match', WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY, 'quoted!{}', null, '' ), + "[match*='quoted's]" => array( "[match*='quoted's]", 'match', WP_CSS_Attribute_Selector::MATCH_CONTAINS, 'quoted', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), + + '[escape-nl="foo\\nbar"]' => array( "[escape-nl='foo\\\nbar']", 'escape-nl', WP_CSS_Attribute_Selector::MATCH_EXACT, 'foobar', null, '' ), + '[escape-seq="\\31 23"]' => array( "[escape-seq='\\31 23']", 'escape-seq', WP_CSS_Attribute_Selector::MATCH_EXACT, '123', null, '' ), + + // Invalid + 'Invalid: (empty string)' => array( '' ), + 'Invalid: foo' => array( 'foo' ), + 'Invalid: [foo' => array( '[foo' ), + 'Invalid: [#foo]' => array( '[#foo]' ), + 'Invalid: [*|*]' => array( '[*|*]' ), + 'Invalid: [ns|*]' => array( '[ns|*]' ), + 'Invalid: [* |att]' => array( '[* |att]' ), + 'Invalid: [*| att]' => array( '[*| att]' ), + 'Invalid: [att * =]' => array( '[att * =]' ), + 'Invalid: [att+=val]' => array( '[att+=val]' ), + 'Invalid: [att=val ' => array( '[att=val ' ), + 'Invalid: [att i]' => array( '[att i]' ), + 'Invalid: [att s]' => array( '[att s]' ), + "Invalid: [att='val\\n']" => array( "[att='val\n']" ), + 'Invalid: [att=val i ' => array( '[att=val i ' ), + 'Invalid: [att="val"ix' => array( '[att="val"ix' ), + ); + } +} diff --git a/tests/phpunit/tests/html-api/wpCssClassSelector.php b/tests/phpunit/tests/html-api/wpCssClassSelector.php new file mode 100644 index 0000000000000..fa1d097a5ad3d --- /dev/null +++ b/tests/phpunit/tests/html-api/wpCssClassSelector.php @@ -0,0 +1,49 @@ +assertNull( $result ); + } else { + $this->assertSame( $expected, $result->class_name ); + $this->assertSame( $rest, substr( $input, $offset ) ); + } + } + + /** + * Data provider. + * + * @return array + */ + public static function data_class_selectors(): array { + return array( + 'valid ._-foo123' => array( '._-foo123', '_-foo123', '' ), + 'valid .foo.bar' => array( '.foo.bar', 'foo', '.bar' ), + 'escaped .\31 23' => array( '.\\31 23', '123', '' ), + 'with descendant .\31 23 div' => array( '.\\31 23 div', '123', ' div' ), + + 'not class foo' => array( 'foo' ), + 'not class #bar' => array( '#bar' ), + 'not valid .1foo' => array( '.1foo' ), + ); + } +} diff --git a/tests/phpunit/tests/html-api/wpCssComplexSelector.php b/tests/phpunit/tests/html-api/wpCssComplexSelector.php new file mode 100644 index 0000000000000..bb7b6e67e9d1a --- /dev/null +++ b/tests/phpunit/tests/html-api/wpCssComplexSelector.php @@ -0,0 +1,71 @@ + .child#bar[baz=quux] , rest'; + $offset = 0; + + /** @var WP_CSS_Complex_Selector|null */ + $sel = WP_CSS_Complex_Selector::parse( $input, $offset ); + + $this->assertSame( 2, count( $sel->context_selectors ) ); + + // Relative selectors should be reverse ordered. + $this->assertSame( 'el2', $sel->context_selectors[0][0]->type ); + $this->assertSame( WP_CSS_Complex_Selector::COMBINATOR_CHILD, $sel->context_selectors[0][1] ); + + $this->assertSame( 'el1', $sel->context_selectors[1][0]->type ); + $this->assertSame( WP_CSS_Complex_Selector::COMBINATOR_DESCENDANT, $sel->context_selectors[1][1] ); + + $this->assertSame( 3, count( $sel->self_selector->subclass_selectors ) ); + $this->assertNull( $sel->self_selector->type_selector ); + $this->assertSame( 'child', $sel->self_selector->subclass_selectors[0]->class_name ); + + $this->assertSame( ', rest', substr( $input, $offset ) ); + } + + /** + * @ticket 62653 + */ + public function test_parse_invalid_complex_selector() { + $input = 'el.foo#bar[baz=quux] > , rest'; + $offset = 0; + $result = WP_CSS_Complex_Selector::parse( $input, $offset ); + $this->assertNull( $result ); + } + + /** + * @ticket 62653 + */ + public function test_parse_invalid_complex_selector_nonfinal_subclass() { + $input = 'el.foo#bar[baz=quux] > final, rest'; + $offset = 0; + $result = WP_CSS_Complex_Selector::parse( $input, $offset ); + $this->assertNull( $result ); + } + + /** + * @ticket 62653 + */ + public function test_parse_empty_complex_selector() { + $input = ''; + $offset = 0; + $result = WP_CSS_Complex_Selector::parse( $input, $offset ); + $this->assertNull( $result ); + } +} diff --git a/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php b/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php index 829af95a55d5f..4e788860ff53f 100644 --- a/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php +++ b/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php @@ -9,79 +9,10 @@ * @since 6.8.0 * * @group html-api + * + * @coversDefaultClass WP_CSS_Complex_Selector_List */ class Tests_HtmlApi_WpCssComplexSelectorList extends WP_UnitTestCase { - private $test_class; - - public function set_up(): void { - parent::set_up(); - $this->test_class = new class() extends WP_CSS_Complex_Selector_List { - public function __construct() { - parent::__construct( array() ); - } - - public static function test_parse_complex_selector( string $input, int &$offset ): ?WP_CSS_Complex_Selector { - return self::parse_complex_selector( $input, $offset ); - } - }; - } - - /** - * @ticket 62653 - */ - public function test_parse_complex_selector() { - $input = 'el1 el2 > .child#bar[baz=quux] , rest'; - $offset = 0; - - /** @var WP_CSS_Complex_Selector|null */ - $sel = $this->test_class::test_parse_complex_selector( $input, $offset ); - - $this->assertSame( 2, count( $sel->context_selectors ) ); - - // Relative selectors should be reverse ordered. - $this->assertSame( 'el2', $sel->context_selectors[0][0]->type ); - $this->assertSame( WP_CSS_Complex_Selector::COMBINATOR_CHILD, $sel->context_selectors[0][1] ); - - $this->assertSame( 'el1', $sel->context_selectors[1][0]->type ); - $this->assertSame( WP_CSS_Complex_Selector::COMBINATOR_DESCENDANT, $sel->context_selectors[1][1] ); - - $this->assertSame( 3, count( $sel->self_selector->subclass_selectors ) ); - $this->assertNull( $sel->self_selector->type_selector ); - $this->assertSame( 'child', $sel->self_selector->subclass_selectors[0]->class_name ); - - $this->assertSame( ', rest', substr( $input, $offset ) ); - } - - /** - * @ticket 62653 - */ - public function test_parse_invalid_complex_selector() { - $input = 'el.foo#bar[baz=quux] > , rest'; - $offset = 0; - $result = $this->test_class::test_parse_complex_selector( $input, $offset ); - $this->assertNull( $result ); - } - - /** - * @ticket 62653 - */ - public function test_parse_invalid_complex_selector_nonfinal_subclass() { - $input = 'el.foo#bar[baz=quux] > final, rest'; - $offset = 0; - $result = $this->test_class::test_parse_complex_selector( $input, $offset ); - $this->assertNull( $result ); - } - - /** - * @ticket 62653 - */ - public function test_parse_empty_complex_selector() { - $input = ''; - $offset = 0; - $result = $this->test_class::test_parse_complex_selector( $input, $offset ); - $this->assertNull( $result ); - } - /** * @ticket 62653 */ diff --git a/tests/phpunit/tests/html-api/wpCssCompoundSelector.php b/tests/phpunit/tests/html-api/wpCssCompoundSelector.php new file mode 100644 index 0000000000000..8800c89d6ed36 --- /dev/null +++ b/tests/phpunit/tests/html-api/wpCssCompoundSelector.php @@ -0,0 +1,44 @@ + .child'; + $offset = 0; + $sel = WP_CSS_Compound_Selector::parse( $input, $offset ); + + $this->assertSame( 'el', $sel->type_selector->type ); + $this->assertSame( 3, count( $sel->subclass_selectors ) ); + $this->assertSame( 'foo', $sel->subclass_selectors[0]->class_name, 'foo' ); + $this->assertSame( 'bar', $sel->subclass_selectors[1]->id, 'bar' ); + $this->assertSame( 'baz', $sel->subclass_selectors[2]->name, 'baz' ); + $this->assertSame( WP_CSS_Attribute_Selector::MATCH_EXACT, $sel->subclass_selectors[2]->matcher ); + $this->assertSame( 'quux', $sel->subclass_selectors[2]->value ); + $this->assertSame( ' > .child', substr( $input, $offset ) ); + } + + /** + * @ticket 62653 + */ + public function test_parse_empty_selector() { + $input = ''; + $offset = 0; + $result = WP_CSS_Compound_Selector::parse( $input, $offset ); + $this->assertNull( $result ); + $this->assertSame( 0, $offset ); + } +} diff --git a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php index c112585e622c8..01eff118a87b0 100644 --- a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php +++ b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php @@ -1,6 +1,6 @@ test_class = new class() extends WP_CSS_Compound_Selector_List { - public function __construct() { - parent::__construct( array() ); - } - - /* - * Parsing - */ - public static function test_parse_ident( string $input, int &$offset ) { - return self::parse_ident( $input, $offset ); - } - - public static function test_parse_string( string $input, int &$offset ) { - return self::parse_string( $input, $offset ); - } - - public static function test_parse_type_selector( string $input, int &$offset ) { - return self::parse_type_selector( $input, $offset ); - } - - public static function test_parse_id_selector( string $input, int &$offset ) { - return self::parse_id_selector( $input, $offset ); - } - - public static function test_parse_class_selector( string $input, int &$offset ) { - return self::parse_class_selector( $input, $offset ); - } - - public static function test_parse_attribute_selector( string $input, int &$offset ) { - return self::parse_attribute_selector( $input, $offset ); - } - - public static function test_parse_compound_selector( string $input, int &$offset ) { - return self::parse_compound_selector( $input, $offset ); - } - - /* - * Utilities - */ - public static function test_is_ident_codepoint( string $input, int $offset ) { - return self::is_ident_codepoint( $input, $offset ); - } - - public static function test_is_ident_start_codepoint( string $input, int $offset ) { - return self::is_ident_start_codepoint( $input, $offset ); - } - }; - } - - /** - * Data provider. - * - * @return array - */ - public static function data_idents(): array { - return array( - 'trailing #' => array( '_-foo123#xyz', '_-foo123', '#xyz' ), - 'trailing .' => array( '😍foo123.xyz', '😍foo123', '.xyz' ), - 'trailing " "' => array( '😍foo123 more', '😍foo123', ' more' ), - 'escaped ASCII character' => array( '\\xyz', 'xyz', '' ), - 'escaped space' => array( '\\ x', ' x', '' ), - 'escaped emoji' => array( '\\😍', '😍', '' ), - 'hex unicode codepoint' => array( '\\1f0a1', '🂡', '' ), - 'HEX UNICODE CODEPOINT' => array( '\\1D4B2', '𝒲', '' ), - - 'hex tab-suffixed 1' => array( "\\31\t23", '123', '' ), - 'hex newline-suffixed 1' => array( "\\31\n23", '123', '' ), - 'hex space-suffixed 1' => array( "\\31 23", '123', '' ), - 'hex tab' => array( '\\9', "\t", '' ), - 'hex a' => array( '\\61 bc', 'abc', '' ), - 'hex a max escape length' => array( '\\000061bc', 'abc', '' ), - - 'out of range replacement min' => array( '\\110000 ', "\u{fffd}", '' ), - 'out of range replacement max' => array( '\\ffffff ', "\u{fffd}", '' ), - 'leading surrogate min replacement' => array( '\\d800 ', "\u{fffd}", '' ), - 'leading surrogate max replacement' => array( '\\dbff ', "\u{fffd}", '' ), - 'trailing surrogate min replacement' => array( '\\dc00 ', "\u{fffd}", '' ), - 'trailing surrogate max replacement' => array( '\\dfff ', "\u{fffd}", '' ), - 'can start with -ident' => array( '-ident', '-ident', '' ), - 'can start with --anything' => array( '--anything', '--anything', '' ), - 'can start with ---anything' => array( '--_anything', '--_anything', '' ), - 'can start with --1anything' => array( '--1anything', '--1anything', '' ), - 'can start with -\31 23' => array( '-\31 23', '-123', '' ), - 'can start with --\31 23' => array( '--\31 23', '--123', '' ), - 'ident ends before ]' => array( 'ident]', 'ident', ']' ), - - // Invalid - 'Invalid: (empty string)' => array( '' ), - 'Invalid: bad start >' => array( '>ident' ), - 'Invalid: bad start [' => array( '[ident' ), - 'Invalid: bad start #' => array( '#ident' ), - 'Invalid: bad start " "' => array( ' ident' ), - 'Invalid: bad start 1' => array( '1ident' ), - 'Invalid: bad start -1' => array( '-1ident' ), - 'Invalid: bad start -' => array( '-' ), - ); - } - - /** - * @ticket 62653 - */ - public function test_is_ident_and_is_ident_start() { - $this->assertFalse( $this->test_class::test_is_ident_codepoint( '[', 0 ) ); - $this->assertFalse( $this->test_class::test_is_ident_codepoint( ']', 0 ) ); - $this->assertFalse( $this->test_class::test_is_ident_start_codepoint( '[', 0 ) ); - $this->assertFalse( $this->test_class::test_is_ident_start_codepoint( ']', 0 ) ); - } - - /** - * @ticket 62653 - * - * @dataProvider data_idents - */ - public function test_parse_ident( string $input, ?string $expected = null, ?string $rest = null ) { - - $offset = 0; - $result = $this->test_class::test_parse_ident( $input, $offset ); - if ( null === $expected ) { - $this->assertNull( $result ); - } else { - $this->assertSame( $expected, $result, 'Ident did not match.' ); - $this->assertSame( $rest, substr( $input, $offset ), 'Offset was not updated correctly.' ); - } - } - - /** - * @ticket 62653 - * - * @dataProvider data_strings - */ - public function test_parse_string( string $input, ?string $expected = null, ?string $rest = null ) { - $offset = 0; - $result = $this->test_class::test_parse_string( $input, $offset ); - if ( null === $expected ) { - $this->assertNull( $result ); - } else { - $this->assertSame( $expected, $result, 'String did not match.' ); - $this->assertSame( $rest, substr( $input, $offset ), 'Offset was not updated correctly.' ); - } - } - - /** - * Data provider. - * - * @return array - */ - public static function data_strings(): array { - return array( - '"foo"' => array( '"foo"', 'foo', '' ), - '"foo"after' => array( '"foo"after', 'foo', 'after' ), - '"foo""two"' => array( '"foo""two"', 'foo', '"two"' ), - '"foo"\'two\'' => array( '"foo"\'two\'', 'foo', "'two'" ), - - "'foo'" => array( "'foo'", 'foo', '' ), - "'foo'after" => array( "'foo'after", 'foo', 'after' ), - "'foo'\"two\"" => array( "'foo'\"two\"", 'foo', '"two"' ), - "'foo''two'" => array( "'foo''two'", 'foo', "'two'" ), - - "'foo\\nbar'" => array( "'foo\\\nbar'", 'foobar', '' ), - "'foo\\31 23'" => array( "'foo\\31 23'", 'foo123', '' ), - "'foo\\31\\n23'" => array( "'foo\\31\n23'", 'foo123', '' ), - "'foo\\31\\t23'" => array( "'foo\\31\t23'", 'foo123', '' ), - "'foo\\00003123'" => array( "'foo\\00003123'", 'foo123', '' ), - - "'foo\\" => array( "'foo\\", 'foo', '' ), - - '"' => array( '"', '', '' ), - '"\\"' => array( '"\\"', '"', '' ), - '"missing close' => array( '"missing close', 'missing close', '' ), - - // Invalid - 'Invalid: (empty string)' => array( '' ), - 'Invalid: .foo' => array( '.foo' ), - 'Invalid: #foo' => array( '#foo' ), - "Invalid: 'newline\\n'" => array( "'newline\n'" ), - 'Invalid: foo' => array( 'foo' ), - ); - } - - /** - * @ticket 62653 - * - * @dataProvider data_id_selectors - */ - public function test_parse_id( string $input, ?string $expected = null, ?string $rest = null ) { - $offset = 0; - $result = $this->test_class::test_parse_id_selector( $input, $offset ); - if ( null === $expected ) { - $this->assertNull( $result ); - } else { - $this->assertSame( $expected, $result->id ); - $this->assertSame( $rest, substr( $input, $offset ) ); - } - } - - /** - * Data provider. - * - * @return array - */ - public static function data_id_selectors(): array { - return array( - 'valid #_-foo123' => array( '#_-foo123', '_-foo123', '' ), - 'valid #foo#bar' => array( '#foo#bar', 'foo', '#bar' ), - 'escaped #\31 23' => array( '#\\31 23', '123', '' ), - 'with descendant #\31 23 div' => array( '#\\31 23 div', '123', ' div' ), - - 'not ID foo' => array( 'foo' ), - 'not ID .bar' => array( '.bar' ), - 'not valid #1foo' => array( '#1foo' ), - ); - } - - /** - * @ticket 62653 - * - * @dataProvider data_class_selectors - */ - public function test_parse_class( string $input, ?string $expected = null, ?string $rest = null ) { - $offset = 0; - $result = $this->test_class::test_parse_class_selector( $input, $offset ); - if ( null === $expected ) { - $this->assertNull( $result ); - } else { - $this->assertSame( $expected, $result->class_name ); - $this->assertSame( $rest, substr( $input, $offset ) ); - } - } - - /** - * Data provider. - * - * @return array - */ - public static function data_class_selectors(): array { - return array( - 'valid ._-foo123' => array( '._-foo123', '_-foo123', '' ), - 'valid .foo.bar' => array( '.foo.bar', 'foo', '.bar' ), - 'escaped .\31 23' => array( '.\\31 23', '123', '' ), - 'with descendant .\31 23 div' => array( '.\\31 23 div', '123', ' div' ), - - 'not class foo' => array( 'foo' ), - 'not class #bar' => array( '#bar' ), - 'not valid .1foo' => array( '.1foo' ), - ); - } - - /** - * @ticket 62653 - * - * @dataProvider data_type_selectors - */ - public function test_parse_type( string $input, ?string $expected = null, ?string $rest = null ) { - $offset = 0; - $result = $this->test_class::test_parse_type_selector( $input, $offset ); - if ( null === $expected ) { - $this->assertNull( $result ); - } else { - $this->assertSame( $expected, $result->type ); - $this->assertSame( $rest, substr( $input, $offset ) ); - } - } - - /** - * Data provider. - * - * @return array - */ - public static function data_type_selectors(): array { - return array( - 'any *' => array( '* .class', '*', ' .class' ), - 'a' => array( 'a', 'a', '' ), - 'div.class' => array( 'div.class', 'div', '.class' ), - 'custom-type#id' => array( 'custom-type#id', 'custom-type', '#id' ), - - // Invalid - 'Invalid: (empty string)' => array( '' ), - 'Invalid: #id' => array( '#id' ), - 'Invalid: .class' => array( '.class' ), - 'Invalid: [attr]' => array( '[attr]' ), - ); - } - - /** - * @ticket 62653 - * - * @dataProvider data_attribute_selectors - */ - public function test_parse_attribute( - string $input, - ?string $expected_name = null, - ?string $expected_matcher = null, - ?string $expected_value = null, - ?string $expected_modifier = null, - ?string $rest = null - ) { - $offset = 0; - $result = $this->test_class::test_parse_attribute_selector( $input, $offset ); - if ( null === $expected_name ) { - $this->assertNull( $result ); - } else { - $this->assertSame( $expected_name, $result->name ); - $this->assertSame( $expected_matcher, $result->matcher ); - $this->assertSame( $expected_value, $result->value ); - $this->assertSame( $expected_modifier, $result->modifier ); - $this->assertSame( $rest, substr( $input, $offset ) ); - } - } - - /** - * Data provider. - * - * @return array - */ - public static function data_attribute_selectors(): array { - return array( - '[href]' => array( '[href]', 'href', null, null, null, '' ), - '[href] type' => array( '[href] type', 'href', null, null, null, ' type' ), - '[href]#id' => array( '[href]#id', 'href', null, null, null, '#id' ), - '[href].class' => array( '[href].class', 'href', null, null, null, '.class' ), - '[href][href2]' => array( '[href][href2]', 'href', null, null, null, '[href2]' ), - '[\n href\t\r]' => array( "[\n href\t\r]", 'href', null, null, null, '' ), - '[href=foo]' => array( '[href=foo]', 'href', WP_CSS_Attribute_Selector::MATCH_EXACT, 'foo', null, '' ), - '[href \n = bar ]' => array( "[href \n = bar ]", 'href', WP_CSS_Attribute_Selector::MATCH_EXACT, 'bar', null, '' ), - '[href \n ^= baz ]' => array( "[href \n ^= baz ]", 'href', WP_CSS_Attribute_Selector::MATCH_PREFIXED_BY, 'baz', null, '' ), - - '[match $= insensitive i]' => array( '[match $= insensitive i]', 'match', WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY, 'insensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), - '[match|=sensitive s]' => array( '[match|=sensitive s]', 'match', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_HYPHEN_PREFIXED, 'sensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), - '[att=val I]' => array( '[att=val I]', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'val', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), - '[att=val S]' => array( '[att=val S]', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'val', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), - - '[match~="quoted[][]"]' => array( '[match~="quoted[][]"]', 'match', WP_CSS_Attribute_Selector::MATCH_ONE_OF_EXACT, 'quoted[][]', null, '' ), - "[match$='quoted!{}']" => array( "[match$='quoted!{}']", 'match', WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY, 'quoted!{}', null, '' ), - "[match*='quoted's]" => array( "[match*='quoted's]", 'match', WP_CSS_Attribute_Selector::MATCH_CONTAINS, 'quoted', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), - - '[escape-nl="foo\\nbar"]' => array( "[escape-nl='foo\\\nbar']", 'escape-nl', WP_CSS_Attribute_Selector::MATCH_EXACT, 'foobar', null, '' ), - '[escape-seq="\\31 23"]' => array( "[escape-seq='\\31 23']", 'escape-seq', WP_CSS_Attribute_Selector::MATCH_EXACT, '123', null, '' ), - - // Invalid - 'Invalid: (empty string)' => array( '' ), - 'Invalid: foo' => array( 'foo' ), - 'Invalid: [foo' => array( '[foo' ), - 'Invalid: [#foo]' => array( '[#foo]' ), - 'Invalid: [*|*]' => array( '[*|*]' ), - 'Invalid: [ns|*]' => array( '[ns|*]' ), - 'Invalid: [* |att]' => array( '[* |att]' ), - 'Invalid: [*| att]' => array( '[*| att]' ), - 'Invalid: [att * =]' => array( '[att * =]' ), - 'Invalid: [att+=val]' => array( '[att+=val]' ), - 'Invalid: [att=val ' => array( '[att=val ' ), - 'Invalid: [att i]' => array( '[att i]' ), - 'Invalid: [att s]' => array( '[att s]' ), - "Invalid: [att='val\\n']" => array( "[att='val\n']" ), - 'Invalid: [att=val i ' => array( '[att=val i ' ), - 'Invalid: [att="val"ix' => array( '[att="val"ix' ), - ); - } - - /** - * @ticket 62653 - */ - public function test_parse_selector() { - $input = 'el.foo#bar[baz=quux] > .child'; - $offset = 0; - $sel = $this->test_class::test_parse_compound_selector( $input, $offset ); - - $this->assertSame( 'el', $sel->type_selector->type ); - $this->assertSame( 3, count( $sel->subclass_selectors ) ); - $this->assertSame( 'foo', $sel->subclass_selectors[0]->class_name, 'foo' ); - $this->assertSame( 'bar', $sel->subclass_selectors[1]->id, 'bar' ); - $this->assertSame( 'baz', $sel->subclass_selectors[2]->name, 'baz' ); - $this->assertSame( WP_CSS_Attribute_Selector::MATCH_EXACT, $sel->subclass_selectors[2]->matcher ); - $this->assertSame( 'quux', $sel->subclass_selectors[2]->value ); - $this->assertSame( ' > .child', substr( $input, $offset ) ); - } - - /** - * @ticket 62653 - */ - public function test_parse_empty_selector() { - $input = ''; - $offset = 0; - $result = $this->test_class::test_parse_compound_selector( $input, $offset ); - $this->assertNull( $result ); - $this->assertSame( 0, $offset ); - } - /** * @ticket 62653 */ diff --git a/tests/phpunit/tests/html-api/wpCssIdSelector.php b/tests/phpunit/tests/html-api/wpCssIdSelector.php new file mode 100644 index 0000000000000..6cd6b83a46b8d --- /dev/null +++ b/tests/phpunit/tests/html-api/wpCssIdSelector.php @@ -0,0 +1,50 @@ +assertNull( $result ); + } else { + $this->assertSame( $expected, $result->id ); + $this->assertSame( $rest, substr( $input, $offset ) ); + } + } + + /** + * Data provider. + * + * @return array + */ + public static function data_id_selectors(): array { + return array( + 'valid #_-foo123' => array( '#_-foo123', '_-foo123', '' ), + 'valid #foo#bar' => array( '#foo#bar', 'foo', '#bar' ), + 'escaped #\31 23' => array( '#\\31 23', '123', '' ), + 'with descendant #\31 23 div' => array( '#\\31 23 div', '123', ' div' ), + + // Invalid + 'not ID foo' => array( 'foo' ), + 'not ID .bar' => array( '.bar' ), + 'not valid #1foo' => array( '#1foo' ), + ); + } +} diff --git a/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php b/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php new file mode 100644 index 0000000000000..4497334791c88 --- /dev/null +++ b/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php @@ -0,0 +1,172 @@ +test_class = new class() extends WP_CSS_Selector_Parser_Matcher { + /* + * Parsing + */ + public static function test_parse_ident( string $input, int &$offset ) { + return self::parse_ident( $input, $offset ); + } + + public static function test_parse_string( string $input, int &$offset ) { + return self::parse_string( $input, $offset ); + } + + /* + * Utilities + */ + public static function test_is_ident_codepoint( string $input, int $offset ) { + return self::is_ident_codepoint( $input, $offset ); + } + + public static function test_is_ident_start_codepoint( string $input, int $offset ) { + return self::is_ident_start_codepoint( $input, $offset ); + } + }; + } + + /** + * Data provider. + * + * @return array + */ + public static function data_idents(): array { + return array( + 'trailing #' => array( '_-foo123#xyz', '_-foo123', '#xyz' ), + 'trailing .' => array( '😍foo123.xyz', '😍foo123', '.xyz' ), + 'trailing " "' => array( '😍foo123 more', '😍foo123', ' more' ), + 'escaped ASCII character' => array( '\\xyz', 'xyz', '' ), + 'escaped space' => array( '\\ x', ' x', '' ), + 'escaped emoji' => array( '\\😍', '😍', '' ), + 'hex unicode codepoint' => array( '\\1f0a1', '🂡', '' ), + 'HEX UNICODE CODEPOINT' => array( '\\1D4B2', '𝒲', '' ), + + 'hex tab-suffixed 1' => array( "\\31\t23", '123', '' ), + 'hex newline-suffixed 1' => array( "\\31\n23", '123', '' ), + 'hex space-suffixed 1' => array( "\\31 23", '123', '' ), + 'hex tab' => array( '\\9', "\t", '' ), + 'hex a' => array( '\\61 bc', 'abc', '' ), + 'hex a max escape length' => array( '\\000061bc', 'abc', '' ), + + 'out of range replacement min' => array( '\\110000 ', "\u{fffd}", '' ), + 'out of range replacement max' => array( '\\ffffff ', "\u{fffd}", '' ), + 'leading surrogate min replacement' => array( '\\d800 ', "\u{fffd}", '' ), + 'leading surrogate max replacement' => array( '\\dbff ', "\u{fffd}", '' ), + 'trailing surrogate min replacement' => array( '\\dc00 ', "\u{fffd}", '' ), + 'trailing surrogate max replacement' => array( '\\dfff ', "\u{fffd}", '' ), + 'can start with -ident' => array( '-ident', '-ident', '' ), + 'can start with --anything' => array( '--anything', '--anything', '' ), + 'can start with ---anything' => array( '--_anything', '--_anything', '' ), + 'can start with --1anything' => array( '--1anything', '--1anything', '' ), + 'can start with -\31 23' => array( '-\31 23', '-123', '' ), + 'can start with --\31 23' => array( '--\31 23', '--123', '' ), + 'ident ends before ]' => array( 'ident]', 'ident', ']' ), + + // Invalid + 'Invalid: (empty string)' => array( '' ), + 'Invalid: bad start >' => array( '>ident' ), + 'Invalid: bad start [' => array( '[ident' ), + 'Invalid: bad start #' => array( '#ident' ), + 'Invalid: bad start " "' => array( ' ident' ), + 'Invalid: bad start 1' => array( '1ident' ), + 'Invalid: bad start -1' => array( '-1ident' ), + 'Invalid: bad start -' => array( '-' ), + ); + } + + /** + * @ticket 62653 + */ + public function test_is_ident_and_is_ident_start() { + $this->assertFalse( $this->test_class::test_is_ident_codepoint( '[', 0 ) ); + $this->assertFalse( $this->test_class::test_is_ident_codepoint( ']', 0 ) ); + $this->assertFalse( $this->test_class::test_is_ident_start_codepoint( '[', 0 ) ); + $this->assertFalse( $this->test_class::test_is_ident_start_codepoint( ']', 0 ) ); + } + + /** + * @ticket 62653 + * + * @dataProvider data_idents + */ + public function test_parse_ident( string $input, ?string $expected = null, ?string $rest = null ) { + + $offset = 0; + $result = $this->test_class::test_parse_ident( $input, $offset ); + if ( null === $expected ) { + $this->assertNull( $result ); + } else { + $this->assertSame( $expected, $result, 'Ident did not match.' ); + $this->assertSame( $rest, substr( $input, $offset ), 'Offset was not updated correctly.' ); + } + } + + /** + * @ticket 62653 + * + * @dataProvider data_strings + */ + public function test_parse_string( string $input, ?string $expected = null, ?string $rest = null ) { + $offset = 0; + $result = $this->test_class::test_parse_string( $input, $offset ); + if ( null === $expected ) { + $this->assertNull( $result ); + } else { + $this->assertSame( $expected, $result, 'String did not match.' ); + $this->assertSame( $rest, substr( $input, $offset ), 'Offset was not updated correctly.' ); + } + } + + /** + * Data provider. + * + * @return array + */ + public static function data_strings(): array { + return array( + '"foo"' => array( '"foo"', 'foo', '' ), + '"foo"after' => array( '"foo"after', 'foo', 'after' ), + '"foo""two"' => array( '"foo""two"', 'foo', '"two"' ), + '"foo"\'two\'' => array( '"foo"\'two\'', 'foo', "'two'" ), + + "'foo'" => array( "'foo'", 'foo', '' ), + "'foo'after" => array( "'foo'after", 'foo', 'after' ), + "'foo'\"two\"" => array( "'foo'\"two\"", 'foo', '"two"' ), + "'foo''two'" => array( "'foo''two'", 'foo', "'two'" ), + + "'foo\\nbar'" => array( "'foo\\\nbar'", 'foobar', '' ), + "'foo\\31 23'" => array( "'foo\\31 23'", 'foo123', '' ), + "'foo\\31\\n23'" => array( "'foo\\31\n23'", 'foo123', '' ), + "'foo\\31\\t23'" => array( "'foo\\31\t23'", 'foo123', '' ), + "'foo\\00003123'" => array( "'foo\\00003123'", 'foo123', '' ), + + "'foo\\" => array( "'foo\\", 'foo', '' ), + + '"' => array( '"', '', '' ), + '"\\"' => array( '"\\"', '"', '' ), + '"missing close' => array( '"missing close', 'missing close', '' ), + + // Invalid + 'Invalid: (empty string)' => array( '' ), + 'Invalid: .foo' => array( '.foo' ), + 'Invalid: #foo' => array( '#foo' ), + "Invalid: 'newline\\n'" => array( "'newline\n'" ), + 'Invalid: foo' => array( 'foo' ), + ); + } +} diff --git a/tests/phpunit/tests/html-api/wpCssTypeSelector.php b/tests/phpunit/tests/html-api/wpCssTypeSelector.php new file mode 100644 index 0000000000000..fb53c41dd058c --- /dev/null +++ b/tests/phpunit/tests/html-api/wpCssTypeSelector.php @@ -0,0 +1,51 @@ +assertNull( $result ); + } else { + $this->assertSame( $expected, $result->type ); + $this->assertSame( $rest, substr( $input, $offset ) ); + } + } + + /** + * Data provider. + * + * @return array + */ + public static function data_type_selectors(): array { + return array( + 'any *' => array( '* .class', '*', ' .class' ), + 'a' => array( 'a', 'a', '' ), + 'div.class' => array( 'div.class', 'div', '.class' ), + 'custom-type#id' => array( 'custom-type#id', 'custom-type', '#id' ), + + // Invalid + 'Invalid: (empty string)' => array( '' ), + 'Invalid: #id' => array( '#id' ), + 'Invalid: .class' => array( '.class' ), + 'Invalid: [attr]' => array( '[attr]' ), + ); + } +} From f217eb0de026fcee8beb645f941de5221c676795 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 11 Dec 2024 18:45:20 +0100 Subject: [PATCH 118/634] Use whitepsace chars constant --- .../html-api/class-wp-css-attribute-selector.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-attribute-selector.php b/src/wp-includes/html-api/class-wp-css-attribute-selector.php index 700a8cba9bb0c..ab566f8f1af11 100644 --- a/src/wp-includes/html-api/class-wp-css-attribute-selector.php +++ b/src/wp-includes/html-api/class-wp-css-attribute-selector.php @@ -231,15 +231,15 @@ public function matches( WP_HTML_Tag_Processor $processor ): bool { */ private function whitespace_delimited_list( string $input ): Generator { // Start by skipping whitespace. - $offset = strspn( $input, " \t\r\n\f" ); + $offset = strspn( $input, self::WHITESPACE_CHARACTERS ); while ( $offset < strlen( $input ) ) { // Find the byte length until the next boundary. - $length = strcspn( $input, " \t\r\n\f", $offset ); + $length = strcspn( $input, self::WHITESPACE_CHARACTERS, $offset ); $value = substr( $input, $offset, $length ); // Move past trailing whitespace. - $offset += $length + strspn( $input, " \t\r\n\f", $offset + $length ); + $offset += $length + strspn( $input, self::WHITESPACE_CHARACTERS, $offset + $length ); yield $value; } From 6154742ecb42762951eb2267fe12434417f7bf85 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 11 Dec 2024 18:46:14 +0100 Subject: [PATCH 119/634] parse_whitespace should be protected --- .../html-api/class-wp-css-selector-parser-matcher.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php b/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php index 8820115f03cfb..744f75496f0f8 100644 --- a/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php +++ b/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php @@ -34,7 +34,7 @@ abstract public static function parse( string $input, int &$offset ): ?static; /** * @todo document */ - final public static function parse_whitespace( string $input, int &$offset ): bool { + final protected static function parse_whitespace( string $input, int &$offset ): bool { $length = strspn( $input, self::WHITESPACE_CHARACTERS, $offset ); $advanced = $length > 0; $offset += $length; From 577b3a3b7036b9db71d6c0ab3337b96f94960686 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 11 Dec 2024 18:48:01 +0100 Subject: [PATCH 120/634] Update interface to abstract class require --- src/wp-settings.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/wp-settings.php b/src/wp-settings.php index b52fe8ab6181c..2e6ed6091a682 100644 --- a/src/wp-settings.php +++ b/src/wp-settings.php @@ -265,8 +265,7 @@ require ABSPATH . WPINC . '/html-api/class-wp-html-stack-event.php'; require ABSPATH . WPINC . '/html-api/class-wp-html-processor-state.php'; require ABSPATH . WPINC . '/html-api/class-wp-html-processor.php'; -require ABSPATH . WPINC . '/html-api/interface-wp-css-html-tag-processor-matcher.php'; -require ABSPATH . WPINC . '/html-api/interface-wp-css-html-processor-matcher.php'; +require ABSPATH . WPINC . '/html-api/class-wp-css-selector-parser-matcher.php'; require ABSPATH . WPINC . '/html-api/class-wp-css-attribute-selector.php'; require ABSPATH . WPINC . '/html-api/class-wp-css-class-selector.php'; require ABSPATH . WPINC . '/html-api/class-wp-css-id-selector.php'; From 5ea93abbf5704268239c3129a43e9bd9834e34b8 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 11 Dec 2024 19:04:03 +0100 Subject: [PATCH 121/634] Document base class --- .../class-wp-css-selector-parser-matcher.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php b/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php index 744f75496f0f8..60e75820c264a 100644 --- a/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php +++ b/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php @@ -1,5 +1,19 @@ Date: Wed, 11 Dec 2024 19:06:19 +0100 Subject: [PATCH 122/634] Invert and comment confusing compound selector condition --- .../html-api/class-wp-css-compound-selector.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector.php b/src/wp-includes/html-api/class-wp-css-compound-selector.php index 68aca4d880e0d..f301f6f9342fd 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector.php @@ -95,12 +95,13 @@ public static function parse( string $input, int &$offset ): ?static { $last_parsed_subclass_selector = self::parse_subclass_selector( $input, $updated_offset ); } - // @todo invert this condition - if ( null !== $type_selector || array() !== $subclass_selectors ) { - $offset = $updated_offset; - return new self( $type_selector, $subclass_selectors ); + // There must be at least one selector. + if ( null === $type_selector && array() === $subclass_selectors ) { + return null; } - return null; + + $offset = $updated_offset; + return new self( $type_selector, $subclass_selectors ); } /** From db469e62def02391ab362d5b7fd01ee4f54606d0 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 11 Dec 2024 19:08:46 +0100 Subject: [PATCH 123/634] Use switch in compound selector parsing --- .../class-wp-css-compound-selector.php | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector.php b/src/wp-includes/html-api/class-wp-css-compound-selector.php index f301f6f9342fd..002021472f496 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector.php @@ -116,16 +116,15 @@ private static function parse_subclass_selector( string $input, int &$offset ) { return null; } - $next_char = $input[ $offset ]; - return '.' === $next_char - ? WP_CSS_Class_Selector::parse( $input, $offset ) - : ( - '#' === $next_char - ? WP_CSS_ID_Selector::parse( $input, $offset ) - : ( '[' === $next_char - ? WP_CSS_Attribute_Selector::parse( $input, $offset ) - : null - ) - ); + switch ( $input[ $offset ] ) { + case '.': + return WP_CSS_Class_Selector::parse( $input, $offset ); + case '#': + return WP_CSS_ID_Selector::parse( $input, $offset ); + case '[': + return WP_CSS_Attribute_Selector::parse( $input, $offset ); + } + + return null; } } From 400263a007f5e5aa6a0394343bf3dd827e32e029 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 11 Dec 2024 19:20:45 +0100 Subject: [PATCH 124/634] Fix up some todo-s --- .../class-wp-css-complex-selector-list.php | 8 -------- .../class-wp-css-compound-selector-list.php | 14 ++++++-------- .../class-wp-css-selector-parser-matcher.php | 19 ++++++++++++++----- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php index 10af613174a35..940bd098c6c19 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php @@ -44,14 +44,6 @@ class WP_CSS_Complex_Selector_List extends WP_CSS_Compound_Selector_List { * @return static|null The selector instance, or null if the parse was unsuccessful. */ public static function parse( string $input, int &$offset ): ?static { - $input = self::normalize_selector_input( $input ); - - if ( '' === $input ) { - return null; - } - - $offset = 0; - $selector = WP_CSS_Complex_Selector::parse( $input, $offset ); if ( null === $selector ) { return null; diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php index a6f3b87409ff6..7edafc779ac4c 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php @@ -122,6 +122,12 @@ protected function __construct( array $selectors ) { * @return static|null */ public static function from_selectors( string $input ): ?static { + $input = self::normalize_selector_input( $input ); + + if ( '' === $input ) { + return null; + } + $offset = 0; return static::parse( $input, $offset ); } @@ -137,14 +143,6 @@ public static function from_selectors( string $input ): ?static { * @return static|null The selector instance, or null if the parse was unsuccessful. */ public static function parse( string $input, int &$offset ): ?static { - $input = self::normalize_selector_input( $input ); - - if ( '' === $input ) { - return null; - } - - $offset = 0; - $selector = WP_CSS_Compound_Selector::parse( $input, $offset ); if ( null === $selector ) { return null; diff --git a/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php b/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php index 60e75820c264a..6d665c4c26cb0 100644 --- a/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php +++ b/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php @@ -46,7 +46,12 @@ abstract public static function parse( string $input, int &$offset ): ?static; */ /** - * @todo document + * Consumes whitespace from the input string. + * + * @param string $input The selector string. + * @param int $offset The offset into the string. The offset is passed by reference and will + * be update to the byte after the whitespace sequence. + * @return bool True if whitespace was consumed. */ final protected static function parse_whitespace( string $input, int &$offset ): bool { $length = strspn( $input, self::WHITESPACE_CHARACTERS, $offset ); @@ -289,7 +294,6 @@ final protected static function parse_ident( string $input, int &$offset ): ?str $ident .= self::consume_escaped_codepoint( $input, $offset ); continue; } elseif ( self::is_ident_codepoint( $input, $offset ) ) { - // @todo this should append and advance the correct number of bytes. $ident .= $input[ $offset ]; ++$offset; continue; @@ -338,7 +342,7 @@ final protected static function next_two_are_valid_escape( string $input, int $o } /** - * Checks if the next code point is an "ident start code point". + * Checks if the next code point is an "ident start code point." * * Caution! This method does not do any bounds checking, it should not be passed * a string with an offset that is out of bounds. @@ -370,7 +374,7 @@ final protected static function is_ident_start_codepoint( string $input, int $of } /** - * Checks if the next code point is an "ident code point". + * Checks if the next code point is an "ident code point." * * Caution! This method does not do any bounds checking, it should not be passed * a string with an offset that is out of bounds. @@ -461,7 +465,12 @@ final protected static function check_if_three_code_points_would_start_an_ident_ } /** - * @todo doc… + * Normalizes selector input for processing. + * + * @see https://www.w3.org/TR/css-syntax-3/#input-preprocessing + * + * @param string $input The selector string. + * @return string The normalized selector string. */ final protected static function normalize_selector_input( string $input ): string { /* From 483a8191401c91f53601033ba3977a068bd03446 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 11 Dec 2024 19:24:22 +0100 Subject: [PATCH 125/634] Make most selector constructors private --- src/wp-includes/html-api/class-wp-css-attribute-selector.php | 2 +- src/wp-includes/html-api/class-wp-css-class-selector.php | 2 +- src/wp-includes/html-api/class-wp-css-compound-selector.php | 2 +- src/wp-includes/html-api/class-wp-css-id-selector.php | 2 +- src/wp-includes/html-api/class-wp-css-type-selector.php | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-attribute-selector.php b/src/wp-includes/html-api/class-wp-css-attribute-selector.php index ab566f8f1af11..d2d4d17792a81 100644 --- a/src/wp-includes/html-api/class-wp-css-attribute-selector.php +++ b/src/wp-includes/html-api/class-wp-css-attribute-selector.php @@ -140,7 +140,7 @@ final class WP_CSS_Attribute_Selector extends WP_CSS_Selector_Parser_Matcher { * @param string|null $modifier The attribute case modifier. * Must be one of the class MODIFIER_* constants or null. */ - public function __construct( string $name, ?string $matcher = null, ?string $value = null, ?string $modifier = null ) { + private function __construct( string $name, ?string $matcher = null, ?string $value = null, ?string $modifier = null ) { $this->name = $name; $this->matcher = $matcher; $this->value = $value; diff --git a/src/wp-includes/html-api/class-wp-css-class-selector.php b/src/wp-includes/html-api/class-wp-css-class-selector.php index 9abcb881ace49..ff7a0b0442813 100644 --- a/src/wp-includes/html-api/class-wp-css-class-selector.php +++ b/src/wp-includes/html-api/class-wp-css-class-selector.php @@ -29,7 +29,7 @@ final class WP_CSS_Class_Selector extends WP_CSS_Selector_Parser_Matcher { * * @param string $class_name The class name to match. */ - public function __construct( string $class_name ) { + private function __construct( string $class_name ) { $this->class_name = $class_name; } diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector.php b/src/wp-includes/html-api/class-wp-css-compound-selector.php index 002021472f496..077ed5aa4b7f3 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector.php @@ -45,7 +45,7 @@ final class WP_CSS_Compound_Selector extends WP_CSS_Selector_Parser_Matcher { * @param (WP_CSS_ID_Selector|WP_CSS_Class_Selector|WP_CSS_Attribute_Selector)[]|null $subclass_selectors * The array of subclass selectors or null. */ - public function __construct( ?WP_CSS_Type_Selector $type_selector, ?array $subclass_selectors ) { + private function __construct( ?WP_CSS_Type_Selector $type_selector, ?array $subclass_selectors ) { $this->type_selector = $type_selector; $this->subclass_selectors = array() === $subclass_selectors ? null : $subclass_selectors; } diff --git a/src/wp-includes/html-api/class-wp-css-id-selector.php b/src/wp-includes/html-api/class-wp-css-id-selector.php index de854c37eea9f..2c7cb6feec658 100644 --- a/src/wp-includes/html-api/class-wp-css-id-selector.php +++ b/src/wp-includes/html-api/class-wp-css-id-selector.php @@ -29,7 +29,7 @@ final class WP_CSS_ID_Selector extends WP_CSS_Selector_Parser_Matcher { * * @param string $id The ID to match. */ - public function __construct( string $id ) { + private function __construct( string $id ) { $this->id = $id; } diff --git a/src/wp-includes/html-api/class-wp-css-type-selector.php b/src/wp-includes/html-api/class-wp-css-type-selector.php index 492569ee51d65..ab41a87f1a113 100644 --- a/src/wp-includes/html-api/class-wp-css-type-selector.php +++ b/src/wp-includes/html-api/class-wp-css-type-selector.php @@ -29,7 +29,7 @@ final class WP_CSS_Type_Selector extends WP_CSS_Selector_Parser_Matcher { * * @param string $type The element type (tag name) to match or '*' to match any element. */ - public function __construct( string $type ) { + private function __construct( string $type ) { $this->type = $type; } From 1f641685627d8536887c69d25e5f69466cb1f076 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 11 Dec 2024 19:32:17 +0100 Subject: [PATCH 126/634] Fix test class implementation of abstract class --- .../phpunit/tests/html-api/wpCssSelectorParserMatcher.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php b/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php index 4497334791c88..4e0dd23af12f7 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php +++ b/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php @@ -16,6 +16,13 @@ class Tests_HtmlApi_WpCssSelectorParserMatcher extends WP_UnitTestCase { public function set_up(): void { parent::set_up(); $this->test_class = new class() extends WP_CSS_Selector_Parser_Matcher { + public function matches( $processor ): bool { + throw new Exeption( 'Matches called on test class.' ); + } + public static function parse( string $input, int &$offset ): ?static { + throw new Exeption( 'Parse called on test class.' ); + } + /* * Parsing */ From 3bfb8a13acbfa5a5360d4555bdc6102f4236d8e5 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 11 Dec 2024 19:41:30 +0100 Subject: [PATCH 127/634] Remove php 8+ ?static return types --- src/wp-includes/html-api/class-wp-css-attribute-selector.php | 2 +- src/wp-includes/html-api/class-wp-css-class-selector.php | 2 +- .../html-api/class-wp-css-complex-selector-list.php | 2 +- src/wp-includes/html-api/class-wp-css-complex-selector.php | 2 +- .../html-api/class-wp-css-compound-selector-list.php | 4 ++-- src/wp-includes/html-api/class-wp-css-compound-selector.php | 2 +- src/wp-includes/html-api/class-wp-css-id-selector.php | 2 +- .../html-api/class-wp-css-selector-parser-matcher.php | 2 +- src/wp-includes/html-api/class-wp-css-type-selector.php | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-attribute-selector.php b/src/wp-includes/html-api/class-wp-css-attribute-selector.php index d2d4d17792a81..dc3c13a5ea534 100644 --- a/src/wp-includes/html-api/class-wp-css-attribute-selector.php +++ b/src/wp-includes/html-api/class-wp-css-attribute-selector.php @@ -255,7 +255,7 @@ private function whitespace_delimited_list( string $input ): Generator { * will be updated if the parse is successful. * @return static|null The selector instance, or null if the parse was unsuccessful. */ - public static function parse( string $input, int &$offset ): ?static { + public static function parse( string $input, int &$offset ) { // Need at least 3 bytes [x] if ( $offset + 2 >= strlen( $input ) ) { return null; diff --git a/src/wp-includes/html-api/class-wp-css-class-selector.php b/src/wp-includes/html-api/class-wp-css-class-selector.php index ff7a0b0442813..57f7dac50315f 100644 --- a/src/wp-includes/html-api/class-wp-css-class-selector.php +++ b/src/wp-includes/html-api/class-wp-css-class-selector.php @@ -53,7 +53,7 @@ public function matches( WP_HTML_Tag_Processor $processor ): bool { * will be updated if the parse is successful. * @return static|null The selector instance, or null if the parse was unsuccessful. */ - public static function parse( string $input, int &$offset ): ?static { + public static function parse( string $input, int &$offset ) { if ( $offset + 1 >= strlen( $input ) || '.' !== $input[ $offset ] ) { return null; } diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php index 940bd098c6c19..d819cd469086f 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php @@ -43,7 +43,7 @@ class WP_CSS_Complex_Selector_List extends WP_CSS_Compound_Selector_List { * will be updated if the parse is successful. * @return static|null The selector instance, or null if the parse was unsuccessful. */ - public static function parse( string $input, int &$offset ): ?static { + public static function parse( string $input, int &$offset ) { $selector = WP_CSS_Complex_Selector::parse( $input, $offset ); if ( null === $selector ) { return null; diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector.php b/src/wp-includes/html-api/class-wp-css-complex-selector.php index 7c997c62a80f7..8c7c25ed7b984 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector.php @@ -200,7 +200,7 @@ private function explore_matches( array $selectors, array $breadcrumbs ): bool { * will be updated if the parse is successful. * @return static|null The selector instance, or null if the parse was unsuccessful. */ - public static function parse( string $input, int &$offset ): ?static { + public static function parse( string $input, int &$offset ) { if ( $offset >= strlen( $input ) ) { return null; } diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php index 7edafc779ac4c..41cf76e2c90f6 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php @@ -121,7 +121,7 @@ protected function __construct( array $selectors ) { * @param string $input CSS selectors. * @return static|null */ - public static function from_selectors( string $input ): ?static { + public static function from_selectors( string $input ) { $input = self::normalize_selector_input( $input ); if ( '' === $input ) { @@ -142,7 +142,7 @@ public static function from_selectors( string $input ): ?static { * will be updated if the parse is successful. * @return static|null The selector instance, or null if the parse was unsuccessful. */ - public static function parse( string $input, int &$offset ): ?static { + public static function parse( string $input, int &$offset ) { $selector = WP_CSS_Compound_Selector::parse( $input, $offset ); if ( null === $selector ) { return null; diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector.php b/src/wp-includes/html-api/class-wp-css-compound-selector.php index 077ed5aa4b7f3..91e543fdc7e7e 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector.php @@ -80,7 +80,7 @@ public function matches( WP_HTML_Tag_Processor $processor ): bool { * will be updated if the parse is successful. * @return static|null The selector instance, or null if the parse was unsuccessful. */ - public static function parse( string $input, int &$offset ): ?static { + public static function parse( string $input, int &$offset ) { if ( $offset >= strlen( $input ) ) { return null; } diff --git a/src/wp-includes/html-api/class-wp-css-id-selector.php b/src/wp-includes/html-api/class-wp-css-id-selector.php index 2c7cb6feec658..f0c203dc6477e 100644 --- a/src/wp-includes/html-api/class-wp-css-id-selector.php +++ b/src/wp-includes/html-api/class-wp-css-id-selector.php @@ -62,7 +62,7 @@ public function matches( WP_HTML_Tag_Processor $processor ): bool { * will be updated if the parse is successful. * @return static|null The selector instance, or null if the parse was unsuccessful. */ - public static function parse( string $input, int &$offset ): ?static { + public static function parse( string $input, int &$offset ) { $ident = self::parse_hash_token( $input, $offset ); if ( null === $ident ) { return null; diff --git a/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php b/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php index 6d665c4c26cb0..e2b56a7b9e55c 100644 --- a/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php +++ b/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php @@ -34,7 +34,7 @@ abstract public function matches( WP_HTML_Tag_Processor $processor ): bool; * will be updated if the parse is successful. * @return static|null The selector instance, or null if the parse was unsuccessful. */ - abstract public static function parse( string $input, int &$offset ): ?static; + abstract public static function parse( string $input, int &$offset ); /* * ------------------------ diff --git a/src/wp-includes/html-api/class-wp-css-type-selector.php b/src/wp-includes/html-api/class-wp-css-type-selector.php index ab41a87f1a113..c16883fa60679 100644 --- a/src/wp-includes/html-api/class-wp-css-type-selector.php +++ b/src/wp-includes/html-api/class-wp-css-type-selector.php @@ -70,7 +70,7 @@ public function matches_tag( string $tag_name ): bool { * will be updated if the parse is successful. * @return static|null The selector instance, or null if the parse was unsuccessful. */ - public static function parse( string $input, int &$offset ): ?static { + public static function parse( string $input, int &$offset ) { if ( $offset >= strlen( $input ) ) { return null; } From 8d2aef2f19c99a7e1401fc29d16e56a930bad948 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 11 Dec 2024 19:47:59 +0100 Subject: [PATCH 128/634] Fix typo in Exception class name --- tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php b/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php index 4e0dd23af12f7..bf84f30637510 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php +++ b/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php @@ -17,10 +17,10 @@ public function set_up(): void { parent::set_up(); $this->test_class = new class() extends WP_CSS_Selector_Parser_Matcher { public function matches( $processor ): bool { - throw new Exeption( 'Matches called on test class.' ); + throw new Error( 'Matches called on test class.' ); } public static function parse( string $input, int &$offset ): ?static { - throw new Exeption( 'Parse called on test class.' ); + throw new Error( 'Parse called on test class.' ); } /* From 33b83338c827a67c48328dbf8f4c2dd70893ba9c Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 11 Dec 2024 19:48:37 +0100 Subject: [PATCH 129/634] Remove ?static return type from test --- tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php b/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php index bf84f30637510..29a76bfd78723 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php +++ b/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php @@ -19,7 +19,7 @@ public function set_up(): void { public function matches( $processor ): bool { throw new Error( 'Matches called on test class.' ); } - public static function parse( string $input, int &$offset ): ?static { + public static function parse( string $input, int &$offset ) { throw new Error( 'Parse called on test class.' ); } From 016d897f35d7b59400ba4b2fd386065b187e8e4d Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 10 Jul 2025 19:36:44 +0200 Subject: [PATCH 130/634] Change MATCH_EXACT_OR_HYPHEN_PREFIXED to _SUFFIXED This is a more appropriate name for the type of match. > `[att|=val]` Represents an element with the att attribute, its value > either being exactly "val" or beginning with "val" immediately > followed by "-" (U+002D). This is primarily intended to allow language > subcode matches (e.g., the hreflang attribute on the a element in > HTML) as described in BCP 47 ([BCP47]) or its successor. --- .../html-api/class-wp-css-attribute-selector.php | 8 ++++---- tests/phpunit/tests/html-api/wpCssAttributeSelector.php | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-attribute-selector.php b/src/wp-includes/html-api/class-wp-css-attribute-selector.php index dc3c13a5ea534..e104b05fabf8c 100644 --- a/src/wp-includes/html-api/class-wp-css-attribute-selector.php +++ b/src/wp-includes/html-api/class-wp-css-attribute-selector.php @@ -43,7 +43,7 @@ final class WP_CSS_Attribute_Selector extends WP_CSS_Selector_Parser_Matcher { * * [attr|=value] */ - const MATCH_EXACT_OR_HYPHEN_PREFIXED = 'exact-or-hyphen-prefixed'; + const MATCH_EXACT_OR_HYPHEN_SUFFIXED = 'exact-or-hyphen-suffixed'; /** * The attribute value matches the start of the attribute. @@ -103,7 +103,7 @@ final class WP_CSS_Attribute_Selector extends WP_CSS_Selector_Parser_Matcher { * Allowed string values are the class constants: * - {@see WP_CSS_Attribute_Selector::MATCH_EXACT} * - {@see WP_CSS_Attribute_Selector::MATCH_ONE_OF_EXACT} - * - {@see WP_CSS_Attribute_Selector::MATCH_EXACT_OR_HYPHEN_PREFIXED} + * - {@see WP_CSS_Attribute_Selector::MATCH_EXACT_OR_HYPHEN_SUFFIXED} * - {@see WP_CSS_Attribute_Selector::MATCH_PREFIXED_BY} * - {@see WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY} * - {@see WP_CSS_Attribute_Selector::MATCH_CONTAINS} @@ -187,7 +187,7 @@ public function matches( WP_HTML_Tag_Processor $processor ): bool { } return false; - case self::MATCH_EXACT_OR_HYPHEN_PREFIXED: + case self::MATCH_EXACT_OR_HYPHEN_SUFFIXED: // Attempt the full match first if ( $case_insensitive @@ -299,7 +299,7 @@ public static function parse( string $input, int &$offset ) { $updated_offset += 2; break; case '|': - $attr_matcher = WP_CSS_Attribute_Selector::MATCH_EXACT_OR_HYPHEN_PREFIXED; + $attr_matcher = WP_CSS_Attribute_Selector::MATCH_EXACT_OR_HYPHEN_SUFFIXED; $updated_offset += 2; break; case '^': diff --git a/tests/phpunit/tests/html-api/wpCssAttributeSelector.php b/tests/phpunit/tests/html-api/wpCssAttributeSelector.php index d907ad7c07e5b..45fa787f7a4ff 100644 --- a/tests/phpunit/tests/html-api/wpCssAttributeSelector.php +++ b/tests/phpunit/tests/html-api/wpCssAttributeSelector.php @@ -57,7 +57,7 @@ public static function data_attribute_selectors(): array { '[href \n ^= baz ]' => array( "[href \n ^= baz ]", 'href', WP_CSS_Attribute_Selector::MATCH_PREFIXED_BY, 'baz', null, '' ), '[match $= insensitive i]' => array( '[match $= insensitive i]', 'match', WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY, 'insensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), - '[match|=sensitive s]' => array( '[match|=sensitive s]', 'match', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_HYPHEN_PREFIXED, 'sensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), + '[match|=sensitive s]' => array( '[match|=sensitive s]', 'match', WP_CSS_Attribute_Selector::MATCH_EXACT_OR_HYPHEN_SUFFIXED, 'sensitive', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), '[att=val I]' => array( '[att=val I]', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'val', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), '[att=val S]' => array( '[att=val S]', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'val', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), From c0fa8d54a4a396ddf25b12aeb51462302b33e49c Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 10 Jul 2025 19:43:54 +0200 Subject: [PATCH 131/634] Use "attr" instead of "att" as short "attributes" --- .../class-wp-css-attribute-selector.php | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-attribute-selector.php b/src/wp-includes/html-api/class-wp-css-attribute-selector.php index e104b05fabf8c..7d9acd1665b51 100644 --- a/src/wp-includes/html-api/class-wp-css-attribute-selector.php +++ b/src/wp-includes/html-api/class-wp-css-attribute-selector.php @@ -22,7 +22,7 @@ final class WP_CSS_Attribute_Selector extends WP_CSS_Selector_Parser_Matcher { * * @example * - * [att=val] + * [attr=val] */ const MATCH_EXACT = 'exact'; @@ -154,8 +154,8 @@ private function __construct( string $name, ?string $matcher = null, ?string $va * @return bool True if the processor's current position matches the selector. */ public function matches( WP_HTML_Tag_Processor $processor ): bool { - $att_value = $processor->get_attribute( $this->name ); - if ( null === $att_value ) { + $attr_value = $processor->get_attribute( $this->name ); + if ( null === $attr_value ) { return false; } @@ -163,8 +163,8 @@ public function matches( WP_HTML_Tag_Processor $processor ): bool { return true; } - if ( true === $att_value ) { - $att_value = ''; + if ( true === $attr_value ) { + $attr_value = ''; } $case_insensitive = self::MODIFIER_CASE_INSENSITIVE === $this->modifier; @@ -172,11 +172,11 @@ public function matches( WP_HTML_Tag_Processor $processor ): bool { switch ( $this->matcher ) { case self::MATCH_EXACT: return $case_insensitive - ? 0 === strcasecmp( $att_value, $this->value ) - : $att_value === $this->value; + ? 0 === strcasecmp( $attr_value, $this->value ) + : $attr_value === $this->value; case self::MATCH_ONE_OF_EXACT: - foreach ( $this->whitespace_delimited_list( $att_value ) as $val ) { + foreach ( $this->whitespace_delimited_list( $attr_value ) as $val ) { if ( $case_insensitive ? 0 === strcasecmp( $val, $this->value ) @@ -191,31 +191,31 @@ public function matches( WP_HTML_Tag_Processor $processor ): bool { // Attempt the full match first if ( $case_insensitive - ? 0 === strcasecmp( $att_value, $this->value ) - : $att_value === $this->value + ? 0 === strcasecmp( $attr_value, $this->value ) + : $attr_value === $this->value ) { return true; } // Partial match - if ( strlen( $att_value ) < strlen( $this->value ) + 1 ) { + if ( strlen( $attr_value ) < strlen( $this->value ) + 1 ) { return false; } $starts_with = "{$this->value}-"; - return 0 === substr_compare( $att_value, $starts_with, 0, strlen( $starts_with ), $case_insensitive ); + return 0 === substr_compare( $attr_value, $starts_with, 0, strlen( $starts_with ), $case_insensitive ); case self::MATCH_PREFIXED_BY: - return 0 === substr_compare( $att_value, $this->value, 0, strlen( $this->value ), $case_insensitive ); + return 0 === substr_compare( $attr_value, $this->value, 0, strlen( $this->value ), $case_insensitive ); case self::MATCH_SUFFIXED_BY: - return 0 === substr_compare( $att_value, $this->value, -strlen( $this->value ), null, $case_insensitive ); + return 0 === substr_compare( $attr_value, $this->value, -strlen( $this->value ), null, $case_insensitive ); case self::MATCH_CONTAINS: return false !== ( $case_insensitive - ? stripos( $att_value, $this->value ) - : strpos( $att_value, $this->value ) + ? stripos( $attr_value, $this->value ) + : strpos( $attr_value, $this->value ) ); } } From cfa2bc2ecb17d2893cb239db168608f295ee187f Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 10 Jul 2025 20:13:46 +0200 Subject: [PATCH 132/634] Simplify exact or hyphen suffixed implementation --- .../class-wp-css-attribute-selector.php | 22 +++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-attribute-selector.php b/src/wp-includes/html-api/class-wp-css-attribute-selector.php index 7d9acd1665b51..dde5f12bbf962 100644 --- a/src/wp-includes/html-api/class-wp-css-attribute-selector.php +++ b/src/wp-includes/html-api/class-wp-css-attribute-selector.php @@ -188,22 +188,12 @@ public function matches( WP_HTML_Tag_Processor $processor ): bool { return false; case self::MATCH_EXACT_OR_HYPHEN_SUFFIXED: - // Attempt the full match first - if ( - $case_insensitive - ? 0 === strcasecmp( $attr_value, $this->value ) - : $attr_value === $this->value - ) { - return true; - } - - // Partial match - if ( strlen( $attr_value ) < strlen( $this->value ) + 1 ) { - return false; - } - - $starts_with = "{$this->value}-"; - return 0 === substr_compare( $attr_value, $starts_with, 0, strlen( $starts_with ), $case_insensitive ); + $exact_length = strlen( $this->value ); + $matches_prefix = substr_compare( $attr_value, $this->value, 0, $exact_length, $case_insensitive ); + return ( + 0 === $matches_prefix && + ( strlen( $attr_value ) === $exact_length || '-' === $attr_value[ $exact_length ] ) + ); case self::MATCH_PREFIXED_BY: return 0 === substr_compare( $attr_value, $this->value, 0, strlen( $this->value ), $case_insensitive ); From dc789e41f26f9b08ab9f306ffc51be7e3945daec Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Mon, 14 Jul 2025 12:44:26 -0500 Subject: [PATCH 133/634] Only expose `select()` for a `while ( $->select() )` loop Matches the calling interface for the other HTML API classes, avoids creating the `Generator`, using a static var to avoid re-parsing the selector string instead. --- .../class-wp-css-complex-selector-list.php | 2 +- .../class-wp-css-compound-selector-list.php | 2 +- .../html-api/class-wp-html-processor.php | 52 ++++++------------- .../html-api/class-wp-html-tag-processor.php | 52 ++++++------------- .../tests/html-api/wpHtmlProcessor-select.php | 9 ++-- .../html-api/wpHtmlTagProcessor-select.php | 8 +-- 6 files changed, 41 insertions(+), 84 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php index d819cd469086f..5d6c4029af08e 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php @@ -12,7 +12,7 @@ * * This class is designed for internal use by the HTML processor. * - * For usage, see {@see WP_HTML_Processor::select()} or {@see WP_HTML_Processor::select_all()}. + * For usage, see {@see WP_HTML_Processor::select()}. * * This class is instantiated via the {@see WP_CSS_Complex_Selector_List::from_selectors()} method. * It takes a CSS selector string and returns an instance of itself or `null` if the selector diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php index 41cf76e2c90f6..d12f6cdeda944 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php @@ -12,7 +12,7 @@ * * This class is designed for internal use by the HTML Tag Processor. * - * For usage, see {@see WP_HTML_Tag_Processor::select()} or {@see WP_HTML_Tag_Processor::select_all()}. + * For usage, see {@see WP_HTML_Tag_Processor::select()}. * * This class is instantiated via the {@see WP_CSS_Compound_Selector_List::from_selectors()} method. * It takes a CSS selector string and returns an instance of itself or `null` if the selector diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index 4be8b2860f3ce..1f23e93a4023d 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -640,12 +640,12 @@ public function get_unsupported_exception() { /** * Progress through a document pausing on tags matching the provided CSS selector string. * - * @example + * Example: * * $processor = WP_HTML_Processor::create_fragment( * 'Example' * ); - * foreach ( $processor->select_all( 'meta[property^="og:" i]' ) as $_ ) { + * while ( $processor->select( 'meta[property^="og:" i]' ) ) { * // Loop is entered twice. * var_dump( * $processor->get_tag(), // string(4) "META" @@ -654,55 +654,37 @@ public function get_unsupported_exception() { * ); * } * - * @since 6.8.0 + * @since {WP_VERSION} * * @param string $selector_string Selector string. - * @return Generator A generator pausing on each tag matching the selector. + * @return bool Whether a selection was found. */ - public function select_all( $selector_string ): Generator { - $selector = WP_CSS_Complex_Selector_List::from_selectors( $selector_string ); + public function select( $selector_string ): bool { + static $previous_selector_string = null; + static $previous_selector = null; + + $selector = $selector_string === $previous_selector_string + ? $previous_selector + : WP_CSS_Complex_Selector_List::from_selectors( $selector_string ); + + $previous_selector = $selector; + $previous_selector_string = $selector_string; + if ( null === $selector ) { _doing_it_wrong( __METHOD__, sprintf( 'Received unsupported or invalid selector "%s".', $selector_string ), '6.8' ); - return; + return false; } while ( $this->next_tag() ) { if ( $selector->matches( $this ) ) { - yield; + return true; } } - } - /** - * Move to the next tag matching the provided CSS selector string. - * - * This method will stop at the next match. To progress through all matches, use - * the {@see WP_HTML_Processor::select_all()} method. - * - * @example - * - * $processor = WP_HTML_Processor::create_fragment( - * 'Example' - * ); - * $processor->select( 'meta[charset]' ); - * var_dump( - * $processor->get_tag(), // string(4) "META" - * $processor->get_attribute( 'charset' ), // string(5) "utf-8" - * ); - * - * @since 6.8.0 - * - * @param string $selector_string - * @return bool True if a matching tag was found, otherwise false. - */ - public function select( string $selector_string ): bool { - foreach ( $this->select_all( $selector_string ) as $_ ) { - return true; - } return false; } diff --git a/src/wp-includes/html-api/class-wp-html-tag-processor.php b/src/wp-includes/html-api/class-wp-html-tag-processor.php index 0f6b59441c75b..2f9d27e0f415c 100644 --- a/src/wp-includes/html-api/class-wp-html-tag-processor.php +++ b/src/wp-includes/html-api/class-wp-html-tag-processor.php @@ -863,12 +863,12 @@ public function change_parsing_namespace( string $new_namespace ): bool { /** * Progress through a document pausing on tags matching the provided CSS selector string. * - * @example + * Example: * * $processor = new WP_HTML_Tag_Processor( * 'Example' * ); - * foreach ( $processor->select_all( 'meta[property^="og:" i]' ) as $_ ) { + * while ( $processor->select( 'meta[property^="og:" i]' ) ) { * // Loop is entered twice. * var_dump( * $processor->get_tag(), // string(4) "META" @@ -877,55 +877,37 @@ public function change_parsing_namespace( string $new_namespace ): bool { * ); * } * - * @since 6.8.0 + * @since {WP_VERSION} * * @param string $selector_string Selector string. - * @return Generator A generator pausing on each tag matching the selector. + * @return bool Whether a selection was found. */ - public function select_all( $selector_string ): Generator { - $selector = WP_CSS_Compound_Selector_List::from_selectors( $selector_string ); + public function select( $selector_string ): bool { + static $previous_selector_string = null; + static $previous_selector = null; + + $selector = $selector_string === $previous_selector_string + ? $previous_selector + : WP_CSS_Compound_Selector_List::from_selectors( $selector_string ); + + $previous_selector = $selector; + $previous_selector_string = $selector_string; + if ( null === $selector ) { _doing_it_wrong( __METHOD__, sprintf( 'Received unsupported or invalid selector "%s".', $selector_string ), '6.8' ); - return; + return false; } while ( $this->next_tag() ) { if ( $selector->matches( $this ) ) { - yield; + return true; } } - } - /** - * Move to the next tag matching the provided CSS selector string. - * - * This method will stop at the next match. To progress through all matches, use - * the {@see WP_HTML_Tag_Processor::select_all()} method. - * - * @example - * - * $processor = new WP_HTML_Tag_Processor( - * 'Example' - * ); - * $processor->select( 'meta[charset]' ); - * var_dump( - * $processor->get_tag(), // string(4) "META" - * $processor->get_attribute( 'charset' ), // string(5) "utf-8" - * ); - * - * @since 6.8.0 - * - * @param string $selector_string - * @return bool True if a matching tag was found, otherwise false. - */ - public function select( string $selector_string ): bool { - foreach ( $this->select_all( $selector_string ) as $_ ) { - return true; - } return false; } diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php index a8f6a7c949080..6ce8e6606fc51 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php @@ -3,10 +3,7 @@ * Unit tests covering WP_HTML_Processor select functionality. * * Covers functionality related to CSS selectors and the {@see WP_HTML_Processor::select()} - * and {@see WP_HTML_Processor::select_all()} methods. - * - * @package WordPress - * @subpackage HTML-API + * and {@see WP_HTML_Processor::select()} methods. * * @since 6.8.0 * @@ -26,10 +23,10 @@ public function test_select_miss() { * * @dataProvider data_selectors */ - public function test_select_all( string $html, string $selector, int $match_count ) { + public function test_selects_all_matches( string $html, string $selector, int $match_count ) { $processor = WP_HTML_Processor::create_full_parser( $html ); $count = 0; - foreach ( $processor->select_all( $selector ) as $_ ) { + while ( $processor->select( $selector ) ) { $breadcrumb_string = implode( ', ', $processor->get_breadcrumbs() ); $this->assertTrue( $processor->get_attribute( 'match' ), diff --git a/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php index 28f88778629ce..4f35fc777f3b6 100644 --- a/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php +++ b/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php @@ -2,11 +2,7 @@ /** * Unit tests covering WP_HTML_Tag_Processor CSS selection functionality. * - * Covers functionality related to CSS selectors and the {@see WP_HTML_Tag_Processor::select()} - * and {@see WP_HTML_Tag_Processor::select_all()} methods. - * - * @package WordPress - * @subpackage HTML-API + * Covers functionality related to CSS selectors and the {@see WP_HTML_Tag_Processor::select()} method. * * @since 6.8.0 * @@ -29,7 +25,7 @@ public function test_select_miss() { public function test_select( string $html, string $selector, int $match_count ) { $processor = new WP_HTML_Tag_Processor( $html ); $count = 0; - foreach ( $processor->select_all( $selector ) as $_ ) { + while ( $processor->select( $selector ) ) { $this->assertTrue( $processor->get_attribute( 'match' ), "Matched unexpected tag {$processor->get_tag()}" From 2d931ef7e768ed6a522fbf44eb78b050de88c04d Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 15 Jul 2025 10:26:52 +0200 Subject: [PATCH 134/634] Fix expectedIncorrectUsage method name --- tests/phpunit/tests/html-api/wpHtmlProcessor-select.php | 2 +- tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php index 6ce8e6606fc51..9bdae5802dfe4 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php @@ -59,7 +59,7 @@ public static function data_selectors(): array { /** * @ticket 62653 * - * @expectedIncorrectUsage WP_HTML_Processor::select_all + * @expectedIncorrectUsage WP_HTML_Processor::select * * @dataProvider data_invalid_selectors */ diff --git a/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php index 4f35fc777f3b6..a133ea63bc3fa 100644 --- a/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php +++ b/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php @@ -83,7 +83,7 @@ public static function data_selectors(): array { /** * @ticket 62653 * - * @expectedIncorrectUsage WP_HTML_Tag_Processor::select_all + * @expectedIncorrectUsage WP_HTML_Tag_Processor::select * * @dataProvider data_invalid_selectors */ From 53ee08d14888d4dd9c5f4614e4721292c9803271 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 15 Jul 2025 10:27:15 +0200 Subject: [PATCH 135/634] Improve and fix complex selector list documentation --- .../class-wp-css-complex-selector-list.php | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php index 5d6c4029af08e..bc1dd5f25d849 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php @@ -21,14 +21,24 @@ * A subset of the CSS selector grammar is supported. The grammar is defined in the CSS Syntax * specification, which is available at {@link https://www.w3.org/TR/selectors/#grammar}. * - * This class is rougly analogous to the in the grammar. See {@see WP_CSS_Compound_Selector_List} for more details on the grammar. + * This class is rougly analogous to the in the grammar. + * See {@see WP_CSS_Compound_Selector_List} for more details on the grammar. * - * This class supports the same selector syntax as {@see WP_CSS_Compound_Selector_List} as well as: - * - The following combinators: - * - Next sibling (`el + el`) - * - Subsequent sibling (`el ~ el`) + * This class supports the same selector syntax as {@see WP_CSS_Compound_Selector_List} as well as + * the following combinators: + * - Descendant (`ancestor descendant`) + * - Child (`parent > child`) * - * @since 6.8.0 + * Combinators may only be used with type selectors in the non-final position, for example: + * - `div [type=input]` is valid because the `div` type selector appears in a non-final position. + * - `[disabled] option` is NOT valid, because the `[disabled]` attribute selector appears + * a non-final position. + * + * These combinators are not supported: + * - Next sibling (`former-sibling + next-sibling`) + * - Subsequent sibling (`former-sibling ~ subsequent-sibling`) + * + * @since {WP_VERSION} * * @access private */ From a627471539c46d33b343fdc6155946e3f455aed5 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 15 Jul 2025 10:27:32 +0200 Subject: [PATCH 136/634] Add unsupports sibling selector tests --- .../phpunit/tests/html-api/wpHtmlProcessor-select.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php index 9bdae5802dfe4..419d9831cbe63 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php @@ -75,11 +75,15 @@ public function test_invalid_selector( string $selector ) { */ public static function data_invalid_selectors(): array { return array( - 'invalid selector' => array( '[invalid!selector]' ), + 'invalid selector' => array( '[invalid!selector]' ), // The class selectors below are not allowed in non-final position. - 'unsupported child selector' => array( '.parent > .child' ), - 'unsupported descendant selector' => array( '.ancestor .descendant' ), + 'unsupported child selector' => array( '.parent > .child' ), + 'unsupported descendant selector' => array( '.ancestor .descendant' ), + + // Unsupported combinators + 'unsupported next sibling selector' => array( 'p + p' ), + 'unsupported subsequent sibling selector' => array( 'p ~ p' ), ); } } From 0058e15e37c32a190d6a33132e8f5320bd94ea87 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 15 Jul 2025 10:31:31 +0200 Subject: [PATCH 137/634] Do not support + and ~ selectors --- src/wp-includes/html-api/class-wp-css-complex-selector.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector.php b/src/wp-includes/html-api/class-wp-css-complex-selector.php index 8c7c25ed7b984..832bea2df6926 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector.php @@ -218,10 +218,14 @@ public static function parse( string $input, int &$offset ) { $combinator = null; $next_selector = null; + // Sibling (`+` and `~`) combinators are not supported at this time. if ( - WP_CSS_Complex_Selector::COMBINATOR_CHILD === $input[ $updated_offset ] || WP_CSS_Complex_Selector::COMBINATOR_NEXT_SIBLING === $input[ $updated_offset ] || WP_CSS_Complex_Selector::COMBINATOR_SUBSEQUENT_SIBLING === $input[ $updated_offset ] + ) { + return null; + } elseif ( + WP_CSS_Complex_Selector::COMBINATOR_CHILD === $input[ $updated_offset ] ) { $combinator = $input[ $updated_offset ]; ++$updated_offset; From a99207dad15b164ed82940049dcb0c6e3f7162eb Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 15 Jul 2025 10:36:00 +0200 Subject: [PATCH 138/634] Update @since tags to WP_VERSION placeholder --- .../html-api/class-wp-css-attribute-selector.php | 4 ++-- src/wp-includes/html-api/class-wp-css-class-selector.php | 4 ++-- .../html-api/class-wp-css-complex-selector-list.php | 2 +- src/wp-includes/html-api/class-wp-css-complex-selector.php | 6 +++--- .../html-api/class-wp-css-compound-selector-list.php | 6 ++---- src/wp-includes/html-api/class-wp-css-compound-selector.php | 4 ++-- src/wp-includes/html-api/class-wp-css-id-selector.php | 4 ++-- src/wp-includes/html-api/class-wp-css-type-selector.php | 4 ++-- src/wp-includes/html-api/class-wp-html-processor.php | 2 +- src/wp-includes/html-api/class-wp-html-tag-processor.php | 2 +- tests/phpunit/tests/html-api/wpCssAttributeSelector.php | 2 +- tests/phpunit/tests/html-api/wpCssClassSelector.php | 2 +- tests/phpunit/tests/html-api/wpCssComplexSelector.php | 2 +- tests/phpunit/tests/html-api/wpCssComplexSelectorList.php | 2 +- tests/phpunit/tests/html-api/wpCssCompoundSelector.php | 2 +- tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php | 2 +- tests/phpunit/tests/html-api/wpCssIdSelector.php | 2 +- tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php | 2 +- tests/phpunit/tests/html-api/wpCssTypeSelector.php | 2 +- tests/phpunit/tests/html-api/wpHtmlProcessor-select.php | 2 +- tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php | 2 +- 21 files changed, 29 insertions(+), 31 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-attribute-selector.php b/src/wp-includes/html-api/class-wp-css-attribute-selector.php index dde5f12bbf962..7e8e21bacbc26 100644 --- a/src/wp-includes/html-api/class-wp-css-attribute-selector.php +++ b/src/wp-includes/html-api/class-wp-css-attribute-selector.php @@ -4,7 +4,7 @@ * * @package WordPress * @subpackage HTML-API - * @since 6.8.0 + * @since {WP_VERSION} */ /** @@ -12,7 +12,7 @@ * * This class is used to test for matching HTML tags in a {@see WP_HTML_Tag_Processor}. * - * @since 6.8.0 + * @since {WP_VERSION} * * @access private */ diff --git a/src/wp-includes/html-api/class-wp-css-class-selector.php b/src/wp-includes/html-api/class-wp-css-class-selector.php index 57f7dac50315f..121b3abf10f96 100644 --- a/src/wp-includes/html-api/class-wp-css-class-selector.php +++ b/src/wp-includes/html-api/class-wp-css-class-selector.php @@ -4,7 +4,7 @@ * * @package WordPress * @subpackage HTML-API - * @since 6.8.0 + * @since {WP_VERSION} */ /** @@ -12,7 +12,7 @@ * * This class is used to test for matching HTML tags in a {@see WP_HTML_Tag_Processor}. * - * @since 6.8.0 + * @since {WP_VERSION} * * @access private */ diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php index bc1dd5f25d849..80c84c10cfad9 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php @@ -4,7 +4,7 @@ * * @package WordPress * @subpackage HTML-API - * @since 6.8.0 + * @since {WP_VERSION} */ /** diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector.php b/src/wp-includes/html-api/class-wp-css-complex-selector.php index 832bea2df6926..96a4fd10be481 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector.php @@ -4,7 +4,7 @@ * * @package WordPress * @subpackage HTML-API - * @since 6.8.0 + * @since {WP_VERSION} */ /** @@ -15,7 +15,7 @@ * A compound selector is at least a single compound selector. There may be additional selectors * with combinators. * - * @since 6.8.0 + * @since {WP_VERSION} * * @access private */ @@ -184,7 +184,7 @@ private function explore_matches( array $selectors, array $breadcrumbs ): bool { __( 'Unsupported combinator "%s" found.' ), $combinator ), - '6.8.0' + '{WP_VERSION}' ); return false; } diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php index d12f6cdeda944..c55eccb0dfe56 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php @@ -4,7 +4,7 @@ * * @package WordPress * @subpackage HTML-API - * @since 6.8.0 + * @since {WP_VERSION} */ /** @@ -67,7 +67,7 @@ * - `svg|*` to select all SVG elements * - `html|title` to select only HTML TITLE elements. * - * @since 6.8.0 + * @since {WP_VERSION} * * @access private * @@ -116,8 +116,6 @@ protected function __construct( array $selectors ) { * Takes a CSS selector string and returns an instance of itself or `null` if the selector * string is invalid or unsupported. * - * @since 6.8.0 - * * @param string $input CSS selectors. * @return static|null */ diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector.php b/src/wp-includes/html-api/class-wp-css-compound-selector.php index 91e543fdc7e7e..48e206819c0d3 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector.php @@ -4,7 +4,7 @@ * * @package WordPress * @subpackage HTML-API - * @since 6.8.0 + * @since {WP_VERSION} */ /** @@ -17,7 +17,7 @@ * - Zero or more subclass selectors (ID, class, or attribute selectors). * - At least one of the above. * - * @since 6.8.0 + * @since {WP_VERSION} * * @access private */ diff --git a/src/wp-includes/html-api/class-wp-css-id-selector.php b/src/wp-includes/html-api/class-wp-css-id-selector.php index f0c203dc6477e..1d3b7f1f85d16 100644 --- a/src/wp-includes/html-api/class-wp-css-id-selector.php +++ b/src/wp-includes/html-api/class-wp-css-id-selector.php @@ -4,7 +4,7 @@ * * @package WordPress * @subpackage HTML-API - * @since 6.8.0 + * @since {WP_VERSION} */ /** @@ -12,7 +12,7 @@ * * This class is used to test for matching HTML tags in a {@see WP_HTML_Tag_Processor}. * - * @since 6.8.0 + * @since {WP_VERSION} * * @access private */ diff --git a/src/wp-includes/html-api/class-wp-css-type-selector.php b/src/wp-includes/html-api/class-wp-css-type-selector.php index c16883fa60679..c7c7baa2d5508 100644 --- a/src/wp-includes/html-api/class-wp-css-type-selector.php +++ b/src/wp-includes/html-api/class-wp-css-type-selector.php @@ -4,7 +4,7 @@ * * @package WordPress * @subpackage HTML-API - * @since 6.8.0 + * @since {WP_VERSION} */ /** @@ -12,7 +12,7 @@ * * This class is used to test for matching HTML tags in a {@see WP_HTML_Tag_Processor}. * - * @since 6.8.0 + * @since {WP_VERSION} * * @access private */ diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index 1f23e93a4023d..a17ba18de3340 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -674,7 +674,7 @@ public function select( $selector_string ): bool { _doing_it_wrong( __METHOD__, sprintf( 'Received unsupported or invalid selector "%s".', $selector_string ), - '6.8' + '{WP_VERSION}' ); return false; } diff --git a/src/wp-includes/html-api/class-wp-html-tag-processor.php b/src/wp-includes/html-api/class-wp-html-tag-processor.php index 2f9d27e0f415c..ac066a908b6c9 100644 --- a/src/wp-includes/html-api/class-wp-html-tag-processor.php +++ b/src/wp-includes/html-api/class-wp-html-tag-processor.php @@ -897,7 +897,7 @@ public function select( $selector_string ): bool { _doing_it_wrong( __METHOD__, sprintf( 'Received unsupported or invalid selector "%s".', $selector_string ), - '6.8' + '{WP_VERSION}' ); return false; } diff --git a/tests/phpunit/tests/html-api/wpCssAttributeSelector.php b/tests/phpunit/tests/html-api/wpCssAttributeSelector.php index 45fa787f7a4ff..e574cedd1876b 100644 --- a/tests/phpunit/tests/html-api/wpCssAttributeSelector.php +++ b/tests/phpunit/tests/html-api/wpCssAttributeSelector.php @@ -6,7 +6,7 @@ * * @subpackage HTML-API * - * @since 6.8.0 + * @since {WP_VERSION} * * @group html-api * diff --git a/tests/phpunit/tests/html-api/wpCssClassSelector.php b/tests/phpunit/tests/html-api/wpCssClassSelector.php index fa1d097a5ad3d..9646d05da23d5 100644 --- a/tests/phpunit/tests/html-api/wpCssClassSelector.php +++ b/tests/phpunit/tests/html-api/wpCssClassSelector.php @@ -6,7 +6,7 @@ * * @subpackage HTML-API * - * @since 6.8.0 + * @since {WP_VERSION} * * @group html-api * diff --git a/tests/phpunit/tests/html-api/wpCssComplexSelector.php b/tests/phpunit/tests/html-api/wpCssComplexSelector.php index bb7b6e67e9d1a..8738bb6fc32d2 100644 --- a/tests/phpunit/tests/html-api/wpCssComplexSelector.php +++ b/tests/phpunit/tests/html-api/wpCssComplexSelector.php @@ -6,7 +6,7 @@ * * @subpackage HTML-API * - * @since 6.8.0 + * @since {WP_VERSION} * * @group html-api * diff --git a/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php b/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php index 4e788860ff53f..edf912e97f490 100644 --- a/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php +++ b/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php @@ -6,7 +6,7 @@ * * @subpackage HTML-API * - * @since 6.8.0 + * @since {WP_VERSION} * * @group html-api * diff --git a/tests/phpunit/tests/html-api/wpCssCompoundSelector.php b/tests/phpunit/tests/html-api/wpCssCompoundSelector.php index 8800c89d6ed36..8092ee049b6e1 100644 --- a/tests/phpunit/tests/html-api/wpCssCompoundSelector.php +++ b/tests/phpunit/tests/html-api/wpCssCompoundSelector.php @@ -6,7 +6,7 @@ * * @subpackage HTML-API * - * @since 6.8.0 + * @since {WP_VERSION} * * @group html-api * diff --git a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php index 01eff118a87b0..af05332c9aa3e 100644 --- a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php +++ b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php @@ -6,7 +6,7 @@ * * @subpackage HTML-API * - * @since 6.8.0 + * @since {WP_VERSION} * * @group html-api * diff --git a/tests/phpunit/tests/html-api/wpCssIdSelector.php b/tests/phpunit/tests/html-api/wpCssIdSelector.php index 6cd6b83a46b8d..6dc2e5461ea03 100644 --- a/tests/phpunit/tests/html-api/wpCssIdSelector.php +++ b/tests/phpunit/tests/html-api/wpCssIdSelector.php @@ -6,7 +6,7 @@ * * @subpackage HTML-API * - * @since 6.8.0 + * @since {WP_VERSION} * * @group html-api * diff --git a/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php b/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php index 29a76bfd78723..29372172da2b1 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php +++ b/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php @@ -6,7 +6,7 @@ * * @subpackage HTML-API * - * @since 6.8.0 + * @since {WP_VERSION} * * @group html-api */ diff --git a/tests/phpunit/tests/html-api/wpCssTypeSelector.php b/tests/phpunit/tests/html-api/wpCssTypeSelector.php index fb53c41dd058c..23d5f5517453a 100644 --- a/tests/phpunit/tests/html-api/wpCssTypeSelector.php +++ b/tests/phpunit/tests/html-api/wpCssTypeSelector.php @@ -6,7 +6,7 @@ * * @subpackage HTML-API * - * @since 6.8.0 + * @since {WP_VERSION} * * @group html-api * diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php index 419d9831cbe63..003e65e69ebce 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php @@ -5,7 +5,7 @@ * Covers functionality related to CSS selectors and the {@see WP_HTML_Processor::select()} * and {@see WP_HTML_Processor::select()} methods. * - * @since 6.8.0 + * @since {WP_VERSION} * * @group html-api */ diff --git a/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php index a133ea63bc3fa..1d09c61b4760d 100644 --- a/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php +++ b/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php @@ -4,7 +4,7 @@ * * Covers functionality related to CSS selectors and the {@see WP_HTML_Tag_Processor::select()} method. * - * @since 6.8.0 + * @since {WP_VERSION} * * @group html-api */ From 0fb0c2010f4e6c729fb410a4df7f8f8e331223ef Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 15 Jul 2025 10:48:34 +0200 Subject: [PATCH 139/634] Add unsupported complex selector test --- .../phpunit/tests/html-api/wpCssCompoundSelectorList.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php index af05332c9aa3e..8f1d3dfb88a45 100644 --- a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php +++ b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php @@ -48,4 +48,13 @@ public function test_parse_empty_selector_list() { $result = WP_CSS_Compound_Selector_List::from_selectors( $input ); $this->assertNull( $result ); } + + /** + * @ticket 62653 + */ + public function test_unsupported_complex_selector() { + $input = 'ancestor descendant'; + $result = WP_CSS_Compound_Selector_List::from_selectors( $input ); + $this->assertNull( $result ); + } } From 2f47c32955139dae5fef66e21efa1ad8668ff1ed Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 15 Jul 2025 10:53:10 +0200 Subject: [PATCH 140/634] Fix spelling and grammar in documentation --- .../html-api/class-wp-css-complex-selector-list.php | 4 ++-- src/wp-includes/html-api/class-wp-css-complex-selector.php | 2 +- .../html-api/class-wp-css-compound-selector-list.php | 2 +- .../html-api/class-wp-css-selector-parser-matcher.php | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php index 80c84c10cfad9..da5e17011e0d8 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector-list.php @@ -21,7 +21,7 @@ * A subset of the CSS selector grammar is supported. The grammar is defined in the CSS Syntax * specification, which is available at {@link https://www.w3.org/TR/selectors/#grammar}. * - * This class is rougly analogous to the in the grammar. + * This class is roughly analogous to the in the grammar. * See {@see WP_CSS_Compound_Selector_List} for more details on the grammar. * * This class supports the same selector syntax as {@see WP_CSS_Compound_Selector_List} as well as @@ -32,7 +32,7 @@ * Combinators may only be used with type selectors in the non-final position, for example: * - `div [type=input]` is valid because the `div` type selector appears in a non-final position. * - `[disabled] option` is NOT valid, because the `[disabled]` attribute selector appears - * a non-final position. + * in a non-final position. * * These combinators are not supported: * - Next sibling (`former-sibling + next-sibling`) diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector.php b/src/wp-includes/html-api/class-wp-css-complex-selector.php index 96a4fd10be481..36671067be537 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector.php @@ -12,7 +12,7 @@ * * This class is used to test for matching HTML tags in a {@see WP_HTML_Processor}. * - * A compound selector is at least a single compound selector. There may be additional selectors + * A complex selector is at least a single compound selector. There may be additional selectors * with combinators. * * @since {WP_VERSION} diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php index c55eccb0dfe56..d70cff59f7428 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php @@ -59,7 +59,7 @@ * - Pseudo-element selectors (`::before`) * - Pseudo-class selectors (`:hover` or `:nth-child(2)`) * - Namespace prefixes (`svg|title` or `[xlink|href]`) - * - No combinators are supported (descendant, child, next sibling, subsequent sibling) + * - Combinators are not supported (descendant, child, next sibling, subsequent sibling) * * Future ideas: * - Namespace type selectors could be implemented with select namespaces in order to diff --git a/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php b/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php index e2b56a7b9e55c..180ecba98bacf 100644 --- a/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php +++ b/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php @@ -8,7 +8,7 @@ */ /** - * Base class for all CSS Selector praser/matcher classes. + * Base class for all CSS Selector parser/matcher classes. * * @since 6.8.0 * @@ -50,7 +50,7 @@ abstract public static function parse( string $input, int &$offset ); * * @param string $input The selector string. * @param int $offset The offset into the string. The offset is passed by reference and will - * be update to the byte after the whitespace sequence. + * be updated to the byte after the whitespace sequence. * @return bool True if whitespace was consumed. */ final protected static function parse_whitespace( string $input, int &$offset ): bool { @@ -258,7 +258,7 @@ final protected static function consume_escaped_codepoint( $input, &$offset ): s /** * Parse an ident token * - * CAUTION: This method is _not_ for parsing and ID selector! + * CAUTION: This method is _not_ for parsing an ID selector! * * > 4.3.11. Consume an ident sequence * > This section describes how to consume an ident sequence from a stream of code points. It returns a string containing the largest name that can be formed from adjacent code points in the stream, starting from the first. From c5723916f34c10fdf5e81ee636edddcc0a2e4f90 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 15 Jul 2025 17:05:28 +0200 Subject: [PATCH 141/634] Improve documentation --- .../class-wp-css-complex-selector.php | 40 +++++++------------ .../class-wp-css-compound-selector-list.php | 5 ++- 2 files changed, 18 insertions(+), 27 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector.php b/src/wp-includes/html-api/class-wp-css-complex-selector.php index 36671067be537..4ebe9fd476f5a 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector.php @@ -48,7 +48,7 @@ final class WP_CSS_Complex_Selector extends WP_CSS_Selector_Parser_Matcher { * The "self selector" is the last element in a complex selector, it corresponds to the * selected element. * - * @example + * Example: * * $self_selector * ┏━━━━┻━━━━┓ @@ -67,38 +67,28 @@ final class WP_CSS_Complex_Selector extends WP_CSS_Selector_Parser_Matcher { * the element at index 1 is the combinator string constant from this class, * e.g. `WP_CSS_Complex_Selector::COMBINATOR_CHILD`. * - * In the example selector below, an element like `` is selected iff: + * In the example selector below, an element like `` matches iff: * - it is a child of an `H1` element - * - *and* that `H1` element is a descendant of a `HEADING` element. + * - that `H1` element is a descendant of a `SECTION` element. * - * The `H1` and `HEADING` parts of this selector are the "context selectors." Note that this - * terminology is used for purposes of this class but does not correspond to language in the - * CSS or selector specifications. - * - * @example + * The `section` and `h1` parts of this selector and their combinators are the + * "context selectors." Note that this terminology does not correspond to language in the + * specification texts. * * $context_selectors - * ┏━━━━━━┻━━━━┓ - * .heading h1 > el.selected - * - * The example would have the following relative selectors: + * ┏━━━━━┻━━━━┓ + * section h1 > strong.selected * - * @example + * The example would have the following context selectors: * - * array ( - * array( - * WP_CSS_Type_Selector( 'ident' => 'h1' ), - * '>', // WP_CSS_Complex_Selector::COMBINATOR_CHILD - * ), - * array( - * new WP_CSS_Type_Selector( 'header' ), - * ' ', // WP_CSS_Complex_Selector::COMBINATOR_DESCENDANT - * ), + * // Pseudo-code + * array( + * array( WP_CSS_Type_Selector( 'type'=>'h1' ), '>' ), + * array( WP_CSS_Type_Selector( 'type'=>'section' ), ' ' ), * ) * - * Note that the order of context selectors is reversed. This is to match the self selector - * first and then match the context selectors beginning with the selector closest to the self - * selector. + * Context selectors are ordered from right to left in the selector text. The selectors closest + * to the target appear at the start of the `context_selectors` array. * * @readonly * @var array{WP_CSS_Type_Selector, string}[]|null diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php index d70cff59f7428..edc6a841a859a 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php @@ -41,7 +41,7 @@ * @link https://www.w3.org/TR/selectors/#grammar Refer to the grammar for more details. * * This class of selectors does not support "complex" selectors. That is any selector with a - * combinator such as descendent (`.ancestor .descendant`) or child (`.parent > .child`). + * combinator such as descendant (`.ancestor .descendant`) or child (`.parent > .child`). * See {@see WP_CSS_Complex_Selector_List} for support of some combinators. * * Note that this grammar has been adapted and does not support the full CSS selector grammar. @@ -59,7 +59,8 @@ * - Pseudo-element selectors (`::before`) * - Pseudo-class selectors (`:hover` or `:nth-child(2)`) * - Namespace prefixes (`svg|title` or `[xlink|href]`) - * - Combinators are not supported (descendant, child, next sibling, subsequent sibling) + * - Combinators are not supported by this class (descendant, child, next sibling, + * subsequent sibling). See {@see WP_CSS_Complex_Selector_List} for combinator support. * * Future ideas: * - Namespace type selectors could be implemented with select namespaces in order to From ac2fb562c560033708cd8cec1321589c8af999f3 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 15 Jul 2025 17:18:47 +0200 Subject: [PATCH 142/634] More documentation improvements --- src/wp-includes/html-api/class-wp-css-attribute-selector.php | 2 +- src/wp-includes/html-api/class-wp-css-complex-selector.php | 4 ++-- .../html-api/class-wp-css-compound-selector-list.php | 4 +--- .../html-api/class-wp-css-selector-parser-matcher.php | 4 ++-- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-attribute-selector.php b/src/wp-includes/html-api/class-wp-css-attribute-selector.php index 7e8e21bacbc26..a63dfaba66b61 100644 --- a/src/wp-includes/html-api/class-wp-css-attribute-selector.php +++ b/src/wp-includes/html-api/class-wp-css-attribute-selector.php @@ -217,7 +217,7 @@ public function matches( WP_HTML_Tag_Processor $processor ): bool { * * @param string $input * - * @return Generator + * @return Generator Yields each whitespace-delimited value from the input string. */ private function whitespace_delimited_list( string $input ): Generator { // Start by skipping whitespace. diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector.php b/src/wp-includes/html-api/class-wp-css-complex-selector.php index 4ebe9fd476f5a..fd05c29daba91 100644 --- a/src/wp-includes/html-api/class-wp-css-complex-selector.php +++ b/src/wp-includes/html-api/class-wp-css-complex-selector.php @@ -99,7 +99,7 @@ final class WP_CSS_Complex_Selector extends WP_CSS_Selector_Parser_Matcher { * Constructor. * * @param WP_CSS_Compound_Selector $self_selector The selector in the final position. - * @param array{WP_CSS_Type_Selector, string}[]|null $selectors The context selectors. + * @param array{WP_CSS_Type_Selector, string}[]|null $context_selectors The context selectors. */ private function __construct( WP_CSS_Compound_Selector $self_selector, @@ -246,7 +246,7 @@ public static function parse( string $input, int &$offset ) { return null; } - /** @var array{WP_CSS_Compound_Selector, string} */ + /** @var array{WP_CSS_Type_Selector, string} */ $selector_pair = array( $self_selector->type_selector, $combinator ); $selectors[] = $selector_pair; $self_selector = $next_selector; diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php index edc6a841a859a..c9eb936ff7371 100644 --- a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php +++ b/src/wp-includes/html-api/class-wp-css-compound-selector-list.php @@ -51,9 +51,7 @@ * - ID selectors (e.g. `#unique-id`) * - Attribute selectors (e.g. `[attribute-name]` or `[attribute-name="value"]`) * - Comma-separated selector lists (e.g. `.selector-1, .selector-2`) - * - The following combinators. Only type (element) selectors are allowed in non-final position: - * - descendant (e.g. `el .descendant`) - * - child (`el > .child`) + * - Compound selectors (e.g. `div.class-name#id[attr]`) * * Unsupported selector syntax: * - Pseudo-element selectors (`::before`) diff --git a/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php b/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php index 180ecba98bacf..e020bbb664d3f 100644 --- a/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php +++ b/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php @@ -123,7 +123,7 @@ final protected static function parse_hash_token( string $input, int &$offset ): * the is not a part of the selector grammar. That * case is treated as failure to parse and null is returned. * - * @return string|null + * @return string|null The parsed string token value, or null if parsing failed. */ final protected static function parse_string( string $input, int &$offset ): ?string { if ( $offset >= strlen( $input ) ) { @@ -278,7 +278,7 @@ final protected static function consume_escaped_codepoint( $input, &$offset ): s * * https://www.w3.org/TR/css-syntax-3/#consume-name * - * @return string|null + * @return string|null The parsed identifier name, or null if parsing failed. */ final protected static function parse_ident( string $input, int &$offset ): ?string { if ( ! self::check_if_three_code_points_would_start_an_ident_sequence( $input, $offset ) ) { From 57b5128ba1381a15d5c8df6157083b7b14490e74 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 15 Jul 2025 17:19:06 +0200 Subject: [PATCH 143/634] Avoid redundant get_attribute call --- src/wp-includes/html-api/class-wp-css-id-selector.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-id-selector.php b/src/wp-includes/html-api/class-wp-css-id-selector.php index 1d3b7f1f85d16..e2e47a24d1e6c 100644 --- a/src/wp-includes/html-api/class-wp-css-id-selector.php +++ b/src/wp-includes/html-api/class-wp-css-id-selector.php @@ -48,8 +48,8 @@ public function matches( WP_HTML_Tag_Processor $processor ): bool { $case_insensitive = $processor->is_quirks_mode(); return $case_insensitive - ? 0 === strcasecmp( $id, $this->id ) - : $processor->get_attribute( 'id' ) === $this->id; + ? 0 === strcasecmp( $id, $this->id ) + : $id === $this->id; } /** From 5f06f84c2eb45594c5f7147bb28cb5865893a43a Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 15 Jul 2025 17:34:05 +0200 Subject: [PATCH 144/634] Reformat some documentation --- .../html-api/class-wp-css-selector-parser-matcher.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php b/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php index e020bbb664d3f..aa8153ca27f45 100644 --- a/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php +++ b/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php @@ -316,7 +316,10 @@ final protected static function parse_ident( string $input, int &$offset ): ?str * Checks for two valid escape codepoints. * * > 4.3.8. Check if two code points are a valid escape - * > This section describes how to check if two code points are a valid escape. The algorithm described here can be called explicitly with two code points, or can be called with the input stream itself. In the latter case, the two code points in question are the current input code point and the next input code point, in that order. + * > This section describes how to check if two code points are a valid escape. The algorithm + * > described here can be called explicitly with two code points, or can be called with the + * > input stream itself. In the latter case, the two code points in question are the current + * > input code point and the next input code point, in that order. * > * > Note: This algorithm will not consume any additional code point. * > @@ -328,7 +331,7 @@ final protected static function parse_ident( string $input, int &$offset ): ?str * * https://www.w3.org/TR/css-syntax-3/#starts-with-a-valid-escape * - * @todo this does not check whether the second codepoint is valid. + * @todo The second codepoint is not checked for validity. * * @param string $input The input string. * @param int $offset The byte offset in the string. From e559f6a18a410c75f73ab566412a5c83fce210eb Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Tue, 15 Jul 2025 13:53:52 -0500 Subject: [PATCH 145/634] Rename files and remove duplicate character --- .../class-wp-css-attribute-selector.php | 0 .../{ => css}/class-wp-css-class-selector.php | 0 .../class-wp-css-complex-selector-list.php | 0 .../class-wp-css-complex-selector.php | 0 .../class-wp-css-compound-selector-list.php | 0 .../class-wp-css-compound-selector.php | 0 .../{ => css}/class-wp-css-id-selector.php | 0 .../class-wp-css-selector-parser-matcher.php | 2 +- .../{ => css}/class-wp-css-type-selector.php | 0 src/wp-settings.php | 18 +++++++++--------- 10 files changed, 10 insertions(+), 10 deletions(-) rename src/wp-includes/html-api/{ => css}/class-wp-css-attribute-selector.php (100%) rename src/wp-includes/html-api/{ => css}/class-wp-css-class-selector.php (100%) rename src/wp-includes/html-api/{ => css}/class-wp-css-complex-selector-list.php (100%) rename src/wp-includes/html-api/{ => css}/class-wp-css-complex-selector.php (100%) rename src/wp-includes/html-api/{ => css}/class-wp-css-compound-selector-list.php (100%) rename src/wp-includes/html-api/{ => css}/class-wp-css-compound-selector.php (100%) rename src/wp-includes/html-api/{ => css}/class-wp-css-id-selector.php (100%) rename src/wp-includes/html-api/{ => css}/class-wp-css-selector-parser-matcher.php (99%) rename src/wp-includes/html-api/{ => css}/class-wp-css-type-selector.php (100%) diff --git a/src/wp-includes/html-api/class-wp-css-attribute-selector.php b/src/wp-includes/html-api/css/class-wp-css-attribute-selector.php similarity index 100% rename from src/wp-includes/html-api/class-wp-css-attribute-selector.php rename to src/wp-includes/html-api/css/class-wp-css-attribute-selector.php diff --git a/src/wp-includes/html-api/class-wp-css-class-selector.php b/src/wp-includes/html-api/css/class-wp-css-class-selector.php similarity index 100% rename from src/wp-includes/html-api/class-wp-css-class-selector.php rename to src/wp-includes/html-api/css/class-wp-css-class-selector.php diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector-list.php b/src/wp-includes/html-api/css/class-wp-css-complex-selector-list.php similarity index 100% rename from src/wp-includes/html-api/class-wp-css-complex-selector-list.php rename to src/wp-includes/html-api/css/class-wp-css-complex-selector-list.php diff --git a/src/wp-includes/html-api/class-wp-css-complex-selector.php b/src/wp-includes/html-api/css/class-wp-css-complex-selector.php similarity index 100% rename from src/wp-includes/html-api/class-wp-css-complex-selector.php rename to src/wp-includes/html-api/css/class-wp-css-complex-selector.php diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector-list.php b/src/wp-includes/html-api/css/class-wp-css-compound-selector-list.php similarity index 100% rename from src/wp-includes/html-api/class-wp-css-compound-selector-list.php rename to src/wp-includes/html-api/css/class-wp-css-compound-selector-list.php diff --git a/src/wp-includes/html-api/class-wp-css-compound-selector.php b/src/wp-includes/html-api/css/class-wp-css-compound-selector.php similarity index 100% rename from src/wp-includes/html-api/class-wp-css-compound-selector.php rename to src/wp-includes/html-api/css/class-wp-css-compound-selector.php diff --git a/src/wp-includes/html-api/class-wp-css-id-selector.php b/src/wp-includes/html-api/css/class-wp-css-id-selector.php similarity index 100% rename from src/wp-includes/html-api/class-wp-css-id-selector.php rename to src/wp-includes/html-api/css/class-wp-css-id-selector.php diff --git a/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php b/src/wp-includes/html-api/css/class-wp-css-selector-parser-matcher.php similarity index 99% rename from src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php rename to src/wp-includes/html-api/css/class-wp-css-selector-parser-matcher.php index aa8153ca27f45..cac314e8b6c27 100644 --- a/src/wp-includes/html-api/class-wp-css-selector-parser-matcher.php +++ b/src/wp-includes/html-api/css/class-wp-css-selector-parser-matcher.php @@ -482,7 +482,7 @@ final protected static function normalize_selector_input( string $input ): strin * This list includes \f. * A later step would normalize it to a known whitespace character, but it can be trimmed here as well. */ - $input = trim( $input, " \t\r\n\r\f" ); + $input = trim( $input, " \t\r\n\f" ); /* * > The input stream consists of the filtered code points pushed into it as the input byte stream is decoded. diff --git a/src/wp-includes/html-api/class-wp-css-type-selector.php b/src/wp-includes/html-api/css/class-wp-css-type-selector.php similarity index 100% rename from src/wp-includes/html-api/class-wp-css-type-selector.php rename to src/wp-includes/html-api/css/class-wp-css-type-selector.php diff --git a/src/wp-settings.php b/src/wp-settings.php index d4a209893d5cd..9337af05da3ae 100644 --- a/src/wp-settings.php +++ b/src/wp-settings.php @@ -266,15 +266,15 @@ require ABSPATH . WPINC . '/html-api/class-wp-html-stack-event.php'; require ABSPATH . WPINC . '/html-api/class-wp-html-processor-state.php'; require ABSPATH . WPINC . '/html-api/class-wp-html-processor.php'; -require ABSPATH . WPINC . '/html-api/class-wp-css-selector-parser-matcher.php'; -require ABSPATH . WPINC . '/html-api/class-wp-css-attribute-selector.php'; -require ABSPATH . WPINC . '/html-api/class-wp-css-class-selector.php'; -require ABSPATH . WPINC . '/html-api/class-wp-css-id-selector.php'; -require ABSPATH . WPINC . '/html-api/class-wp-css-type-selector.php'; -require ABSPATH . WPINC . '/html-api/class-wp-css-compound-selector.php'; -require ABSPATH . WPINC . '/html-api/class-wp-css-complex-selector.php'; -require ABSPATH . WPINC . '/html-api/class-wp-css-compound-selector-list.php'; -require ABSPATH . WPINC . '/html-api/class-wp-css-complex-selector-list.php'; +require ABSPATH . WPINC . '/html-api/css/class-wp-css-selector-parser-matcher.php'; +require ABSPATH . WPINC . '/html-api/css/class-wp-css-attribute-selector.php'; +require ABSPATH . WPINC . '/html-api/css/class-wp-css-class-selector.php'; +require ABSPATH . WPINC . '/html-api/css/class-wp-css-id-selector.php'; +require ABSPATH . WPINC . '/html-api/css/class-wp-css-type-selector.php'; +require ABSPATH . WPINC . '/html-api/css/class-wp-css-compound-selector.php'; +require ABSPATH . WPINC . '/html-api/css/class-wp-css-complex-selector.php'; +require ABSPATH . WPINC . '/html-api/css/class-wp-css-compound-selector-list.php'; +require ABSPATH . WPINC . '/html-api/css/class-wp-css-complex-selector-list.php'; require ABSPATH . WPINC . '/class-wp-http.php'; require ABSPATH . WPINC . '/class-wp-http-streams.php'; require ABSPATH . WPINC . '/class-wp-http-curl.php'; From 0a87b201785b6a85420e666aaac6b3b7811ba92d Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 16:58:41 +0200 Subject: [PATCH 146/634] CSS selector: Fix off-by-one rejecting [a=b] at end of selector The length guard before the attribute matcher required 4 remaining bytes where the minimum valid tail `=x]` is 3, so a valid exact-match attribute selector with a single-character unquoted value at the end of the selector string (e.g. `[a=b]`) was wrongly rejected as unparseable. Relax the guard from `>=` to `>`. All reads after the guard are bounded: the operator reads touch at most offset+1, and every later read re-checks the length itself. Adds the exact-fit valid case and invalid cases at the same boundary (`[a=]`, `[a~=]`, `[a==b]`, `[a=1]`) to the parse tests, plus an assertNotNull so parse failures report cleanly instead of erroring on a null property read. Found by the CSS selector fuzzer (tools/css-selector-fuzz, Bug 3 in FINDINGS.md). (cherry picked from commit 16d03e2c5fd49d79f413562d88d7e6e36774618a) --- .../html-api/css/class-wp-css-attribute-selector.php | 2 +- tests/phpunit/tests/html-api/wpCssAttributeSelector.php | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/html-api/css/class-wp-css-attribute-selector.php b/src/wp-includes/html-api/css/class-wp-css-attribute-selector.php index a63dfaba66b61..aee6f09a41088 100644 --- a/src/wp-includes/html-api/css/class-wp-css-attribute-selector.php +++ b/src/wp-includes/html-api/css/class-wp-css-attribute-selector.php @@ -275,7 +275,7 @@ public static function parse( string $input, int &$offset ) { } // need to match at least `=x]` at this point - if ( $updated_offset + 3 >= strlen( $input ) ) { + if ( $updated_offset + 3 > strlen( $input ) ) { return null; } diff --git a/tests/phpunit/tests/html-api/wpCssAttributeSelector.php b/tests/phpunit/tests/html-api/wpCssAttributeSelector.php index e574cedd1876b..08880a7311acf 100644 --- a/tests/phpunit/tests/html-api/wpCssAttributeSelector.php +++ b/tests/phpunit/tests/html-api/wpCssAttributeSelector.php @@ -31,6 +31,7 @@ public function test_parse_attribute( if ( null === $expected_name ) { $this->assertNull( $result ); } else { + $this->assertNotNull( $result, "Failed to parse attribute selector: {$input}" ); $this->assertSame( $expected_name, $result->name ); $this->assertSame( $expected_matcher, $result->matcher ); $this->assertSame( $expected_value, $result->value ); @@ -53,6 +54,7 @@ public static function data_attribute_selectors(): array { '[href][href2]' => array( '[href][href2]', 'href', null, null, null, '[href2]' ), '[\n href\t\r]' => array( "[\n href\t\r]", 'href', null, null, null, '' ), '[href=foo]' => array( '[href=foo]', 'href', WP_CSS_Attribute_Selector::MATCH_EXACT, 'foo', null, '' ), + '[a=b]' => array( '[a=b]', 'a', WP_CSS_Attribute_Selector::MATCH_EXACT, 'b', null, '' ), '[href \n = bar ]' => array( "[href \n = bar ]", 'href', WP_CSS_Attribute_Selector::MATCH_EXACT, 'bar', null, '' ), '[href \n ^= baz ]' => array( "[href \n ^= baz ]", 'href', WP_CSS_Attribute_Selector::MATCH_PREFIXED_BY, 'baz', null, '' ), @@ -79,6 +81,10 @@ public static function data_attribute_selectors(): array { 'Invalid: [*| att]' => array( '[*| att]' ), 'Invalid: [att * =]' => array( '[att * =]' ), 'Invalid: [att+=val]' => array( '[att+=val]' ), + 'Invalid: [a=]' => array( '[a=]' ), + 'Invalid: [a~=]' => array( '[a~=]' ), + 'Invalid: [a==b]' => array( '[a==b]' ), + 'Invalid: [a=1]' => array( '[a=1]' ), 'Invalid: [att=val ' => array( '[att=val ' ), 'Invalid: [att i]' => array( '[att i]' ), 'Invalid: [att s]' => array( '[att s]' ), From 989e18da8a9ed5bdd829e66f41ec63f086bf0aca Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 17:11:19 +0200 Subject: [PATCH 147/634] CSS selector: Empty-operand substring attribute matchers match nothing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per Selectors level 4, the substring attribute matchers with an empty value — [x^=""], [x$=""], [x*=""] — represent nothing and must never match. The matcher instead matched any element carrying the attribute (prefix and contains) or an element whose attribute value was exactly empty (suffix). Add an early return for the empty operand on those three matchers, before the case modifier and boolean-attribute normalization so [x^="" i] and valueless attributes are covered too. [x=""], [x|=""], and [x~=""] are unaffected and remain spec-correct: exact and hyphen matchers may match an empty value, and the one-of matcher already matched nothing because a whitespace-delimited list never yields an empty item. Tests pin all of these, including |= against a hyphen-prefixed value. https://www.w3.org/TR/selectors-4/#attribute-substrings Found by the CSS selector fuzzer (tools/css-selector-fuzz, Bug 2 in FINDINGS.md). (cherry picked from commit 0cefeb2fc8fd6b255498c6dc0438b7334698b975) --- .../css/class-wp-css-attribute-selector.php | 18 ++++++++++++++++++ .../tests/html-api/wpHtmlProcessor-select.php | 10 ++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/wp-includes/html-api/css/class-wp-css-attribute-selector.php b/src/wp-includes/html-api/css/class-wp-css-attribute-selector.php index aee6f09a41088..8b631966bb579 100644 --- a/src/wp-includes/html-api/css/class-wp-css-attribute-selector.php +++ b/src/wp-includes/html-api/css/class-wp-css-attribute-selector.php @@ -163,6 +163,24 @@ public function matches( WP_HTML_Tag_Processor $processor ): bool { return true; } + /* + * The substring matchers match nothing when the value is empty: + * + * > If "val" is the empty string then the selector does not represent anything. + * + * https://www.w3.org/TR/selectors-4/#attribute-substrings + */ + if ( + '' === $this->value && + ( + self::MATCH_PREFIXED_BY === $this->matcher || + self::MATCH_SUFFIXED_BY === $this->matcher || + self::MATCH_CONTAINS === $this->matcher + ) + ) { + return false; + } + if ( true === $attr_value ) { $attr_value = ''; } diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php index 003e65e69ebce..0fb5788efce7f 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php @@ -53,6 +53,16 @@ public static function data_selectors(): array { 'any child matches all children' => array( '

', 'section > *', 2 ), 'multiple complex selectors' => array( '

', 'section > div p > i', 1 ), + + // Per Selectors-4, the substring matchers ^= $= *= match nothing when the value + // is empty. ~= also matches nothing: an empty string is never a list item. + 'empty value ^= matches nothing' => array( '', '[x^=""]', 0 ), + 'empty value $= matches nothing' => array( '', '[x$=""]', 0 ), + 'empty value *= matches nothing' => array( '', '[x*=""]', 0 ), + 'empty value ~= matches nothing' => array( '', '[x~=""]', 0 ), + 'empty value ^= i matches nothing' => array( '', '[x^="" i]', 0 ), + 'empty value = matches empty' => array( '', '[x=""]', 1 ), + 'empty value |= matches empty or hyphen-prefixed' => array( '', '[x|=""]', 2 ), ); } From 5ac71eeb3fc0ce524d6ed481d7840191397337d1 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 11 Jun 2026 10:43:31 +0200 Subject: [PATCH 148/634] CSS selector: Align test data provider arrows per WPCS phpcbf reports 40 WordPress.Arrays.MultipleStatementAlignment warnings in this file's data providers, and the coding-standards workflow runs phpcs over the test suite without -n, so warnings fail CI. Pure whitespace; no test changes. (cherry picked from commit 3db43eaef2107421f156e6ac2a29478fe6e4b2fd) --- .../html-api/wpCssSelectorParserMatcher.php | 84 +++++++++---------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php b/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php index 4f3c1f73390fe..37f26ec8f3b92 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php +++ b/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php @@ -54,38 +54,38 @@ public static function test_is_ident_start_codepoint( string $input, int $offset */ public static function data_idents(): array { return array( - 'trailing #' => array( '_-foo123#xyz', '_-foo123', '#xyz' ), - 'trailing .' => array( '😍foo123.xyz', '😍foo123', '.xyz' ), - 'trailing " "' => array( '😍foo123 more', '😍foo123', ' more' ), - 'escaped ASCII character' => array( '\\xyz', 'xyz', '' ), - 'escape after multibyte character' => array( 'Ü\\sup', 'Üsup', '' ), - 'escape after multibyte characters' => array( 'ÜÜ\\sup', 'ÜÜsup', '' ), + 'trailing #' => array( '_-foo123#xyz', '_-foo123', '#xyz' ), + 'trailing .' => array( '😍foo123.xyz', '😍foo123', '.xyz' ), + 'trailing " "' => array( '😍foo123 more', '😍foo123', ' more' ), + 'escaped ASCII character' => array( '\\xyz', 'xyz', '' ), + 'escape after multibyte character' => array( 'Ü\\sup', 'Üsup', '' ), + 'escape after multibyte characters' => array( 'ÜÜ\\sup', 'ÜÜsup', '' ), 'hex escape after multibyte character' => array( 'Ü\\31 23', 'Ü123', '' ), - 'escaped space' => array( '\\ x', ' x', '' ), - 'escaped emoji' => array( '\\😍', '😍', '' ), - 'hex unicode codepoint' => array( '\\1f0a1', '🂡', '' ), - 'HEX UNICODE CODEPOINT' => array( '\\1D4B2', '𝒲', '' ), - - 'hex tab-suffixed 1' => array( "\\31\t23", '123', '' ), - 'hex newline-suffixed 1' => array( "\\31\n23", '123', '' ), - 'hex space-suffixed 1' => array( "\\31 23", '123', '' ), - 'hex tab' => array( '\\9', "\t", '' ), - 'hex a' => array( '\\61 bc', 'abc', '' ), - 'hex a max escape length' => array( '\\000061bc', 'abc', '' ), - - 'out of range replacement min' => array( '\\110000 ', "\u{fffd}", '' ), - 'out of range replacement max' => array( '\\ffffff ', "\u{fffd}", '' ), - 'leading surrogate min replacement' => array( '\\d800 ', "\u{fffd}", '' ), - 'leading surrogate max replacement' => array( '\\dbff ', "\u{fffd}", '' ), - 'trailing surrogate min replacement' => array( '\\dc00 ', "\u{fffd}", '' ), - 'trailing surrogate max replacement' => array( '\\dfff ', "\u{fffd}", '' ), - 'can start with -ident' => array( '-ident', '-ident', '' ), - 'can start with --anything' => array( '--anything', '--anything', '' ), - 'can start with ---anything' => array( '--_anything', '--_anything', '' ), - 'can start with --1anything' => array( '--1anything', '--1anything', '' ), - 'can start with -\31 23' => array( '-\31 23', '-123', '' ), - 'can start with --\31 23' => array( '--\31 23', '--123', '' ), - 'ident ends before ]' => array( 'ident]', 'ident', ']' ), + 'escaped space' => array( '\\ x', ' x', '' ), + 'escaped emoji' => array( '\\😍', '😍', '' ), + 'hex unicode codepoint' => array( '\\1f0a1', '🂡', '' ), + 'HEX UNICODE CODEPOINT' => array( '\\1D4B2', '𝒲', '' ), + + 'hex tab-suffixed 1' => array( "\\31\t23", '123', '' ), + 'hex newline-suffixed 1' => array( "\\31\n23", '123', '' ), + 'hex space-suffixed 1' => array( "\\31 23", '123', '' ), + 'hex tab' => array( '\\9', "\t", '' ), + 'hex a' => array( '\\61 bc', 'abc', '' ), + 'hex a max escape length' => array( '\\000061bc', 'abc', '' ), + + 'out of range replacement min' => array( '\\110000 ', "\u{fffd}", '' ), + 'out of range replacement max' => array( '\\ffffff ', "\u{fffd}", '' ), + 'leading surrogate min replacement' => array( '\\d800 ', "\u{fffd}", '' ), + 'leading surrogate max replacement' => array( '\\dbff ', "\u{fffd}", '' ), + 'trailing surrogate min replacement' => array( '\\dc00 ', "\u{fffd}", '' ), + 'trailing surrogate max replacement' => array( '\\dfff ', "\u{fffd}", '' ), + 'can start with -ident' => array( '-ident', '-ident', '' ), + 'can start with --anything' => array( '--anything', '--anything', '' ), + 'can start with ---anything' => array( '--_anything', '--_anything', '' ), + 'can start with --1anything' => array( '--1anything', '--1anything', '' ), + 'can start with -\31 23' => array( '-\31 23', '-123', '' ), + 'can start with --\31 23' => array( '--\31 23', '--123', '' ), + 'ident ends before ]' => array( 'ident]', 'ident', ']' ), /* * > EOF @@ -93,19 +93,19 @@ public static function data_idents(): array { * * https://www.w3.org/TR/css-syntax-3/#consume-escaped-code-point */ - 'escape at EOF' => array( 'foo\\', "foo\u{fffd}", '' ), - 'lone escape at EOF' => array( '\\', "\u{fffd}", '' ), - 'hyphen then escape at EOF' => array( '-\\', "-\u{fffd}", '' ), + 'escape at EOF' => array( 'foo\\', "foo\u{fffd}", '' ), + 'lone escape at EOF' => array( '\\', "\u{fffd}", '' ), + 'hyphen then escape at EOF' => array( '-\\', "-\u{fffd}", '' ), // Invalid - 'Invalid: (empty string)' => array( '' ), - 'Invalid: bad start >' => array( '>ident' ), - 'Invalid: bad start [' => array( '[ident' ), - 'Invalid: bad start #' => array( '#ident' ), - 'Invalid: bad start " "' => array( ' ident' ), - 'Invalid: bad start 1' => array( '1ident' ), - 'Invalid: bad start -1' => array( '-1ident' ), - 'Invalid: bad start -' => array( '-' ), + 'Invalid: (empty string)' => array( '' ), + 'Invalid: bad start >' => array( '>ident' ), + 'Invalid: bad start [' => array( '[ident' ), + 'Invalid: bad start #' => array( '#ident' ), + 'Invalid: bad start " "' => array( ' ident' ), + 'Invalid: bad start 1' => array( '1ident' ), + 'Invalid: bad start -1' => array( '-1ident' ), + 'Invalid: bad start -' => array( '-' ), ); } From aed6cfb4aaddb874c26c30fdf53d568a98d8c17c Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 17:26:10 +0200 Subject: [PATCH 149/634] CSS selector: Decode identity escapes at the byte offset, not char index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit consume_escaped_codepoint() read the escaped codepoint for non-hex (identity) escapes with mb_substr( $input, $offset, 1 ), but $offset is a byte offset while mb_substr()'s second argument is a character index. Any multibyte content earlier in the selector string shifts the read one character right per continuation byte, decoding the wrong codepoint: 'Ü\sup' parsed as ident 'Üuup', and the corruption threads across an entire selector list ('#ÜÜÜ,\sup #x' parsed the second selector's type as ' up'). Depending on the mis-decoded codepoint this also caused spurious parse failures of valid selectors. Hex escapes were already byte-correct and are unaffected. Read the codepoint from the byte offset instead. ASCII-only inputs are byte-for-byte unchanged, and the returned codepoint's byte length keeps the offset advancing exactly past it. Adds parse_ident and parse_string cases pinning identity escapes after multibyte characters, plus a hex-escape control. Found by the CSS selector fuzzer (tools/css-selector-fuzz, Bug 1 in FINDINGS.md). (cherry picked from commit 7419a9fef6c6c23d14b8ae9c04ae1c91834824b0) --- .../html-api/css/class-wp-css-selector-parser-matcher.php | 3 ++- tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/html-api/css/class-wp-css-selector-parser-matcher.php b/src/wp-includes/html-api/css/class-wp-css-selector-parser-matcher.php index cac314e8b6c27..dc8aa8d018446 100644 --- a/src/wp-includes/html-api/css/class-wp-css-selector-parser-matcher.php +++ b/src/wp-includes/html-api/css/class-wp-css-selector-parser-matcher.php @@ -250,7 +250,8 @@ final protected static function consume_escaped_codepoint( $input, &$offset ): s return $codepoint_char; } - $codepoint_char = mb_substr( $input, $offset, 1, 'UTF-8' ); + // $offset is a byte offset; mb_substr() expects a character offset. + $codepoint_char = mb_substr( substr( $input, $offset ), 0, 1, 'UTF-8' ); $offset += strlen( $codepoint_char ); return $codepoint_char; } diff --git a/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php b/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php index 29372172da2b1..ffa02b17b7f0d 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php +++ b/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php @@ -58,6 +58,9 @@ public static function data_idents(): array { 'trailing .' => array( '😍foo123.xyz', '😍foo123', '.xyz' ), 'trailing " "' => array( '😍foo123 more', '😍foo123', ' more' ), 'escaped ASCII character' => array( '\\xyz', 'xyz', '' ), + 'escape after multibyte character' => array( 'Ü\\sup', 'Üsup', '' ), + 'escape after multibyte characters' => array( 'ÜÜ\\sup', 'ÜÜsup', '' ), + 'hex escape after multibyte character' => array( 'Ü\\31 23', 'Ü123', '' ), 'escaped space' => array( '\\ x', ' x', '' ), 'escaped emoji' => array( '\\😍', '😍', '' ), 'hex unicode codepoint' => array( '\\1f0a1', '🂡', '' ), @@ -158,6 +161,7 @@ public static function data_strings(): array { "'foo\\nbar'" => array( "'foo\\\nbar'", 'foobar', '' ), "'foo\\31 23'" => array( "'foo\\31 23'", 'foo123', '' ), + "'Ü\\sup'" => array( "'Ü\\sup'", 'Üsup', '' ), "'foo\\31\\n23'" => array( "'foo\\31\n23'", 'foo123', '' ), "'foo\\31\\t23'" => array( "'foo\\31\t23'", 'foo123', '' ), "'foo\\00003123'" => array( "'foo\\00003123'", 'foo123', '' ), From e0356cad899bd09610827c125d4815a9dc02697b Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 22:38:35 +0200 Subject: [PATCH 150/634] CSS selector: Backslash at end of input is a valid escape (U+FFFD) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per CSS Syntax 3, a backslash followed by EOF is a valid escape in ident context -- §4.3.8 rejects only a newline as the second code point, and EOF is not a newline -- and consuming it returns U+FFFD REPLACEMENT CHARACTER (§4.3.7). WP rejected the whole selector: next_two_are_valid_escape() required a code point after the backslash, so '.foo\' parsed to null instead of the class "foo\u{FFFD}". Fix: consume_escaped_codepoint() returns U+FFFD at EOF without advancing, and next_two_are_valid_escape() accepts a backslash as the final byte. String context is unaffected: parse_string() guards EOF itself before consuming an escape, preserving the §4.3.5 'do nothing' EOF rule ('foo\ still parses to foo). Review of the fix surfaced a second bug in the same family: normalize_selector_input() trimmed *trailing* whitespace before tokenizing, so '.foo\ ' (escaped space: the valid, unmatchable class 'foo ') and ".foo\\n" (invalid escape: must be rejected) both collapsed to '.foo\' and matched elements with class "foo\u{FFFD}" -- a wrong-match-set bug, where before the EOF-escape fix the collapse was a harmless fail-safe rejection. Now only leading whitespace is stripped; the grammar already consumes insignificant trailing whitespace via parse_whitespace() in both selector-list parsers. Verified against lexbor: '.foo\' matches class "foo\u{FFFD}", lone '\' parses as type U+FFFD and matches nothing, '.foo\ ' is valid and matches nothing, and the LF/CR/FF escape variants are rejected -- exact agreement on all probes. (NEXT-STEPS.md 'candidate finding 4', now confirmed and closed.) (cherry picked from commit 203858bbd470a2b7a8eeaf7f7579d85eeced3264) --- .../class-wp-css-selector-parser-matcher.php | 29 ++++++++++++++++--- .../tests/html-api/wpCssClassSelector.php | 1 + .../html-api/wpCssCompoundSelectorList.php | 23 +++++++++++++++ .../tests/html-api/wpCssIdSelector.php | 1 + .../html-api/wpCssSelectorParserMatcher.php | 10 +++++++ .../tests/html-api/wpCssTypeSelector.php | 1 + .../html-api/wpHtmlTagProcessor-select.php | 20 +++++++++++++ 7 files changed, 81 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/html-api/css/class-wp-css-selector-parser-matcher.php b/src/wp-includes/html-api/css/class-wp-css-selector-parser-matcher.php index dc8aa8d018446..23d14d01c673b 100644 --- a/src/wp-includes/html-api/css/class-wp-css-selector-parser-matcher.php +++ b/src/wp-includes/html-api/css/class-wp-css-selector-parser-matcher.php @@ -209,6 +209,14 @@ final protected static function parse_string( string $input, int &$offset ): ?st * @return string */ final protected static function consume_escaped_codepoint( $input, &$offset ): string { + /* + * > EOF + * > This is a parse error. Return U+FFFD REPLACEMENT CHARACTER (�). + */ + if ( $offset >= strlen( $input ) ) { + return "\u{FFFD}"; + } + $hex_length = strspn( $input, '0123456789abcdefABCDEF', $offset, 6 ); if ( $hex_length > 0 ) { /** @@ -339,10 +347,17 @@ final protected static function parse_ident( string $input, int &$offset ): ?str * @return bool True if the next two codepoints are a valid escape, otherwise false. */ final protected static function next_two_are_valid_escape( string $input, int $offset ): bool { - if ( $offset + 1 >= strlen( $input ) ) { + if ( $offset >= strlen( $input ) ) { return false; } - return '\\' === $input[ $offset ] && "\n" !== $input[ $offset + 1 ]; + + /* + * The second code point may be EOF. EOF is not a newline, so a + * backslash at the end of input is a valid escape; consuming it + * produces U+FFFD REPLACEMENT CHARACTER. + */ + return '\\' === $input[ $offset ] && + ( $offset + 1 >= strlen( $input ) || "\n" !== $input[ $offset + 1 ] ); } /** @@ -481,9 +496,15 @@ final protected static function normalize_selector_input( string $input ): strin * > A selector string is a list of one or more complex selectors ([SELECTORS4], section 3.1) that may be surrounded by whitespace… * * This list includes \f. - * A later step would normalize it to a known whitespace character, but it can be trimmed here as well. + * + * Only leading whitespace is removed here. Trailing whitespace may be + * significant: a backslash may escape a final whitespace code point + * into an ident (`.foo\ ` is the class `foo `), and a backslash + * before a final newline is an invalid escape, while a backslash at + * the end of input is a valid escape that decodes to U+FFFD. The + * selector grammar consumes insignificant trailing whitespace itself. */ - $input = trim( $input, " \t\r\n\f" ); + $input = ltrim( $input, " \t\r\n\f" ); /* * > The input stream consists of the filtered code points pushed into it as the input byte stream is decoded. diff --git a/tests/phpunit/tests/html-api/wpCssClassSelector.php b/tests/phpunit/tests/html-api/wpCssClassSelector.php index 9646d05da23d5..3328b047fa143 100644 --- a/tests/phpunit/tests/html-api/wpCssClassSelector.php +++ b/tests/phpunit/tests/html-api/wpCssClassSelector.php @@ -40,6 +40,7 @@ public static function data_class_selectors(): array { 'valid .foo.bar' => array( '.foo.bar', 'foo', '.bar' ), 'escaped .\31 23' => array( '.\\31 23', '123', '' ), 'with descendant .\31 23 div' => array( '.\\31 23 div', '123', ' div' ), + 'escape at EOF .foo\\' => array( '.foo\\', "foo\u{fffd}", '' ), 'not class foo' => array( 'foo' ), 'not class #bar' => array( '#bar' ), diff --git a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php index 8f1d3dfb88a45..c71aa09596d8f 100644 --- a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php +++ b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php @@ -40,6 +40,29 @@ public function test_parse_invalid_selector_list2() { $this->assertNull( $result ); } + /** + * An escaped whitespace code point at the end of input belongs to the + * ident and must survive input normalization: `.foo\ ` is the valid + * class `foo ` (with a space), not a backslash at the end of input. + * + * @ticket 62653 + */ + public function test_parse_escaped_whitespace_at_end_of_input() { + $result = WP_CSS_Compound_Selector_List::from_selectors( '.foo\\ ' ); + $this->assertNotNull( $result ); + } + + /** + * A backslash before a newline is not a valid escape; at the end of + * input it must not be mistaken for trimmable trailing whitespace. + * + * @ticket 62653 + */ + public function test_parse_escape_before_newline_at_end_of_input_is_invalid() { + $result = WP_CSS_Compound_Selector_List::from_selectors( ".foo\\\n" ); + $this->assertNull( $result ); + } + /** * @ticket 62653 */ diff --git a/tests/phpunit/tests/html-api/wpCssIdSelector.php b/tests/phpunit/tests/html-api/wpCssIdSelector.php index 6dc2e5461ea03..03694fa4456e5 100644 --- a/tests/phpunit/tests/html-api/wpCssIdSelector.php +++ b/tests/phpunit/tests/html-api/wpCssIdSelector.php @@ -40,6 +40,7 @@ public static function data_id_selectors(): array { 'valid #foo#bar' => array( '#foo#bar', 'foo', '#bar' ), 'escaped #\31 23' => array( '#\\31 23', '123', '' ), 'with descendant #\31 23 div' => array( '#\\31 23 div', '123', ' div' ), + 'escape at EOF #foo\\' => array( '#foo\\', "foo\u{fffd}", '' ), // Invalid 'not ID foo' => array( 'foo' ), diff --git a/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php b/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php index ffa02b17b7f0d..4f3c1f73390fe 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php +++ b/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php @@ -87,6 +87,16 @@ public static function data_idents(): array { 'can start with --\31 23' => array( '--\31 23', '--123', '' ), 'ident ends before ]' => array( 'ident]', 'ident', ']' ), + /* + * > EOF + * > This is a parse error. Return U+FFFD REPLACEMENT CHARACTER (�). + * + * https://www.w3.org/TR/css-syntax-3/#consume-escaped-code-point + */ + 'escape at EOF' => array( 'foo\\', "foo\u{fffd}", '' ), + 'lone escape at EOF' => array( '\\', "\u{fffd}", '' ), + 'hyphen then escape at EOF' => array( '-\\', "-\u{fffd}", '' ), + // Invalid 'Invalid: (empty string)' => array( '' ), 'Invalid: bad start >' => array( '>ident' ), diff --git a/tests/phpunit/tests/html-api/wpCssTypeSelector.php b/tests/phpunit/tests/html-api/wpCssTypeSelector.php index 23d5f5517453a..94ae49bff474a 100644 --- a/tests/phpunit/tests/html-api/wpCssTypeSelector.php +++ b/tests/phpunit/tests/html-api/wpCssTypeSelector.php @@ -40,6 +40,7 @@ public static function data_type_selectors(): array { 'a' => array( 'a', 'a', '' ), 'div.class' => array( 'div.class', 'div', '.class' ), 'custom-type#id' => array( 'custom-type#id', 'custom-type', '#id' ), + 'escape at EOF foo\\' => array( 'foo\\', "foo\u{fffd}", '' ), // Invalid 'Invalid: (empty string)' => array( '' ), diff --git a/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php index 1d09c61b4760d..a2cc231150b09 100644 --- a/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php +++ b/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php @@ -75,6 +75,16 @@ public static function data_selectors(): array { 'attribute contains insensitive' => array( '

', '[att*="x"i]', 1 ), 'attribute contains sensitive mod' => array( '

', '[att*="x"s]', 1 ), + /* + * An escaped trailing whitespace code point is part of the ident, + * not trailing whitespace: `.foo\ ` is the class `foo ` (with a + * space). Class attribute values are whitespace-separated token + * lists, so such a class can never match. It must NOT be confused + * with a backslash at the end of input, which decodes to U+FFFD. + */ + 'escaped space at end' => array( "

", '.foo\\ ', 0 ), + 'escaped tab at end' => array( "
", ".foo\\\t", 0 ), + 'list' => array( '

', 'a, p, .class, #id, [att]', 2 ), 'compound' => array( '

', 'custom-el[att="bar"][ fruit ~= "banana" i]', 1 ), ); @@ -102,6 +112,16 @@ public static function data_invalid_selectors(): array { 'complex descendant' => array( 'div *' ), 'complex child' => array( 'div > *' ), 'invalid selector' => array( '[invalid!selector]' ), + + /* + * A backslash before a newline at the end of input is not a valid + * escape and is not trailing whitespace: the selector is invalid. + * The CR and FF variants are normalized to a newline before + * tokenizing. + */ + 'escape before newline at end' => array( ".foo\\\n" ), + 'escape before CR at end' => array( ".foo\\\r" ), + 'escape before FF at end' => array( ".foo\\\f" ), ); } } From 481e5a4e857d44b13961aa35984b3fc926fb95a4 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 23:02:16 +0200 Subject: [PATCH 151/634] CSS selector: End of input auto-closes an open attribute selector MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per CSS Syntax 3 §5.4.8/§4.3.5, tokenization auto-closes unterminated simple blocks and unterminated strings at EOF (a parse error, but the block/string is returned), and the selector grammar then applies to the block contents. So '[att=val' is the same selector as '[att=val]', and '[att="a b' carries the string value 'a b'. WP rejected all of these with null. The attribute parser now treats the end of input like a closing ']' at the two positions where the grammar is complete (after the name, and after the value/modifier), and the early length guards that required room for a closing bracket are relaxed accordingly. Truncation inside the grammar itself is still invalid: '[', '[a=', '[a~', '[a=b x', and a comma inside the open block ('[a=b, div') all stay null. Escape interplay (verified per spec and in Chromium): '[a=b\' carries the value "b\u{FFFD}" (escape at EOF in ident context), while '[a="b\' carries 'b' (backslash-then-EOF in a string 'does nothing'). '[a\]' parses as a presence selector for the attribute 'a]' (the escaped ']' joins the ident and EOF closes the block). Chromium agrees with every accepted and rejected form above. lexbor rejects all EOF-truncated forms (it does not implement the auto-close rule) and diverges from browsers and the spec here; the fuzzer's lexbor differential is unaffected because it compares canonical re-renders, which always include the closing bracket. (cherry picked from commit 5eea359bd5da8d0f8bc01a510237eec4177a5c1e) --- .../css/class-wp-css-attribute-selector.php | 64 ++++++++++--------- .../tests/html-api/wpCssAttributeSelector.php | 33 +++++++++- .../html-api/wpHtmlTagProcessor-select.php | 18 ++++++ 3 files changed, 83 insertions(+), 32 deletions(-) diff --git a/src/wp-includes/html-api/css/class-wp-css-attribute-selector.php b/src/wp-includes/html-api/css/class-wp-css-attribute-selector.php index 8b631966bb579..8fd3b5b3cbd35 100644 --- a/src/wp-includes/html-api/css/class-wp-css-attribute-selector.php +++ b/src/wp-includes/html-api/css/class-wp-css-attribute-selector.php @@ -258,14 +258,21 @@ private function whitespace_delimited_list( string $input ): Generator { * * To create an instance of this class, use the {@see WP_CSS_Compound_Selector_List::from_selectors()} method. * + * The end of input acts like a closing `]`: tokenization auto-closes + * unterminated simple blocks (and unterminated strings) at EOF, so + * `[att=val` is the same selector as `[att=val]`. Truncation inside the + * selector grammar itself (e.g. `[` or `[att=`) is still invalid. + * + * https://www.w3.org/TR/css-syntax-3/#consume-simple-block + * * @param string $input The selector string. * @param int $offset The offset into the string. The offset is passed by reference and * will be updated if the parse is successful. * @return static|null The selector instance, or null if the parse was unsuccessful. */ public static function parse( string $input, int &$offset ) { - // Need at least 3 bytes [x] - if ( $offset + 2 >= strlen( $input ) ) { + // Need at least 2 bytes `[x`; the closing `]` may be supplied by the end of input. + if ( $offset + 1 >= strlen( $input ) ) { return null; } @@ -283,8 +290,10 @@ public static function parse( string $input, int &$offset ) { } self::parse_whitespace( $input, $updated_offset ); + // The end of input auto-closes the attribute selector. if ( $updated_offset >= strlen( $input ) ) { - return null; + $offset = $updated_offset; + return new WP_CSS_Attribute_Selector( $attr_name ); } if ( ']' === $input[ $updated_offset ] ) { @@ -292,15 +301,10 @@ public static function parse( string $input, int &$offset ) { return new WP_CSS_Attribute_Selector( $attr_name ); } - // need to match at least `=x]` at this point - if ( $updated_offset + 3 > strlen( $input ) ) { - return null; - } - if ( '=' === $input[ $updated_offset ] ) { ++$updated_offset; $attr_matcher = WP_CSS_Attribute_Selector::MATCH_EXACT; - } elseif ( '=' === $input[ $updated_offset + 1 ] ) { + } elseif ( $updated_offset + 1 < strlen( $input ) && '=' === $input[ $updated_offset + 1 ] ) { switch ( $input[ $updated_offset ] ) { case '~': $attr_matcher = WP_CSS_Attribute_Selector::MATCH_ONE_OF_EXACT; @@ -339,32 +343,34 @@ public static function parse( string $input, int &$offset ) { } self::parse_whitespace( $input, $updated_offset ); - if ( $updated_offset >= strlen( $input ) ) { - return null; - } $attr_modifier = null; - switch ( $input[ $updated_offset ] ) { - case 'i': - case 'I': - $attr_modifier = WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE; - ++$updated_offset; - break; - - case 's': - case 'S': - $attr_modifier = WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE; - ++$updated_offset; - break; - } + if ( $updated_offset < strlen( $input ) ) { + switch ( $input[ $updated_offset ] ) { + case 'i': + case 'I': + $attr_modifier = WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE; + ++$updated_offset; + break; + + case 's': + case 'S': + $attr_modifier = WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE; + ++$updated_offset; + break; + } - if ( null !== $attr_modifier ) { - self::parse_whitespace( $input, $updated_offset ); - if ( $updated_offset >= strlen( $input ) ) { - return null; + if ( null !== $attr_modifier ) { + self::parse_whitespace( $input, $updated_offset ); } } + // The end of input auto-closes the attribute selector. + if ( $updated_offset >= strlen( $input ) ) { + $offset = $updated_offset; + return new self( $attr_name, $attr_matcher, $attr_val, $attr_modifier ); + } + if ( ']' === $input[ $updated_offset ] ) { $offset = $updated_offset + 1; return new self( $attr_name, $attr_matcher, $attr_val, $attr_modifier ); diff --git a/tests/phpunit/tests/html-api/wpCssAttributeSelector.php b/tests/phpunit/tests/html-api/wpCssAttributeSelector.php index 08880a7311acf..99051f2cc971c 100644 --- a/tests/phpunit/tests/html-api/wpCssAttributeSelector.php +++ b/tests/phpunit/tests/html-api/wpCssAttributeSelector.php @@ -70,10 +70,36 @@ public static function data_attribute_selectors(): array { '[escape-nl="foo\\nbar"]' => array( "[escape-nl='foo\\\nbar']", 'escape-nl', WP_CSS_Attribute_Selector::MATCH_EXACT, 'foobar', null, '' ), '[escape-seq="\\31 23"]' => array( "[escape-seq='\\31 23']", 'escape-seq', WP_CSS_Attribute_Selector::MATCH_EXACT, '123', null, '' ), + /* + * The end of input closes an open attribute selector: tokenization + * auto-closes unterminated simple blocks (and strings) at EOF. + * + * https://www.w3.org/TR/css-syntax-3/#consume-simple-block + */ + 'EOF [foo' => array( '[foo', 'foo', null, null, null, '' ), + 'EOF [ \n foo' => array( "[ \n foo", 'foo', null, null, null, '' ), + 'EOF [foo ' => array( '[foo ', 'foo', null, null, null, '' ), + 'EOF [a=b' => array( '[a=b', 'a', WP_CSS_Attribute_Selector::MATCH_EXACT, 'b', null, '' ), + 'EOF [att=val ' => array( '[att=val ', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'val', null, '' ), + 'EOF [a="b' => array( '[a="b', 'a', WP_CSS_Attribute_Selector::MATCH_EXACT, 'b', null, '' ), + "EOF [a='b" => array( "[a='b", 'a', WP_CSS_Attribute_Selector::MATCH_EXACT, 'b', null, '' ), + 'EOF [a="b\\' => array( '[a="b\\', 'a', WP_CSS_Attribute_Selector::MATCH_EXACT, 'b', null, '' ), + 'EOF [a=b\\' => array( '[a=b\\', 'a', WP_CSS_Attribute_Selector::MATCH_EXACT, "b\u{FFFD}", null, '' ), + 'EOF [a^=b' => array( '[a^=b', 'a', WP_CSS_Attribute_Selector::MATCH_PREFIXED_BY, 'b', null, '' ), + 'EOF [att=val i' => array( '[att=val i', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'val', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), + 'EOF [att=val i ' => array( '[att=val i ', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'val', WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, '' ), + 'EOF [att="val"s' => array( '[att="val"s', 'att', WP_CSS_Attribute_Selector::MATCH_EXACT, 'val', WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, '' ), + // Invalid 'Invalid: (empty string)' => array( '' ), 'Invalid: foo' => array( 'foo' ), - 'Invalid: [foo' => array( '[foo' ), + 'Invalid: [' => array( '[' ), + 'Invalid: [ ' => array( '[ ' ), + 'Invalid: [a=' => array( '[a=' ), + 'Invalid: [a= ' => array( '[a= ' ), + 'Invalid: [a~' => array( '[a~' ), + 'Invalid: [a=b x' => array( '[a=b x' ), + 'Invalid: [a i' => array( '[a i' ), 'Invalid: [#foo]' => array( '[#foo]' ), 'Invalid: [*|*]' => array( '[*|*]' ), 'Invalid: [ns|*]' => array( '[ns|*]' ), @@ -85,12 +111,13 @@ public static function data_attribute_selectors(): array { 'Invalid: [a~=]' => array( '[a~=]' ), 'Invalid: [a==b]' => array( '[a==b]' ), 'Invalid: [a=1]' => array( '[a=1]' ), - 'Invalid: [att=val ' => array( '[att=val ' ), + 'Invalid: [a=1' => array( '[a=1' ), 'Invalid: [att i]' => array( '[att i]' ), 'Invalid: [att s]' => array( '[att s]' ), "Invalid: [att='val\\n']" => array( "[att='val\n']" ), - 'Invalid: [att=val i ' => array( '[att=val i ' ), + "Invalid: [att='val\\n" => array( "[att='val\n" ), 'Invalid: [att="val"ix' => array( '[att="val"ix' ), + 'Invalid: [att="val"ix ' => array( '[att="val"ix ' ), ); } } diff --git a/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php index a2cc231150b09..d09a6e350256d 100644 --- a/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php +++ b/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php @@ -85,6 +85,16 @@ public static function data_selectors(): array { 'escaped space at end' => array( "
", '.foo\\ ', 0 ), 'escaped tab at end' => array( "
", ".foo\\\t", 0 ), + /* + * The end of input closes an open attribute selector ( and an + * unterminated string ): tokenization auto-closes simple blocks + * at EOF. + */ + 'EOF-truncated attribute presence' => array( '
', '[att', 1 ), + 'EOF-truncated attribute value' => array( '
', '[att=val', 1 ), + 'EOF-truncated quoted value' => array( '
', '[att="a b', 1 ), + 'EOF-truncated with modifier' => array( '
', '[att=val i', 1 ), + 'list' => array( '

', 'a, p, .class, #id, [att]', 2 ), 'compound' => array( '

', 'custom-el[att="bar"][ fruit ~= "banana" i]', 1 ), ); @@ -122,6 +132,14 @@ public static function data_invalid_selectors(): array { 'escape before newline at end' => array( ".foo\\\n" ), 'escape before CR at end' => array( ".foo\\\r" ), 'escape before FF at end' => array( ".foo\\\f" ), + + /* + * EOF auto-closes an open attribute selector block, but + * grammar-level truncation is still invalid. + */ + 'truncated matcher without value' => array( '[a=' ), + 'truncated half matcher' => array( '[a~' ), + 'lone open bracket' => array( '[' ), ); } } From 8bf3e522df5e8879525d5adf1d6ff4ef686b2990 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 23:54:25 +0200 Subject: [PATCH 152/634] CSS selector: Implement HTML's case-insensitive attribute value list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HTML defines 46 attributes (type, rel, lang, dir, media, hreflang, http-equiv, ...) whose values must match ASCII case-insensitively in attribute selectors on an HTML element when the selector carries no i/s modifier: https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors WP honored only the explicit modifiers, so [type=TEXT] silently failed to match — a wrong match set rather than a refusal, invisible to callers. The matcher now folds case when all three hold: no modifier on the selector, the element is in the html namespace (per the processor's get_namespace()), and the lowercased attribute name is in the list. An explicit s modifier still forces case-sensitive matching, per Selectors 4 §6.3: 'the UA must match the value case-sensitively ... regardless of document language rules.' All six matchers and |='s hyphen check honor the rule via the existing case-insensitive comparison branches. Namespace scoping follows the spec's 'on an HTML element' wording: SVG/MathML elements keep case-sensitive matching, while elements at HTML integration points (e.g. inside ) fold, since they are html-namespace. Verified in Chromium, which agrees on the integration point but also folds plain SVG-namespace elements, diverging from the spec's scoping; WP follows the spec. The standalone Tag Processor tracks no namespaces and folds everywhere — the same class of approximation as its ancestor-blind matching. The review panel machine-diffed both list constants against the live spec (exact, in spec order). (cherry picked from commit 40640d173ec680a05cf06bd9829273ab2a8805ae) --- .../css/class-wp-css-attribute-selector.php | 71 ++++++++++++++++++- .../tests/html-api/wpHtmlProcessor-select.php | 11 +++ .../html-api/wpHtmlTagProcessor-select.php | 17 +++++ 3 files changed, 98 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/html-api/css/class-wp-css-attribute-selector.php b/src/wp-includes/html-api/css/class-wp-css-attribute-selector.php index 8fd3b5b3cbd35..134e68104811f 100644 --- a/src/wp-includes/html-api/css/class-wp-css-attribute-selector.php +++ b/src/wp-includes/html-api/css/class-wp-css-attribute-selector.php @@ -90,6 +90,66 @@ final class WP_CSS_Attribute_Selector extends WP_CSS_Selector_Parser_Matcher { */ const MODIFIER_CASE_INSENSITIVE = 'case-insensitive'; + /** + * The attributes whose values HTML defines as ASCII case-insensitive + * for attribute selectors on an HTML element, when the selector has no + * `i`/`s` modifier. An explicit `s` modifier forces case-sensitive + * matching even for these attributes; elements in other namespaces + * (SVG, MathML) are unaffected. + * + * The names are stored as array keys for constant-time lookup. + * + * @see https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors + */ + const HTML_CASE_INSENSITIVE_ATTRIBUTE_VALUES = array( + 'accept' => true, + 'accept-charset' => true, + 'align' => true, + 'alink' => true, + 'axis' => true, + 'bgcolor' => true, + 'charset' => true, + 'checked' => true, + 'clear' => true, + 'codetype' => true, + 'color' => true, + 'compact' => true, + 'declare' => true, + 'defer' => true, + 'dir' => true, + 'direction' => true, + 'disabled' => true, + 'enctype' => true, + 'face' => true, + 'frame' => true, + 'hreflang' => true, + 'http-equiv' => true, + 'lang' => true, + 'language' => true, + 'link' => true, + 'media' => true, + 'method' => true, + 'multiple' => true, + 'nohref' => true, + 'noresize' => true, + 'noshade' => true, + 'nowrap' => true, + 'readonly' => true, + 'rel' => true, + 'rev' => true, + 'rules' => true, + 'scope' => true, + 'scrolling' => true, + 'selected' => true, + 'shape' => true, + 'target' => true, + 'text' => true, + 'type' => true, + 'valign' => true, + 'valuetype' => true, + 'vlink' => true, + ); + /** * The name of the attribute to match. * @@ -185,7 +245,16 @@ public function matches( WP_HTML_Tag_Processor $processor ): bool { $attr_value = ''; } - $case_insensitive = self::MODIFIER_CASE_INSENSITIVE === $this->modifier; + /* + * Without an explicit modifier, HTML defines some attributes' values + * as ASCII case-insensitive on HTML elements. An explicit `s` + * modifier forces case-sensitive matching even for those. + */ + $case_insensitive = self::MODIFIER_CASE_INSENSITIVE === $this->modifier || ( + null === $this->modifier && + 'html' === $processor->get_namespace() && + isset( self::HTML_CASE_INSENSITIVE_ATTRIBUTE_VALUES[ strtolower( $this->name ) ] ) + ); switch ( $this->matcher ) { case self::MATCH_EXACT: diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php index 0fb5788efce7f..fcb1acf3fa7d6 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php @@ -63,6 +63,17 @@ public static function data_selectors(): array { 'empty value ^= i matches nothing' => array( '', '[x^="" i]', 0 ), 'empty value = matches empty' => array( '', '[x=""]', 1 ), 'empty value |= matches empty or hyphen-prefixed' => array( '', '[x|=""]', 2 ), + + /* + * HTML's case-insensitive attribute value list applies to + * "an HTML element in an HTML document": a foreign element with + * the same attribute name keeps case-sensitive matching. + * ( Chromium applies the list to foreign elements as well, + * diverging from the HTML specification here. ) + * + * https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors + */ + 'HTML-namespace-only attribute case-insensitivity' => array( '', '[type=TEXT]', 1 ), ); } diff --git a/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php index d09a6e350256d..1062c66a40253 100644 --- a/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php +++ b/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php @@ -95,6 +95,23 @@ public static function data_selectors(): array { 'EOF-truncated quoted value' => array( '
', '[att="a b', 1 ), 'EOF-truncated with modifier' => array( '
', '[att=val i', 1 ), + /* + * HTML defines a set of attributes whose values must match ASCII + * case-insensitively in selectors when no modifier is present. + * An explicit `s` modifier still forces case-sensitive matching. + * Attributes outside the list stay case-sensitive by default. + * + * https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors + */ + 'HTML insensitive attribute =' => array( '', '[type=TEXT]', 2 ), + 'HTML insensitive attribute ~=' => array( '', '[rel~=nofollow]', 1 ), + 'HTML insensitive attribute ^=' => array( '', '[media^=screen]', 1 ), + 'HTML insensitive attribute |=' => array( '', '[hreflang|=en]', 1 ), + 'HTML insensitive attribute s mod' => array( '', '[type=text s]', 1 ), + 'HTML insensitive attribute i mod' => array( '', '[type=text i]', 2 ), + 'unlisted attribute stays sensitive' => array( '', '[data-type=TEXT]', 1 ), + 'listed attribute name is matched case-insensitively in the list' => array( '', '[TYPE=TEXT]', 1 ), + 'list' => array( '

', 'a, p, .class, #id, [att]', 2 ), 'compound' => array( '

', 'custom-el[att="bar"][ fruit ~= "banana" i]', 1 ), ); From 00537a266f562edbf062cef6ccf7204c6e2dabc8 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 11 Jun 2026 10:48:22 +0200 Subject: [PATCH 153/634] CSS selector: Decode identity escapes without copying the input tail The identity arm of consume_escaped_codepoint() read one character via mb_substr( substr( $input, $offset ), 0, 1 ), copying the entire remaining input per escape: O(n^2) over selectors composed of escapes, plus an O(n) temporary allocation each time. Size the code point in place instead with the bounded scanner _wp_scan_utf8( $input, $at, $invalid_length, 4, 1 ) from compat-utf8.php (WP 6.9, loaded unconditionally before the HTML API), then copy at most 4 bytes. Escapes of invalid UTF-8 fall through to the literal previous mb_substr() line, so behavior is preserved by construction under every mb_substitute_character setting; that fallback remains O(tail) per call, accepted for developer-supplied selectors. _wp_utf8_codepoint_span() is deliberately not used: it leaves the scanner's ASCII fast-path unbounded, which is quadratic again (noted in-code). 200KB of repeated \g through parse_ident: 180 ms before, 45 ms after, with linear scaling after (47/90/180 ms at 200/400/800KB; previously ~4x per doubling) and half the peak memory. Escape pin coverage grows to 14 cases: 2/3/4-byte characters including at end of input, NUL, and each invalid-byte class (lone continuation, overlong lead, invalid lead, truncated 3/4-byte, encoded surrogate, above U+10FFFF), with expectations probe-verified against the pre-change implementation. Adversarial review: equivalence reviewer ran ~74M differential old-vs-new cases (exhaustive byte-class boundaries at every offset, random fuzz, non-default mb_substitute_character) with 0 mismatches; perf reviewer independently reproduced the quadratic-before / linear-after curves; integration reviewer verified load order (including SHORTINIT), private-function precedent, and phpcs. All approved. Gates: full html-api PHPUnit group green (1654 tests), fuzzer 5000 seeds 0 failures. (cherry picked from commit 9d82c1ccafbf4a8db412f7873e01eb55a9b0c627) --- .../class-wp-css-selector-parser-matcher.php | 29 +++++++++++++++- .../html-api/wpCssSelectorParserMatcher.php | 33 +++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/html-api/css/class-wp-css-selector-parser-matcher.php b/src/wp-includes/html-api/css/class-wp-css-selector-parser-matcher.php index 23d14d01c673b..0fe7d6c608ed0 100644 --- a/src/wp-includes/html-api/css/class-wp-css-selector-parser-matcher.php +++ b/src/wp-includes/html-api/css/class-wp-css-selector-parser-matcher.php @@ -258,7 +258,34 @@ final protected static function consume_escaped_codepoint( $input, &$offset ): s return $codepoint_char; } - // $offset is a byte offset; mb_substr() expects a character offset. + /* + * Find the byte length of the code point at $offset without copying the rest + * of the input: a code point is at most 4 bytes, so the scan is bounded and + * an escape of valid UTF-8 decodes in O(1) regardless of selector length. + * Escaped invalid bytes take the mb_substr() fallback below, which copies + * the remaining input on each call. + * + * `_wp_utf8_codepoint_span()` is not suitable here: it does not bound the + * scan, so its ASCII fast-path reads to the end of the input on every call, + * which is quadratic over a selector composed of escapes. + */ + $at = $offset; + $invalid_length = 0; + _wp_scan_utf8( $input, $at, $invalid_length, 4, 1 ); + if ( $at > $offset ) { + $codepoint_char = substr( $input, $offset, $at - $offset ); + $offset = $at; + return $codepoint_char; + } + + /* + * The bytes at $offset are not valid UTF-8. Decode with mbstring to + * preserve the parser's long-standing behavior for invalid input, which + * depends on `mb_substitute_character()`: with the default setting the + * substitute character `?` is returned and one byte is consumed. + * + * $offset is a byte offset; mb_substr() expects a character offset. + */ $codepoint_char = mb_substr( substr( $input, $offset ), 0, 1, 'UTF-8' ); $offset += strlen( $codepoint_char ); return $codepoint_char; diff --git a/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php b/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php index 37f26ec8f3b92..6971fbbdec7fc 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php +++ b/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php @@ -97,6 +97,39 @@ public static function data_idents(): array { 'lone escape at EOF' => array( '\\', "\u{fffd}", '' ), 'hyphen then escape at EOF' => array( '-\\', "-\u{fffd}", '' ), + // Identity escapes of multibyte characters, by UTF-8 sequence length. + 'escaped 2-byte character' => array( "\\\u{FC}z", "\u{FC}z", '' ), + 'escaped 3-byte character' => array( "\\\u{270F}z", "\u{270F}z", '' ), + 'escaped 4-byte character' => array( "\\\u{1F0A1}z", "\u{1F0A1}z", '' ), + 'escaped 2-byte character at EOF' => array( "a\\\u{FC}", "a\u{FC}", '' ), + 'escaped 3-byte character at EOF' => array( "a\\\u{270F}", "a\u{270F}", '' ), + 'escaped 4-byte character at EOF' => array( "a\\\u{1F0A1}", "a\u{1F0A1}", '' ), + + /* + * An escaped NUL byte passes through this low-level helper unchanged. + * This is unreachable through the public selector API, where + * normalize_selector_input() replaces NUL with U+FFFD before parsing. + */ + 'escaped NUL byte' => array( "a\\\x00z", "a\x00z", '' ), + + /* + * Identity escapes of invalid UTF-8 byte sequences. + * + * These inputs are not valid UTF-8. The escaped invalid byte decodes via + * mbstring substitution (`?` under the default `mb_substitute_character()` + * setting) and one byte is consumed; any continuation bytes that follow + * are appended verbatim by the ident-code-point path. These cases pin the + * current behavior under the default mbstring settings; they do not + * assert it is desirable. + */ + 'escaped lone continuation byte' => array( "a\\\x80z", 'a?z', '' ), + 'escaped overlong lead 0xC0' => array( "a\\\xC0\xAFz", "a?\xAFz", '' ), + 'escaped invalid lead 0xF5' => array( "a\\\xF5z", 'a?z', '' ), + 'escaped truncated 3-byte sequence' => array( "a\\\xE2\x80z", "a?\x80z", '' ), + 'escaped truncated 4-byte at EOF' => array( "a\\\xF0\x9F\x82", "a?\x9F\x82", '' ), + 'escaped UTF-8-encoded surrogate' => array( "a\\\xED\xA0\x80z", "a?\xA0\x80z", '' ), + 'escaped sequence above U+10FFFF' => array( "a\\\xF4\x90\x80\x80z", "a?\x90\x80\x80z", '' ), + // Invalid 'Invalid: (empty string)' => array( '' ), 'Invalid: bad start >' => array( '>ident' ), From 1b148d7a274a880fdca9aa733fc3b66bb59b9150 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 11 Jun 2026 11:45:35 +0200 Subject: [PATCH 154/634] CSS selector: Pin a canary mb_substitute_character in escape tests Decoding an identity escape of invalid UTF-8 leaks the process-global mb_substitute_character() setting into parse results: the substitute character is returned and the offset advances by the byte length of the substitute, not of the invalid sequence. Under the default '?' this is nearly invisible; under a multibyte substitute it swallows following characters and can push the offset past the end of the input. Pin the setting to a distinctive canary -- U+2603 SNOWMAN -- in set_up()/tear_down() and rewrite the seven invalid-byte pins to the canary expectations, making the dependence unmistakable: five cases show the trailing 'z' being eaten, and a dedicated test asserts the offset overrun that the rest-of-input assertion cannot see (substr() returns '' both at and past the end). A differential run of all provider cases under canary/default/'none' confirms exactly these seven react to the setting; everything else is independent of it. These pins document the leak, not endorse it. They are the ready-made red suite for the planned fix: decoding invalid bytes to U+FFFD per maximal subpart (CSS Syntax 3 section 3.2 via the WHATWG Encoding Standard) makes the outputs setting-independent and flips every one of these expectations. Adversarial review approved; full html-api group green (1654 tests) with the substitute character verified restored after the run. (cherry picked from commit 9b0b1df6ec47b2937e9eb49a4388b08bb0f5e104) --- .../html-api/wpCssSelectorParserMatcher.php | 78 +++++++++++++++---- 1 file changed, 65 insertions(+), 13 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php b/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php index 6971fbbdec7fc..707afb5d4a133 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php +++ b/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php @@ -13,8 +13,27 @@ class Tests_HtmlApi_WpCssSelectorParserMatcher extends WP_UnitTestCase { private $test_class; + /** + * Preserves the `mb_substitute_character()` setting around each test. + * + * @var int|string + */ + private $original_substitute_character; + public function set_up(): void { parent::set_up(); + + /* + * Decoding invalid UTF-8 in identity escapes leaks the process-global + * `mb_substitute_character()` setting into parse results. Pin it to a + * distinctive character — U+2603 SNOWMAN (☃) — so that any dependence + * on the setting is unmistakable in test expectations, rather than a + * `?` that looks like an intentional placeholder. The escape-decode + * cases below document the leak; a parser that decodes invalid bytes + * to U+FFFD per CSS Syntax §3.2 would be unaffected by this setting. + */ + $this->original_substitute_character = mb_substitute_character(); + mb_substitute_character( 0x2603 ); $this->test_class = new class() extends WP_CSS_Selector_Parser_Matcher { public function matches( $processor ): bool { throw new Error( 'Matches called on test class.' ); @@ -47,6 +66,11 @@ public static function test_is_ident_start_codepoint( string $input, int $offset }; } + public function tear_down(): void { + mb_substitute_character( $this->original_substitute_character ); + parent::tear_down(); + } + /** * Data provider. * @@ -115,20 +139,30 @@ public static function data_idents(): array { /* * Identity escapes of invalid UTF-8 byte sequences. * - * These inputs are not valid UTF-8. The escaped invalid byte decodes via - * mbstring substitution (`?` under the default `mb_substitute_character()` - * setting) and one byte is consumed; any continuation bytes that follow - * are appended verbatim by the ident-code-point path. These cases pin the - * current behavior under the default mbstring settings; they do not - * assert it is desirable. + * These inputs are not valid UTF-8. The escaped invalid byte decodes to + * the process-global `mb_substitute_character()` — pinned to U+2603 (☃) + * in set_up() to make the dependence visible — and the offset then + * advances by the byte length of *the substitute character* (3 bytes + * for ☃, 1 byte for the default `?`), not of the invalid sequence. + * The expectations below show the damage: following characters are + * swallowed (the `z` in most cases) and the offset can even overrun + * the end of the input (the lone-continuation and 0xF5 cases end with + * the offset one byte past the end; see the dedicated offset test). + * + * These cases pin the current behavior to document the leak, not to + * endorse it. CSS Syntax §3.2 decodes the input byte stream per the + * WHATWG Encoding Standard, which replaces each maximal subpart of an + * invalid sequence with U+FFFD; when the parser does that, these + * expectations flip to U+FFFD outputs that are independent of + * `mb_substitute_character()`. */ - 'escaped lone continuation byte' => array( "a\\\x80z", 'a?z', '' ), - 'escaped overlong lead 0xC0' => array( "a\\\xC0\xAFz", "a?\xAFz", '' ), - 'escaped invalid lead 0xF5' => array( "a\\\xF5z", 'a?z', '' ), - 'escaped truncated 3-byte sequence' => array( "a\\\xE2\x80z", "a?\x80z", '' ), - 'escaped truncated 4-byte at EOF' => array( "a\\\xF0\x9F\x82", "a?\x9F\x82", '' ), - 'escaped UTF-8-encoded surrogate' => array( "a\\\xED\xA0\x80z", "a?\xA0\x80z", '' ), - 'escaped sequence above U+10FFFF' => array( "a\\\xF4\x90\x80\x80z", "a?\x90\x80\x80z", '' ), + 'escaped lone continuation byte' => array( "a\\\x80z", "a\u{2603}", '' ), + 'escaped overlong lead 0xC0' => array( "a\\\xC0\xAFz", "a\u{2603}", '' ), + 'escaped invalid lead 0xF5' => array( "a\\\xF5z", "a\u{2603}", '' ), + 'escaped truncated 3-byte sequence' => array( "a\\\xE2\x80z", "a\u{2603}", '' ), + 'escaped truncated 4-byte at EOF' => array( "a\\\xF0\x9F\x82", "a\u{2603}", '' ), + 'escaped UTF-8-encoded surrogate' => array( "a\\\xED\xA0\x80z", "a\u{2603}z", '' ), + 'escaped sequence above U+10FFFF' => array( "a\\\xF4\x90\x80\x80z", "a\u{2603}\x80z", '' ), // Invalid 'Invalid: (empty string)' => array( '' ), @@ -169,6 +203,24 @@ public function test_parse_ident( string $input, ?string $expected = null, ?stri } } + /** + * The rest-of-input assertion above cannot distinguish an offset at the end + * of the input from one past it (`substr()` returns '' for both), so the + * offset overrun caused by decoding an escaped invalid byte to a multibyte + * substitute character is pinned explicitly here: the 3-byte ☃ advance over + * the 1-byte invalid sequence leaves the offset one byte past the end. + * Decoding invalid bytes to U+FFFD with maximal-subpart consumption would + * turn this case into `"a\u{FFFD}z"` with the offset at the end of input. + */ + public function test_parse_ident_escaped_invalid_byte_overruns_offset() { + $input = "a\\\x80z"; + $offset = 0; + $result = $this->test_class::test_parse_ident( $input, $offset ); + + $this->assertSame( "a\u{2603}", $result, 'Ident did not match.' ); + $this->assertSame( strlen( $input ) + 1, $offset, 'Offset did not overrun the end of input.' ); + } + /** * @ticket 62653 * From b26128e09b4bf4b24a0771a29ebdf76c7f566e3f Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 11 Jun 2026 18:07:47 +0200 Subject: [PATCH 155/634] CSS selector: Scrub invalid UTF-8 selector input to U+FFFD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Selector strings are UTF-8 text. from_selectors() now decodes the input byte stream before parsing: normalize_selector_input() replaces each maximal subpart of an ill-formed byte sequence with U+FFFD via wp_scrub_utf8() (WP 6.9), per the byte-decoding step CSS Syntax 3 section 3.2 defines through the WHATWG Encoding Standard's UTF-8 decoder. A replaced selector is almost always a developer mistake (mojibake, double encoding) that would otherwise yield a silently empty match set, so the replacement also reports _doing_it_wrong(), named "::from_selectors" via late static binding. The mb_substitute_character() leak in consume_escaped_codepoint() dies structurally: with all public input scrubbed, the identity arm's mb_substr() fallback became unreachable through from_selectors() and is replaced by a deterministic decode for direct parse() callers — consume the maximal subpart the existing _wp_scan_utf8() call already reported and return one U+FFFD, consistent with the scrub. This also removes the remaining O(tail)-per-escape copy for invalid bytes. Design decision: reject (wp_is_valid_utf8() -> null) and raw byte passthrough were both considered and discarded by a three-persona adversarial design review; scrub is the option that stays stable under both the current raw value getters and a future where the getters scrub their return values. An escape-arm-only U+FFFD decode was ruled out unanimously: it would break the identity property that escaping a non-special code point is equivalent to writing it unescaped. The known divergence is pinned in a test: a scrubbed selector cannot match raw invalid bytes in a document (the Tag Processor reports raw bytes); if the HTML API value getters are ever changed to scrub, that pin flips to a match and must be updated in the same change. The compound-list class docblock gains a "Text Encoding" section recording the contract. Tests: the seven U+2603-canary escape pins flip to maximal-subpart U+FFFD expectations, and the canary is retained permanently — its job inverted from documenting the leak to proving setting-independence (a reintroduced mb_substitute_character dependence fails eight tests). New coverage: scrub + notice through from_selectors() on both list classes (the complex-list test pins the late-static-binding notice name), a lone invalid byte parsing as a U+FFFD type selector, the notice firing even when the scrubbed selector is rejected by the grammar, string-token invalid-byte decode, identity-escape equivalence and U+FFFD matching through select(), and the raw-document-bytes no-match pin (deliberately unique 0xC1 byte: select() memoizes the last parsed selector string, so a unique selector guarantees the parse-time notice under any test order). Adversarial review: three hostile reviewers. The equivalence reviewer verified the decode against an independent reference WHATWG UTF-8 decoder (exhaustive 1-2-byte tails, ~204k boundary-alphabet 3-4-byte tails, 100k random; zero mismatches, all under a U+2603 canary), scrub idempotence and ordering-neutrality (200k cases), and the notice-name propagation. The test reviewer killed four core mutations against the suite and demonstrated two test defects (select()-cache coupling, an unpinned complex-list notice name), both fixed before commit. The integration reviewer verified worker-model equivalence and determinism (10000 fuzz seeds clean). All approved. Gates: full html-api group green (1665 tests), fuzzer 5000 seeds 0 failures, self-check OK, phpcs clean. (cherry picked from commit 598ed6f363daec3d954cf22cee71b7f98f1f17c2) --- .../class-wp-css-compound-selector-list.php | 24 ++++ .../class-wp-css-selector-parser-matcher.php | 46 +++++-- .../html-api/wpCssComplexSelectorList.php | 14 ++ .../html-api/wpCssCompoundSelectorList.php | 60 +++++++++ .../html-api/wpCssSelectorParserMatcher.php | 125 +++++++++--------- .../html-api/wpHtmlTagProcessor-select.php | 64 ++++++++- 6 files changed, 254 insertions(+), 79 deletions(-) diff --git a/src/wp-includes/html-api/css/class-wp-css-compound-selector-list.php b/src/wp-includes/html-api/css/class-wp-css-compound-selector-list.php index c9eb936ff7371..4042b1bc94f3e 100644 --- a/src/wp-includes/html-api/css/class-wp-css-compound-selector-list.php +++ b/src/wp-includes/html-api/css/class-wp-css-compound-selector-list.php @@ -18,6 +18,26 @@ * It takes a CSS selector string and returns an instance of itself or `null` if the selector * is invalid or unsupported. * + * ### Text Encoding + * + * Selector strings are UTF-8 text. Ill-formed byte sequences in a selector string are + * replaced with U+FFFD REPLACEMENT CHARACTER (visually "�"), one per maximal subpart, + * before parsing — following the byte-decoding step CSS Syntax specifies for input + * byte streams (via the WHATWG Encoding Standard's UTF-8 decoder), not a browser's + * `querySelector`, which receives already-decoded strings and can never see ill-formed + * input. The replacement also triggers a `_doing_it_wrong()` notice, since a selector + * containing ill-formed bytes is almost always a developer error and, once replaced, + * matches only literal U+FFFD characters in the document. + * + * Note that the document side is byte-oriented and unscrubbed: the Tag Processor + * reports attribute values and class names with their raw bytes intact (see the + * "Text Encoding" section of {@see WP_HTML_Tag_Processor}). A selector containing + * ill-formed bytes therefore never matches those same raw bytes in a document. + * Selectors for non-UTF-8 ( but ASCII-compatible ) documents can only reliably match + * non-ASCII values by converting the selector and document to UTF-8 beforehand. + * + * @link https://www.w3.org/TR/css-syntax-3/#input-byte-stream + * * A subset of the CSS selector grammar is supported. The grammar is defined in the CSS Syntax * specification, which is available at {@link https://www.w3.org/TR/selectors/#grammar}. * @@ -115,6 +135,10 @@ protected function __construct( array $selectors ) { * Takes a CSS selector string and returns an instance of itself or `null` if the selector * string is invalid or unsupported. * + * The selector string must be UTF-8: ill-formed byte sequences are replaced with + * U+FFFD per maximal subpart before parsing and reported with `_doing_it_wrong()`. + * See the "Text Encoding" section of the class documentation. + * * @param string $input CSS selectors. * @return static|null */ diff --git a/src/wp-includes/html-api/css/class-wp-css-selector-parser-matcher.php b/src/wp-includes/html-api/css/class-wp-css-selector-parser-matcher.php index 0fe7d6c608ed0..14d9d28a771cc 100644 --- a/src/wp-includes/html-api/css/class-wp-css-selector-parser-matcher.php +++ b/src/wp-includes/html-api/css/class-wp-css-selector-parser-matcher.php @@ -262,8 +262,6 @@ final protected static function consume_escaped_codepoint( $input, &$offset ): s * Find the byte length of the code point at $offset without copying the rest * of the input: a code point is at most 4 bytes, so the scan is bounded and * an escape of valid UTF-8 decodes in O(1) regardless of selector length. - * Escaped invalid bytes take the mb_substr() fallback below, which copies - * the remaining input on each call. * * `_wp_utf8_codepoint_span()` is not suitable here: it does not bound the * scan, so its ASCII fast-path reads to the end of the input on every call, @@ -279,16 +277,15 @@ final protected static function consume_escaped_codepoint( $input, &$offset ): s } /* - * The bytes at $offset are not valid UTF-8. Decode with mbstring to - * preserve the parser's long-standing behavior for invalid input, which - * depends on `mb_substitute_character()`: with the default setting the - * substitute character `?` is returned and one byte is consumed. - * - * $offset is a byte offset; mb_substr() expects a character offset. + * The bytes at $offset are not valid UTF-8, which can only happen when + * `parse()` was called directly with un-normalized input: the public + * `from_selectors()` API replaces ill-formed byte sequences with U+FFFD + * before parsing. Decode consistently with that normalization — consume + * the maximal subpart of the ill-formed sequence, whose length the scan + * above reported, and return a single U+FFFD. */ - $codepoint_char = mb_substr( substr( $input, $offset ), 0, 1, 'UTF-8' ); - $offset += strlen( $codepoint_char ); - return $codepoint_char; + $offset += max( 1, $invalid_length ); + return "\u{FFFD}"; } /** @@ -511,14 +508,39 @@ final protected static function check_if_three_code_points_would_start_an_ident_ } /** - * Normalizes selector input for processing. + * Normalizes selector input for processing: decodes the byte stream as + * UTF-8 ( replacing ill-formed sequences with U+FFFD ), then filters the + * code points per the input-preprocessing rules. * + * @see https://www.w3.org/TR/css-syntax-3/#input-byte-stream * @see https://www.w3.org/TR/css-syntax-3/#input-preprocessing * * @param string $input The selector string. * @return string The normalized selector string. */ final protected static function normalize_selector_input( string $input ): string { + /* + * > The input byte stream defines the byte stream that comprises a style sheet. + * > To decode bytes into a stream of code points… + * + * Selector strings are UTF-8 text. Decoding replaces each maximal + * subpart of an ill-formed byte sequence with U+FFFD REPLACEMENT + * CHARACTER (�), per the WHATWG Encoding Standard's UTF-8 decoder. + * The replaced selector is unlikely to match the elements the + * developer intended, so the replacement also reports a notice. + * + * https://www.w3.org/TR/css-syntax-3/#input-byte-stream + */ + $scrubbed = wp_scrub_utf8( $input ); + if ( $scrubbed !== $input ) { + _doing_it_wrong( + get_called_class() . '::from_selectors', + 'Selector strings must be valid UTF-8: ill-formed byte sequences were replaced with U+FFFD (�), which is unlikely to match the intended elements.', + '{WP_VERSION}' + ); + $input = $scrubbed; + } + /* * > A selector string is a list of one or more complex selectors ([SELECTORS4], section 3.1) that may be surrounded by whitespace… * diff --git a/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php b/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php index edf912e97f490..b85f788f98f0d 100644 --- a/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php +++ b/tests/phpunit/tests/html-api/wpCssComplexSelectorList.php @@ -48,4 +48,18 @@ public function test_parse_empty_selector_list() { $result = WP_CSS_Complex_Selector_List::from_selectors( $input ); $this->assertNull( $result ); } + + /** + * The invalid-UTF-8 scrub notice reports the called class: through this + * class it must be named WP_CSS_Complex_Selector_List::from_selectors, + * not the WP_CSS_Compound_Selector_List parent where from_selectors() + * and the scrub are implemented. The fuzzer's notice model depends on + * the per-class name. + * + * @expectedIncorrectUsage WP_CSS_Complex_Selector_List::from_selectors + */ + public function test_invalid_utf8_scrub_notice_reports_the_called_class() { + $result = WP_CSS_Complex_Selector_List::from_selectors( "el \xC2.child" ); + $this->assertNotNull( $result, 'Selector with invalid UTF-8 should parse after scrubbing.' ); + } } diff --git a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php index c71aa09596d8f..33149c22ed400 100644 --- a/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php +++ b/tests/phpunit/tests/html-api/wpCssCompoundSelectorList.php @@ -80,4 +80,64 @@ public function test_unsupported_complex_selector() { $result = WP_CSS_Compound_Selector_List::from_selectors( $input ); $this->assertNull( $result ); } + + /** + * Selector strings are UTF-8 text: invalid byte sequences are replaced + * with U+FFFD per maximal subpart (CSS Syntax §3.2 via the WHATWG + * Encoding Standard) before parsing, so the selector parses rather than + * being rejected. The replacement is almost certainly not what the + * developer meant, so it also triggers `_doing_it_wrong()`. + * + * @expectedIncorrectUsage WP_CSS_Compound_Selector_List::from_selectors + */ + public function test_invalid_utf8_is_scrubbed_to_replacement_character_and_notifies() { + $result = WP_CSS_Compound_Selector_List::from_selectors( ".B\xFCcher" ); + $this->assertNotNull( $result, 'Selector with invalid UTF-8 should parse after scrubbing.' ); + } + + /** + * Valid UTF-8 — including a literal U+FFFD — must parse without any + * incorrect-usage notice: scrubbing is the identity function on valid + * input. + */ + public function test_valid_utf8_with_literal_replacement_character_is_not_notified() { + $result = WP_CSS_Compound_Selector_List::from_selectors( ".B\u{FFFD}cher" ); + $this->assertNotNull( $result, 'Selector containing a literal U+FFFD should parse.' ); + } + + /** + * The whole input is scrubbed uniformly, so a selector list with invalid + * bytes in one of several selectors still parses as a list. + * + * @expectedIncorrectUsage WP_CSS_Compound_Selector_List::from_selectors + */ + public function test_invalid_utf8_in_selector_list_is_scrubbed() { + $result = WP_CSS_Compound_Selector_List::from_selectors( ".ok, .B\xE2\x8Ccher" ); + $this->assertNotNull( $result, 'Selector list with invalid UTF-8 should parse after scrubbing.' ); + } + + /** + * A selector consisting of nothing but an invalid byte parses: it scrubs + * to U+FFFD, which is an ident-start code point and therefore a valid + * type selector. Surprising, but it follows from the scrub running + * before tokenization — the parser never sees the invalid byte. + * + * @expectedIncorrectUsage WP_CSS_Compound_Selector_List::from_selectors + */ + public function test_lone_invalid_byte_parses_as_replacement_character_type_selector() { + $result = WP_CSS_Compound_Selector_List::from_selectors( "\x80" ); + $this->assertNotNull( $result, 'A lone invalid byte should parse as a U+FFFD type selector.' ); + } + + /** + * The scrub notice reports the byte replacement, which happens before + * parsing — it fires even when the scrubbed selector is then rejected + * by the grammar. + * + * @expectedIncorrectUsage WP_CSS_Compound_Selector_List::from_selectors + */ + public function test_invalid_utf8_notice_fires_even_when_selector_is_rejected() { + $result = WP_CSS_Compound_Selector_List::from_selectors( "\x80 div" ); + $this->assertNull( $result, 'Descendant combinators are unsupported by the compound list; the scrubbed selector should still be rejected.' ); + } } diff --git a/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php b/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php index 707afb5d4a133..181519b3cbed3 100644 --- a/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php +++ b/tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php @@ -24,13 +24,12 @@ public function set_up(): void { parent::set_up(); /* - * Decoding invalid UTF-8 in identity escapes leaks the process-global - * `mb_substitute_character()` setting into parse results. Pin it to a - * distinctive character — U+2603 SNOWMAN (☃) — so that any dependence - * on the setting is unmistakable in test expectations, rather than a - * `?` that looks like an intentional placeholder. The escape-decode - * cases below document the leak; a parser that decodes invalid bytes - * to U+FFFD per CSS Syntax §3.2 would be unaffected by this setting. + * Parse results must not depend on the process-global + * `mb_substitute_character()` setting. Pin it to a distinctive + * character — U+2603 SNOWMAN (☃) — for every test in this file: any + * dependence on the setting would surface as a ☃ in the results + * rather than the expected U+FFFD. This guards the invalid-byte + * decode, which once leaked the setting into parse results. */ $this->original_substitute_character = mb_substitute_character(); mb_substitute_character( 0x2603 ); @@ -139,30 +138,25 @@ public static function data_idents(): array { /* * Identity escapes of invalid UTF-8 byte sequences. * - * These inputs are not valid UTF-8. The escaped invalid byte decodes to - * the process-global `mb_substitute_character()` — pinned to U+2603 (☃) - * in set_up() to make the dependence visible — and the offset then - * advances by the byte length of *the substitute character* (3 bytes - * for ☃, 1 byte for the default `?`), not of the invalid sequence. - * The expectations below show the damage: following characters are - * swallowed (the `z` in most cases) and the offset can even overrun - * the end of the input (the lone-continuation and 0xF5 cases end with - * the offset one byte past the end; see the dedicated offset test). - * - * These cases pin the current behavior to document the leak, not to - * endorse it. CSS Syntax §3.2 decodes the input byte stream per the - * WHATWG Encoding Standard, which replaces each maximal subpart of an - * invalid sequence with U+FFFD; when the parser does that, these - * expectations flip to U+FFFD outputs that are independent of - * `mb_substitute_character()`. + * These inputs are not valid UTF-8, which can only reach the parser + * through a direct `parse()` call: the public `from_selectors()` API + * replaces invalid byte sequences with U+FFFD before parsing. On + * this un-normalized path the escape decodes the maximal subpart of + * the invalid sequence (CSS Syntax §3.2 via the WHATWG Encoding + * Standard) to a single U+FFFD — independent of the + * `mb_substitute_character()` setting, which set_up() pins to ☃ + * precisely to prove that independence. Invalid bytes *after* the + * escaped subpart are not escaped; they pass through this low-level + * helper raw, exactly as unescaped invalid bytes do (the 0xAF, + * 0xA0 0x80, and 0x90 0x80 0x80 tails below). */ - 'escaped lone continuation byte' => array( "a\\\x80z", "a\u{2603}", '' ), - 'escaped overlong lead 0xC0' => array( "a\\\xC0\xAFz", "a\u{2603}", '' ), - 'escaped invalid lead 0xF5' => array( "a\\\xF5z", "a\u{2603}", '' ), - 'escaped truncated 3-byte sequence' => array( "a\\\xE2\x80z", "a\u{2603}", '' ), - 'escaped truncated 4-byte at EOF' => array( "a\\\xF0\x9F\x82", "a\u{2603}", '' ), - 'escaped UTF-8-encoded surrogate' => array( "a\\\xED\xA0\x80z", "a\u{2603}z", '' ), - 'escaped sequence above U+10FFFF' => array( "a\\\xF4\x90\x80\x80z", "a\u{2603}\x80z", '' ), + 'escaped lone continuation byte' => array( "a\\\x80z", "a\u{FFFD}z", '' ), + 'escaped overlong lead 0xC0' => array( "a\\\xC0\xAFz", "a\u{FFFD}\xAFz", '' ), + 'escaped invalid lead 0xF5' => array( "a\\\xF5z", "a\u{FFFD}z", '' ), + 'escaped truncated 3-byte sequence' => array( "a\\\xE2\x80z", "a\u{FFFD}z", '' ), + 'escaped truncated 4-byte at EOF' => array( "a\\\xF0\x9F\x82", "a\u{FFFD}", '' ), + 'escaped UTF-8-encoded surrogate' => array( "a\\\xED\xA0\x80z", "a\u{FFFD}\xA0\x80z", '' ), + 'escaped sequence above U+10FFFF' => array( "a\\\xF4\x90\x80\x80z", "a\u{FFFD}\x90\x80\x80z", '' ), // Invalid 'Invalid: (empty string)' => array( '' ), @@ -206,19 +200,19 @@ public function test_parse_ident( string $input, ?string $expected = null, ?stri /** * The rest-of-input assertion above cannot distinguish an offset at the end * of the input from one past it (`substr()` returns '' for both), so the - * offset overrun caused by decoding an escaped invalid byte to a multibyte - * substitute character is pinned explicitly here: the 3-byte ☃ advance over - * the 1-byte invalid sequence leaves the offset one byte past the end. - * Decoding invalid bytes to U+FFFD with maximal-subpart consumption would - * turn this case into `"a\u{FFFD}z"` with the offset at the end of input. + * offset arithmetic of the invalid-byte decode is pinned explicitly here: + * the escape consumes exactly the 1-byte maximal subpart and the following + * `z`, leaving the offset at — never past — the end of the input. (The + * previous `mb_substr()`-based decode advanced by the byte length of the + * substitute character and overran the end by one byte under the ☃ canary.) */ - public function test_parse_ident_escaped_invalid_byte_overruns_offset() { + public function test_parse_ident_escaped_invalid_byte_does_not_overrun_offset() { $input = "a\\\x80z"; $offset = 0; $result = $this->test_class::test_parse_ident( $input, $offset ); - $this->assertSame( "a\u{2603}", $result, 'Ident did not match.' ); - $this->assertSame( strlen( $input ) + 1, $offset, 'Offset did not overrun the end of input.' ); + $this->assertSame( "a\u{FFFD}z", $result, 'Ident did not match.' ); + $this->assertSame( strlen( $input ), $offset, 'Offset should stop exactly at the end of input.' ); } /** @@ -244,35 +238,44 @@ public function test_parse_string( string $input, ?string $expected = null, ?str */ public static function data_strings(): array { return array( - '"foo"' => array( '"foo"', 'foo', '' ), - '"foo"after' => array( '"foo"after', 'foo', 'after' ), - '"foo""two"' => array( '"foo""two"', 'foo', '"two"' ), - '"foo"\'two\'' => array( '"foo"\'two\'', 'foo', "'two'" ), + '"foo"' => array( '"foo"', 'foo', '' ), + '"foo"after' => array( '"foo"after', 'foo', 'after' ), + '"foo""two"' => array( '"foo""two"', 'foo', '"two"' ), + '"foo"\'two\'' => array( '"foo"\'two\'', 'foo', "'two'" ), + + "'foo'" => array( "'foo'", 'foo', '' ), + "'foo'after" => array( "'foo'after", 'foo', 'after' ), + "'foo'\"two\"" => array( "'foo'\"two\"", 'foo', '"two"' ), + "'foo''two'" => array( "'foo''two'", 'foo', "'two'" ), - "'foo'" => array( "'foo'", 'foo', '' ), - "'foo'after" => array( "'foo'after", 'foo', 'after' ), - "'foo'\"two\"" => array( "'foo'\"two\"", 'foo', '"two"' ), - "'foo''two'" => array( "'foo''two'", 'foo', "'two'" ), + "'foo\\nbar'" => array( "'foo\\\nbar'", 'foobar', '' ), + "'foo\\31 23'" => array( "'foo\\31 23'", 'foo123', '' ), + "'Ü\\sup'" => array( "'Ü\\sup'", 'Üsup', '' ), + "'foo\\31\\n23'" => array( "'foo\\31\n23'", 'foo123', '' ), + "'foo\\31\\t23'" => array( "'foo\\31\t23'", 'foo123', '' ), + "'foo\\00003123'" => array( "'foo\\00003123'", 'foo123', '' ), - "'foo\\nbar'" => array( "'foo\\\nbar'", 'foobar', '' ), - "'foo\\31 23'" => array( "'foo\\31 23'", 'foo123', '' ), - "'Ü\\sup'" => array( "'Ü\\sup'", 'Üsup', '' ), - "'foo\\31\\n23'" => array( "'foo\\31\n23'", 'foo123', '' ), - "'foo\\31\\t23'" => array( "'foo\\31\t23'", 'foo123', '' ), - "'foo\\00003123'" => array( "'foo\\00003123'", 'foo123', '' ), + "'foo\\" => array( "'foo\\", 'foo', '' ), - "'foo\\" => array( "'foo\\", 'foo', '' ), + /* + * Invalid UTF-8 in string context, reachable only via a direct + * parse() call ( from_selectors() scrubs first ): an escaped + * invalid byte decodes its maximal subpart to U+FFFD, exactly as + * in ident context; raw invalid bytes pass through unexamined. + */ + 'string with escaped invalid byte' => array( "'a\\\xC0z'", "a\u{FFFD}z", '' ), + 'string with raw invalid byte' => array( "'a\xC0z'", "a\xC0z", '' ), - '"' => array( '"', '', '' ), - '"\\"' => array( '"\\"', '"', '' ), - '"missing close' => array( '"missing close', 'missing close', '' ), + '"' => array( '"', '', '' ), + '"\\"' => array( '"\\"', '"', '' ), + '"missing close' => array( '"missing close', 'missing close', '' ), // Invalid - 'Invalid: (empty string)' => array( '' ), - 'Invalid: .foo' => array( '.foo' ), - 'Invalid: #foo' => array( '#foo' ), - "Invalid: 'newline\\n'" => array( "'newline\n'" ), - 'Invalid: foo' => array( 'foo' ), + 'Invalid: (empty string)' => array( '' ), + 'Invalid: .foo' => array( '.foo' ), + 'Invalid: #foo' => array( '#foo' ), + "Invalid: 'newline\\n'" => array( "'newline\n'" ), + 'Invalid: foo' => array( 'foo' ), ); } } diff --git a/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php index 1062c66a40253..96bb8e1b4457d 100644 --- a/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php +++ b/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php @@ -136,9 +136,9 @@ public function test_invalid_selector( string $selector ) { */ public static function data_invalid_selectors(): array { return array( - 'complex descendant' => array( 'div *' ), - 'complex child' => array( 'div > *' ), - 'invalid selector' => array( '[invalid!selector]' ), + 'complex descendant' => array( 'div *' ), + 'complex child' => array( 'div > *' ), + 'invalid selector' => array( '[invalid!selector]' ), /* * A backslash before a newline at the end of input is not a valid @@ -146,9 +146,9 @@ public static function data_invalid_selectors(): array { * The CR and FF variants are normalized to a newline before * tokenizing. */ - 'escape before newline at end' => array( ".foo\\\n" ), - 'escape before CR at end' => array( ".foo\\\r" ), - 'escape before FF at end' => array( ".foo\\\f" ), + 'escape before newline at end' => array( ".foo\\\n" ), + 'escape before CR at end' => array( ".foo\\\r" ), + 'escape before FF at end' => array( ".foo\\\f" ), /* * EOF auto-closes an open attribute selector block, but @@ -159,4 +159,56 @@ public static function data_invalid_selectors(): array { 'lone open bracket' => array( '[' ), ); } + + /** + * Selector strings are UTF-8 text: invalid byte sequences are replaced + * with U+FFFD per maximal subpart before parsing. A selector containing + * invalid bytes therefore matches a literal U+FFFD in the document, and + * an identity escape of an invalid byte is equivalent to the same byte + * unescaped — both are scrubbed before tokenization. + * + * @expectedIncorrectUsage WP_CSS_Compound_Selector_List::from_selectors + */ + public function test_select_scrubbed_selector_matches_replacement_character() { + $html = "
"; + + $processor = new WP_HTML_Tag_Processor( $html ); + $this->assertTrue( + $processor->select( ".a\xC0b" ), + 'Scrubbed selector should match the replacement character in the document.' + ); + + $processor = new WP_HTML_Tag_Processor( $html ); + $this->assertTrue( + $processor->select( ".a\\\xC0b" ), + 'An identity escape of an invalid byte should be equivalent to the unescaped byte.' + ); + } + + /** + * A selector containing invalid bytes can never match those same raw + * bytes in a document: the selector side is scrubbed to U+FFFD while + * the Tag Processor reports raw document bytes untouched. + * + * This pins a deliberate, documented divergence. If the HTML API value + * getters (get_attribute(), class_list(), …) are ever changed to scrub + * invalid UTF-8 in their return values, both sides become U+FFFD and + * this case flips to a match — update this expectation in the same + * change. + * + * The selector byte (0xC1) is unique within this file on purpose: + * select() memoizes the most recently parsed selector string, so the + * scrub notice only fires when this test's selector was not already + * parsed by an earlier test. A unique selector string guarantees a + * fresh parse regardless of test order. + * + * @expectedIncorrectUsage WP_CSS_Compound_Selector_List::from_selectors + */ + public function test_select_scrubbed_selector_does_not_match_raw_invalid_document_bytes() { + $processor = new WP_HTML_Tag_Processor( "
" ); + $this->assertFalse( + $processor->select( ".a\xC1b" ), + 'Scrubbed selector should not match raw invalid bytes in the document.' + ); + } } From 74081b16926f1041c5f1a95f88fd39dd05cf8934 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 12:49:25 +0200 Subject: [PATCH 156/634] initial css fuzzer --- tools/css-selector-fuzz/FINDINGS.md | 114 +++ tools/css-selector-fuzz/NEXT-STEPS.md | 178 ++++ tools/css-selector-fuzz/README.md | 70 ++ tools/css-selector-fuzz/lib/AstExtractor.php | 149 +++ tools/css-selector-fuzz/lib/Bootstrap.php | 63 ++ .../lib/DocumentGenerator.php | 450 +++++++++ tools/css-selector-fuzz/lib/Prng.php | 65 ++ .../lib/ReferenceMatcher.php | 253 +++++ .../lib/SelectorGenerator.php | 899 ++++++++++++++++++ tools/css-selector-fuzz/lib/Worker.php | 589 ++++++++++++ tools/css-selector-fuzz/lib/autoload.php | 9 + tools/css-selector-fuzz/lib/util.php | 157 +++ tools/css-selector-fuzz/lib/wp-stubs.php | 62 ++ tools/css-selector-fuzz/replay.php | 91 ++ tools/css-selector-fuzz/runner.php | 267 ++++++ tools/css-selector-fuzz/tests/self-check.php | 131 +++ tools/css-selector-fuzz/worker.php | 34 + 17 files changed, 3581 insertions(+) create mode 100644 tools/css-selector-fuzz/FINDINGS.md create mode 100644 tools/css-selector-fuzz/NEXT-STEPS.md create mode 100644 tools/css-selector-fuzz/README.md create mode 100644 tools/css-selector-fuzz/lib/AstExtractor.php create mode 100644 tools/css-selector-fuzz/lib/Bootstrap.php create mode 100644 tools/css-selector-fuzz/lib/DocumentGenerator.php create mode 100644 tools/css-selector-fuzz/lib/Prng.php create mode 100644 tools/css-selector-fuzz/lib/ReferenceMatcher.php create mode 100644 tools/css-selector-fuzz/lib/SelectorGenerator.php create mode 100644 tools/css-selector-fuzz/lib/Worker.php create mode 100644 tools/css-selector-fuzz/lib/autoload.php create mode 100644 tools/css-selector-fuzz/lib/util.php create mode 100644 tools/css-selector-fuzz/lib/wp-stubs.php create mode 100644 tools/css-selector-fuzz/replay.php create mode 100644 tools/css-selector-fuzz/runner.php create mode 100644 tools/css-selector-fuzz/tests/self-check.php create mode 100644 tools/css-selector-fuzz/worker.php diff --git a/tools/css-selector-fuzz/FINDINGS.md b/tools/css-selector-fuzz/FINDINGS.md new file mode 100644 index 0000000000000..981b33ef41d80 --- /dev/null +++ b/tools/css-selector-fuzz/FINDINGS.md @@ -0,0 +1,114 @@ +# CSS Selector Fuzzer — Findings + +Run: branch `html-css-fuzz` @ `6ebbcc2fe4`, PHP 8.4.21. ~3600 deterministic +seeds, 0 crashes/timeouts. Three distinct, reproduced WordPress-core correctness +bugs in the new HTML-API CSS selector support. Every selector below is valid, +supported CSS that the API mis-handles **without** reporting lack of support. + +Reproduce any case: `php tools/css-selector-fuzz/replay.php --selector '' [--html '']`. + +--- + +## Bug 1 — Identity escapes mis-decode after a multibyte character (mis-parse) + +**Invariant:** `ast-mismatch` (57 hits, the dominant signature). + +`WP_CSS_Selector_Parser_Matcher::consume_escaped_codepoint()` decodes a +non-hex ("identity") escape with: + +```php +$codepoint_char = mb_substr( $input, $offset, 1, 'UTF-8' ); +``` + +`$offset` is a **byte** offset (threaded by reference through the whole +selector-string parse), but `mb_substr()`'s 2nd argument is a **character** +index. The two diverge by one per multibyte continuation byte seen earlier in +the string, so an identity escape preceded by any multibyte content decodes the +**wrong codepoint** (reads N characters too far right, N = preceding continuation bytes). + +Minimal reproduction (second selector's type should be `sup`): + +| selector | parsed context type | +|---|---| +| `#abc,\sup #x` | `sup` ✅ | +| `#Ü,\sup #x` | `uup` ❌ | +| `#ÜÜ,\sup #x` | `pup` ❌ | +| `#ÜÜÜ,\sup #x` | `" up"` ❌ | + +Hex escapes (`\75 `) use byte-correct `substr` and are unaffected; only the +non-hex identity-escape branch is wrong. Depending on what wrong codepoint is +produced this also causes spurious parse failures (a valid selector returns +`null`). + +**Fix direction:** read the next codepoint by byte offset, e.g. +`mb_substr( substr( $input, $offset ), 0, 1, 'UTF-8' )`, or decode the UTF-8 +lead byte length from `$input[$offset]` directly. + +--- + +## Bug 2 — Empty-value `^=` `*=` `$=` match everything instead of nothing (mis-match) + +**Invariant:** `match-mismatch-html` / `match-mismatch-tag` (12 hits). + +Per Selectors-4, `[attr^=""]`, `[attr*=""]`, `[attr$=""]` match **nothing** (an +empty operand never matches). `WP_CSS_Attribute_Selector::matches()` instead: + +- `^=`: `substr_compare($attr,'',0,0) === 0` → always 0 → matches any element with the attribute. +- `*=`: `strpos($attr,'') === 0` (PHP) → matches any element with the attribute. +- `$=`: matches elements whose attribute value is exactly `""`. + +`~=` is handled correctly (returns nothing for an empty/whitespace operand). + +Reproduction against `………`: + +| selector | WP matches | spec | +|---|---|---| +| `[x^=""]` | `I, B` | none | +| `[x*=""]` | `I, B` | none | +| `[x$=""]` | `I` | none | +| `[x~=""]` | none ✅ | none | + +**Fix direction:** in `matches()`, return `false` for `^= $= *=` (and `~=`) when +`'' === $this->value`, before the `substr_compare`/`strpos` calls. (This also +removes a `substr_compare` negative-length edge with very short attribute values.) + +--- + +## Bug 3 — Off-by-one length guard rejects `[name=x]` at end of string (false reject) + +**Invariant:** `parse-expectation` (1 hit; valid selector → `null`). + +`WP_CSS_Attribute_Selector::parse()` guards "need at least `=x]` remaining": + +```php +// need to match at least `=x]` at this point +if ( $updated_offset + 3 >= strlen( $input ) ) { + return null; +} +``` + +`>=` is off by one: it also rejects the exact-fit case where `=x]` **is** the +remaining tail. This rejects a valid attribute selector that uses the exact-match +`=` operator with a single-character **unquoted** value when its `]` is the last +character of the selector string. + +| selector | result | +|---|---| +| `[a=b]` | `null` ❌ | +| `div.x[y=z]` | `null` ❌ | +| `[a=bb]` | parsed ✅ (2-char value) | +| `[a="b"]` | parsed ✅ (quoted) | +| `[a^=b]` | parsed ✅ (2-char operator) | +| `[a=b].c` | parsed ✅ (trailing content) | + +**Fix direction:** change `>=` to `>` (need `strlen - $updated_offset >= 3`). + +--- + +## Fuzzer status + +Implemented and validated: deterministic seeds, seed-based replay, generative +6-bucket selector generation, independent reference matcher, ~18 invariants, +process-isolated runner, self-check suite. `php tools/css-selector-fuzz/tests/self-check.php` +passes; see `README.md` for usage. No fuzzer-side (oracle/generator) defects +surfaced in 3600 seeds — all failures are the three target bugs above. diff --git a/tools/css-selector-fuzz/NEXT-STEPS.md b/tools/css-selector-fuzz/NEXT-STEPS.md new file mode 100644 index 0000000000000..0b509450a177e --- /dev/null +++ b/tools/css-selector-fuzz/NEXT-STEPS.md @@ -0,0 +1,178 @@ +# CSS Selector Fuzzer — Next Steps / Improvement Roadmap + +Status: first-generation fuzzer is implemented, validated, and has found three +real WordPress-core bugs (see `FINDINGS.md`). Design and current coverage are in +`README.md`. This document is the prioritized plan to take it from "found three +bugs" to "exhaustive and trustworthy." Do NOT re-explain the existing tool here; +read `README.md` and `FINDINGS.md` first. + +Repo: `/Users/jonsurrell/a8c/wordpress-develop/html-css-fuzz`, branch +`html-css-fuzz` @ `6ebbcc2fe4` (trunk + merged `html-api/add-css-selector-parser`). +PHP 8.4.21. Everything under `tools/css-selector-fuzz/` is untracked; nothing +committed. `/artifacts` is gitignored (runner output lives there). + +## Measured weaknesses driving this plan + +- Match oracle is a hand-reimplementation (`ReferenceMatcher`) by the same author + who could share a spec misreading with WP — no third opinion exists today. +- Positive-match rate is low (measured): supported-compound 39.6% of parseable + cases match ≥1 element; supported-complex only **14.5%**; ~72% of all supported + cases match nothing. Most match assertions are vacuous `[] == []`. +- The "structurally safe element set" restriction (needed so `model == + parse-tree` holds) means combinator/breadcrumb matching is only ever tested on + clean trees — never on foster-parented / adoption-agency / foreign-content / + implied-end-tag restructured trees, which are the hard cases. +- No metamorphic invariants (the cheapest oracle-free signal class) — absent. +- Line coverage never measured. Some target branches are provably unreachable by + the current generator (e.g. `consume_escaped_codepoint`'s U+FFFD path for + null/surrogate/over-max codepoints; the `normalize_selector_input` NUL→U+FFFD + path). +- No automatic minimizer (the sibling `html-api-fuzz` branch ships + `tools/html-api-fuzz/minimize.php` as a pattern to copy). +- Match path only exercises `WP_HTML_Processor::create_full_parser`; fragment + contexts and varied quirks-mode triggers (only doctype presence is toggled) + are untested. + +## Work items, in priority order + +### 1. Metamorphic invariants (cheapest, highest signal-per-effort, no deps) + +Add oracle-free relations to `Worker::run_case` that must hold for any parseable +supported selector over any document. For each, transform the selector, assert +the match set (both processors) is unchanged — or for AST-level ones, assert the +extracted AST is unchanged: + +- ASCII-case-fold a type-selector name → identical matches (type names are + case-insensitive). +- Reorder subclass selectors within a compound (`div.a#b[c]` ≡ any permutation of + the subclass part) → identical matches and structurally-equivalent AST. +- Escape an arbitrary ident codepoint that does not require escaping → identical + AST and matches (exercises the escape decoder against the no-op case). +- Append a redundant universal (`sel` vs `sel:where`-free `*sel` where the type + slot is empty → `*` + subclasses) → identical matches. +- Duplicate a selector-list branch (`a, a`) → identical matches. +- Whitespace-insert around combinators and commas where insignificant → identical + matches. + +These need no external engine; they would have independently caught Bug 1. + +### 2. Path-directed generation (fix the 14.5% positive-match rate) + +Add a generation mode that GUARANTEES positive matches and meaningful negatives: + +- Pick a random element in the generated model tree. +- Synthesize a selector that must match it: type from its tag, subclasses from a + subset of its real classes/id/attributes, and (for complex) a context chain + drawn from its real ancestor tags with `>`/descendant combinators matching the + actual nesting. +- Emit the matching selector (assert it matches that element) AND near-miss + mutations (swap one ancestor combinator `>`↔descendant, drop/extend a class, + change one attribute operator) and assert the flip. + +This makes the combinator/breadcrumb walker actually exercised with real depth +and real positive/negative boundaries instead of mostly-empty match sets. Keep +the existing buckets; add this as a new bucket. + +### 3. lexbor differential oracle (the match-oracle correctness ceiling) + +Use lexbor as a THIRD, independent oracle — primarily to validate +`ReferenceMatcher`, secondarily to unlock wilder HTML. Build cost is acceptable +(confirmed by maintainer). Refs: https://lexbor.com/modules/selectors/ and the +HTML module for selector matching. + +Design: + +- C harness linking liblexbor: read many `{html, selector}` cases from stdin + (one process, batched — invoked by the runner like the existing PHP worker + subprocess; isolate crashes). Parse HTML with `lxb_html_document_parse`, parse + the selector with the CSS/selectors module, run `lxb_selectors_find`, and via + the callback collect each matched element's unique `data-fid` attribute. Emit + one line of matched-fid sets per case. FFI to `liblexbor.so` is an acceptable + alternative but a standalone CLI isolates crashes better. +- Mark every generated element with a unique `data-fid` (the generator already + does this). +- **Tree-equality gate:** only run the differential on cases where WP's tree and + lexbor's tree agree (compare the fid→tag→breadcrumb sequence from each). This + isolates the SELECTOR layer from HTML tree-construction differences (which are + a different fuzzer's concern — see `html-api-fuzz`). Bonus: this gate lets you + fuzz ARBITRARY/wild HTML and keep any case where the two trees agree, which + relaxes the current "safe element set" restriction and reaches restructured + trees the present generator can't produce. +- Three-way verdict: `reference ≠ lexbor` ⇒ fuzzer-oracle bug (fix the fuzzer); + `reference == lexbor ≠ WP` ⇒ high-confidence WP finding. + +**CRITICAL CAVEAT — quirks-mode / case-sensitivity:** lexbor has a known +class/ID case-sensitivity bug — https://github.com/lexbor/lexbor/issues/368. +WP folds class/ID names ASCII-case-insensitively in QUIRKS mode and +case-sensitively in no-quirks (`WP_HTML_Tag_Processor::is_quirks_mode()`); type +names are always case-insensitive. Do NOT trust lexbor on quirks-mode case +behavior. Restrict the lexbor differential to **no-quirks documents** (emit +``), and keep `ReferenceMatcher` as the authority for the +quirks-mode path. Pin the exact lexbor version used and note whether #368 is +fixed in it. Re-evaluate enabling quirks comparison only after verifying lexbor's +behavior against that issue. + +- Also surface (don't auto-fail) **attribute default case-insensitivity**: + Selectors-4/HTML define a set of attributes matched case-insensitively by + default; WP appears to implement only explicit `i`/`s` modifiers. lexbor may + implement the default set, producing divergence that is either a real WP + conformance gap or an intentional subset limitation — triage per case and + report. + +### 4. Parser-derived oracle tree (decouple "tree right" from "match right") + +Instead of asserting `model == parse-tree`, walk the processor ONCE to capture +the ground-truth tree (fid → tag → breadcrumbs → attributes), then run both the +reference matcher and the lexbor differential against arbitrary/wild HTML using +that captured tree as truth for the selector layer. This is the structural +change that makes #3's wild-HTML mode fully general and lets the generator reuse +`html-api-fuzz`'s nasty-HTML generator. (`model-desync` becomes a separate, +optional sanity check rather than a precondition.) + +### 5. Coverage measurement + reach the unreachable branches + +- Wire line/branch coverage (phpdbg is available: `phpdbg -qrr` with + coverage, or install pcov/xdebug) over the `src/wp-includes/html-api/css/` + classes; gate "done" on a coverage target and a written list of intentionally- + unreached lines. +- Add a generator path emitting raw hex escapes for null / surrogate + (U+D800–U+DFFF) / over-max (> U+10FFFF) codepoints and assert they decode to + U+FFFD (currently unreachable — the renderer only escapes real codepoints). +- Fuzz NUL bytes and CR/FF in the selector INPUT to exercise + `normalize_selector_input` (NUL→U+FFFD, CR/CRLF/FF→LF). + +### 6. Automatic minimizer + +Port the delta-debugging pattern from `tools/html-api-fuzz/minimize.php`: given a +failing seed, shrink both the HTML and the selector (byte/structural deletes, +keep-failing) to a minimal reproducer. Wire into `replay.php` or a new +`minimize.php`. Bugs 1 and 3 were hand-minimized; automate it. + +### 7. Broaden match surface + +- Run the match oracle through `create_fragment` with varied fragment contexts, + not just `create_full_parser`. +- Vary all quirks-mode triggers (not only doctype presence): no-doctype, + malformed doctype, ``, limited-quirks doctypes. + +## Acceptance bar for "exacting standards" + +- Coverage measured and reported for the `css/` classes, with a justified list of + any unreached lines. +- Three independent oracles agree on no-quirks supported cases (AST round-trip, + `ReferenceMatcher`, lexbor); divergences are triaged to either a WP finding or + a fuzzer-oracle fix — never left ambiguous. +- Metamorphic invariants in place and passing. +- Positive-match rate for combinator selectors materially raised (path-directed + generation); match assertions are mostly non-vacuous. +- Minimizer produces minimal repros automatically. +- A clean multi-thousand-seed run with all signatures triaged; `FINDINGS.md` + updated with any new bugs (each with a minimal repro and a one-line fix + direction), and confirmation that the three known bugs still reproduce. + +## Existing bugs to keep verifying (regression anchors) + +From `FINDINGS.md` — minimal repros, all must still trigger until core is fixed: +1. Identity escape after multibyte mis-decodes: `#Ü,\sup #x` → type `uup` (want `sup`). +2. Empty-value matchers match everything: `[x^=""]`, `[x*=""]`, `[x$=""]`. +3. Off-by-one length guard: `[a=b]` (single-char unquoted value, exact `=`, at EOF) → `null`. diff --git a/tools/css-selector-fuzz/README.md b/tools/css-selector-fuzz/README.md new file mode 100644 index 0000000000000..03c2c51d654f7 --- /dev/null +++ b/tools/css-selector-fuzz/README.md @@ -0,0 +1,70 @@ +# CSS Selector Fuzzer + +Generative fuzzer for the HTML API CSS selector support: +`WP_CSS_Compound_Selector_List`, `WP_CSS_Complex_Selector_List`, and the +`select()` methods on `WP_HTML_Tag_Processor` and `WP_HTML_Processor`. + +Every case is fully deterministic from its integer seed: the same seed always +produces the same document, the same selector, and the same verdict. + +## What a case does + +1. Generate a random HTML document from a structurally "safe" element set so + the model tree is provably identical to the parsed tree (this is itself + verified every case — `model-desync`). +2. Generate a selector in one of six buckets: + - `supported-compound` — must parse in both grammars; carries intended AST. + - `supported-complex` — uses `>`/descendant combinators; must parse only + in the complex grammar; carries intended AST. + - `unsupported` — valid CSS the API intentionally rejects (pseudo-classes + and -elements, `+`/`~`/`||` combinators, namespaces, non-type context + selectors); must not parse. + - `invalid` — not valid CSS; must not parse. + - `chaos` — arbitrary bytes; no parse expectation. + - `mutated` — a supported selector with random byte mutations; no parse + expectation. +3. Check invariants: + - No PHP error/warning/exception from parsing or matching, ever. + - Parse result (instance vs `null`) matches the bucket's expectation. + - Anything the compound grammar parses, the complex grammar parses, and + both produce the same AST. + - Parsed AST equals the generated AST (escapes, strings, whitespace and + case randomization must not change meaning). + - For any selector that parses (including chaos/mutated), the `select()` + match set equals an independent spec-faithful reference matcher, on both + processors, including quirks-mode class/ID case-insensitivity. + - For any selector that does not parse, `select()` returns `false`, + `_doing_it_wrong` fires exactly once per call (also via the parse + cache), and the processor remains usable. + - The processor ends with no `get_last_error()`/unsupported state. + - Repeating a case yields a byte-identical result digest (determinism). + +## Usage + +Bounded fuzz run (process-isolated chunks, crash/hang attribution): + + php tools/css-selector-fuzz/runner.php --max-seeds 1000 --duration-seconds 60 + +Artifacts go to `artifacts/css-selector-fuzz/run-*/` and are intentionally +small: `state.json` (counters, per-signature tallies) and `failures.ndjson` +(one line per failure, with base64 selector + document for offline analysis). + +Replay a failure by seed: + + php tools/css-selector-fuzz/replay.php --seed 42 --show-html + php tools/css-selector-fuzz/replay.php --seed 42 --json + +Probe a specific selector: + + php tools/css-selector-fuzz/replay.php --selector 'section > div.cls' --html '
' + +Run a batch in-process (no isolation, faster): + + php tools/css-selector-fuzz/worker.php --start-seed 1 --count 500 + +Options of note: + +- `runner.php --stop-on-failure` stops at the first failing chunk. +- `worker.php --determinism-every N` re-runs every Nth seed twice (default 16). +- `worker.php --max-failures N` stops a batch after N failures (default 200) + to bound artifact size. diff --git a/tools/css-selector-fuzz/lib/AstExtractor.php b/tools/css-selector-fuzz/lib/AstExtractor.php new file mode 100644 index 0000000000000..ed81beac30c3e --- /dev/null +++ b/tools/css-selector-fuzz/lib/AstExtractor.php @@ -0,0 +1,149 @@ + array(), + 'self' => self::from_compound( $selector ), + ); + } + return $out; + } + + private static function from_complex( \WP_CSS_Complex_Selector $selector ): array { + $context = array(); + foreach ( (array) $selector->context_selectors as $pair ) { + if ( ! is_array( $pair ) || 2 !== count( $pair ) ) { + throw new \UnexpectedValueException( 'Context selector pair has unexpected shape.' ); + } + if ( ! $pair[0] instanceof \WP_CSS_Type_Selector ) { + throw new \UnexpectedValueException( 'Context selector is not a type selector: ' . self::describe( $pair[0] ) ); + } + if ( ! in_array( $pair[1], array( ' ', '>' ), true ) ) { + throw new \UnexpectedValueException( 'Context selector uses unsupported combinator: ' . var_export( $pair[1], true ) ); + } + $context[] = array( $pair[0]->type, $pair[1] ); + } + + return array( + 'context' => $context, + 'self' => self::from_compound( $selector->self_selector ), + ); + } + + private static function from_compound( \WP_CSS_Compound_Selector $selector ): array { + $subs = null; + if ( null !== $selector->subclass_selectors ) { + if ( array() === $selector->subclass_selectors ) { + throw new \UnexpectedValueException( 'Compound selector has empty (non-null) subclass selector array.' ); + } + $subs = array(); + foreach ( $selector->subclass_selectors as $sub ) { + $subs[] = self::from_subclass( $sub ); + } + } + + if ( null === $selector->type_selector && null === $subs ) { + throw new \UnexpectedValueException( 'Compound selector has neither type nor subclass selectors.' ); + } + + return array( + 'type' => null === $selector->type_selector ? null : $selector->type_selector->type, + 'subs' => $subs, + ); + } + + private static function from_subclass( $sub ): array { + if ( $sub instanceof \WP_CSS_Class_Selector ) { + return array( + 'kind' => 'class', + 'name' => $sub->class_name, + ); + } + if ( $sub instanceof \WP_CSS_ID_Selector ) { + return array( + 'kind' => 'id', + 'name' => $sub->id, + ); + } + if ( $sub instanceof \WP_CSS_Attribute_Selector ) { + $valid_matchers = array( + null, + \WP_CSS_Attribute_Selector::MATCH_EXACT, + \WP_CSS_Attribute_Selector::MATCH_ONE_OF_EXACT, + \WP_CSS_Attribute_Selector::MATCH_EXACT_OR_HYPHEN_SUFFIXED, + \WP_CSS_Attribute_Selector::MATCH_PREFIXED_BY, + \WP_CSS_Attribute_Selector::MATCH_SUFFIXED_BY, + \WP_CSS_Attribute_Selector::MATCH_CONTAINS, + ); + if ( ! in_array( $sub->matcher, $valid_matchers, true ) ) { + throw new \UnexpectedValueException( 'Attribute selector has unknown matcher: ' . var_export( $sub->matcher, true ) ); + } + $valid_modifiers = array( + null, + \WP_CSS_Attribute_Selector::MODIFIER_CASE_SENSITIVE, + \WP_CSS_Attribute_Selector::MODIFIER_CASE_INSENSITIVE, + ); + if ( ! in_array( $sub->modifier, $valid_modifiers, true ) ) { + throw new \UnexpectedValueException( 'Attribute selector has unknown modifier: ' . var_export( $sub->modifier, true ) ); + } + if ( ( null === $sub->matcher ) !== ( null === $sub->value ) ) { + throw new \UnexpectedValueException( 'Attribute selector matcher/value nullness mismatch.' ); + } + return array( + 'kind' => 'attr', + 'name' => $sub->name, + 'matcher' => $sub->matcher, + 'value' => $sub->value, + 'modifier' => $sub->modifier, + ); + } + throw new \UnexpectedValueException( 'Unknown subclass selector: ' . self::describe( $sub ) ); + } + + private static function get_private( $object, string $property, string $declaring_class ) { + $reflection = new \ReflectionProperty( $declaring_class, $property ); + $reflection->setAccessible( true ); + $value = $reflection->getValue( $object ); + if ( ! is_array( $value ) ) { + throw new \UnexpectedValueException( "Property {$property} is not an array." ); + } + return $value; + } + + private static function describe( $value ): string { + return is_object( $value ) ? get_class( $value ) : gettype( $value ); + } +} diff --git a/tools/css-selector-fuzz/lib/Bootstrap.php b/tools/css-selector-fuzz/lib/Bootstrap.php new file mode 100644 index 0000000000000..6d33b4de7c4e9 --- /dev/null +++ b/tools/css-selector-fuzz/lib/Bootstrap.php @@ -0,0 +1,63 @@ + */ + public static function doing_it_wrong_calls(): array { + return $GLOBALS['css_selector_fuzz_doing_it_wrong']; + } +} diff --git a/tools/css-selector-fuzz/lib/DocumentGenerator.php b/tools/css-selector-fuzz/lib/DocumentGenerator.php new file mode 100644 index 0000000000000..70e3ab80d2a39 --- /dev/null +++ b/tools/css-selector-fuzz/lib/DocumentGenerator.php @@ -0,0 +1,450 @@ +prng = $prng; + $this->max_elements = $max_elements; + $this->pools = array( + 'tags' => array(), + 'classes' => array(), + 'ids' => array(), + 'attrNames' => array(), + 'attrValues' => array(), + ); + } + + /** + * @return array{model: array, html: string, quirks: bool, pools: array} + */ + public static function generate( Prng $prng ): array { + $generator = new self( $prng, $prng->int( 8, 40 ) ); + return $generator->build(); + } + + private function build(): array { + $has_doctype = $this->prng->chance( 85 ); + + $head_children = array(); + if ( $this->prng->chance( 60 ) ) { + $head_children[] = $this->make_element( 'title', array(), array() ); + } + if ( $this->prng->chance( 30 ) ) { + $head_children[] = $this->make_element( 'meta', $this->random_attrs(), array() ); + } + + $body_children = array(); + $child_budget = $this->prng->int( 1, 6 ); + for ( $i = 0; $i < $child_budget && $this->element_count < $this->max_elements; $i++ ) { + $body_children[] = $this->random_subtree( 0 ); + } + + $head = $this->make_element( 'head', array(), $head_children ); + $body = $this->make_element( 'body', $this->prng->chance( 30 ) ? $this->random_attrs() : array(), $body_children ); + $html = $this->make_element( 'html', $this->prng->chance( 20 ) ? $this->random_attrs() : array(), array( $head, $body ) ); + + $rendered = ( $has_doctype ? '' : '' ) . $this->render_element( $html ); + + foreach ( $this->pools as $key => $values ) { + $this->pools[ $key ] = array_values( array_unique( $values ) ); + } + + return array( + 'model' => $html, + 'html' => $rendered, + 'quirks' => ! $has_doctype, + 'pools' => $this->pools, + ); + } + + private function random_subtree( int $depth ): array { + ++$this->element_count; + + if ( $depth >= 7 || $this->element_count >= $this->max_elements || $this->prng->chance( 25 ) ) { + // Leaf. + if ( $this->prng->chance( 25 ) ) { + return $this->make_element( $this->prng->choice( self::VOID_TAGS ), $this->random_attrs(), array(), true ); + } + return $this->make_element( $this->prng->choice( self::SAFE_TAGS ), $this->random_attrs(), array() ); + } + + $children = array(); + $child_count = $this->prng->int( 1, 4 ); + for ( $i = 0; $i < $child_count && $this->element_count < $this->max_elements; $i++ ) { + $children[] = $this->random_subtree( $depth + 1 ); + } + + return $this->make_element( $this->prng->choice( self::SAFE_TAGS ), $this->random_attrs(), $children ); + } + + private function make_element( string $tag, array $attrs, array $children, bool $is_void = false ): array { + $fid = 'e' . $this->fid_counter++; + + $written_tag = $this->prng->chance( 15 ) ? $this->random_case( $tag ) : $tag; + + $this->pools['tags'][] = $tag; + + return array( + 'tag' => $written_tag, + 'fid' => $fid, + 'attrs' => $attrs, + 'children' => $children, + 'void' => $is_void || in_array( strtolower( $tag ), array( 'meta', 'br', 'hr', 'img', 'wbr', 'input', 'embed' ), true ), + ); + } + + /** @return array name/value pairs in source order. */ + private function random_attrs(): array { + $attrs = array(); + $count = $this->prng->weighted( + array( + 0 => 15, + 1 => 30, + 2 => 30, + 3 => 15, + 4 => 10, + ) + ); + + $used_names = array(); + for ( $i = 0; $i < $count; $i++ ) { + $name = $this->prng->choice( self::ATTR_NAMES ); + + // Occasionally repeat an attribute name: the processor keeps the first. + $is_duplicate = isset( $used_names[ ascii_strtolower( $name ) ] ); + if ( $is_duplicate && ! $this->prng->chance( 20 ) ) { + continue; + } + $used_names[ ascii_strtolower( $name ) ] = true; + + if ( $this->prng->chance( 12 ) ) { + $name = $this->random_case( $name ); + } + + $lower = ascii_strtolower( $name ); + if ( 'class' === $lower ) { + $value = $this->random_class_value(); + } elseif ( 'id' === $lower ) { + $value = $this->prng->chance( 85 ) ? $this->random_id_value() : ( $this->prng->chance( 50 ) ? '' : true ); + } elseif ( in_array( $lower, array( 'disabled', 'hidden' ), true ) ) { + $value = $this->prng->chance( 70 ) ? true : $this->prng->choice( array( '', 'disabled', 'true' ) ); + } else { + $value = $this->prng->chance( 12 ) ? true : $this->random_attr_value(); + } + + $this->pools['attrNames'][] = ascii_strtolower( $name ); + if ( is_string( $value ) ) { + $this->pools['attrValues'][] = $value; + } + + $attrs[] = array( $name, $value ); + } + + return $attrs; + } + + private function random_class_value(): string { + $count = $this->prng->int( 1, 4 ); + $classes = array(); + for ( $i = 0; $i < $count; $i++ ) { + $class = $this->random_word( true ); + $classes[] = $class; + $this->pools['classes'][] = $class; + } + + $ws = array( ' ', ' ', ' ', "\t", "\n", "\f", ' ' ); + $value = $this->prng->chance( 20 ) ? $this->prng->choice( $ws ) : ''; + foreach ( $classes as $i => $class ) { + if ( $i > 0 ) { + $value .= $this->prng->choice( $ws ); + } + $value .= $class; + } + if ( $this->prng->chance( 20 ) ) { + $value .= $this->prng->choice( $ws ); + } + return $value; + } + + private function random_id_value(): string { + $id = $this->random_word( true ); + $this->pools['ids'][] = $id; + return $id; + } + + private function random_attr_value(): string { + $kind = $this->prng->weighted( + array( + 'word' => 35, + 'words' => 20, + 'hyphenated' => 15, + 'empty' => 8, + 'spicy' => 12, + 'unicode' => 10, + ) + ); + + switch ( $kind ) { + case 'word': + return $this->random_word( true ); + case 'words': + $parts = array(); + $n = $this->prng->int( 2, 4 ); + for ( $i = 0; $i < $n; $i++ ) { + $parts[] = $this->random_word( true ); + } + return implode( $this->prng->choice( array( ' ', ' ', "\t", "\n" ) ), $parts ); + case 'hyphenated': + return $this->random_word( false ) . '-' . $this->random_word( false ); + case 'empty': + return ''; + case 'spicy': + $spice = array( 'a"b', "a'b", 'a&b', 'ab', 'a=b', 'a b c', '&', '"x', '100%', 'semi;colon', 'a,b' ); + return $this->prng->choice( $spice ); + case 'unicode': + $unicode = array( 'héllo', 'ÄÖÜ', '✓done', 'naïve', 'Ωmega', '\u{1F600}smile' ); + $value = $this->prng->choice( $unicode ); + return str_replace( '\u{1F600}', "\u{1F600}", $value ); + } + return 'fallback'; + } + + private function random_word( bool $allow_mixed_case ): string { + $stems = array( 'alpha', 'beta', 'gamma', 'delta', 'box', 'col', 'item', 'note', 'wide', 'main-item', 'x', 'a', '-lead', '--var', '_under', 'Über', 'mixedCase' ); + $word = $this->prng->choice( $stems ); + if ( $this->prng->chance( 30 ) ) { + $word .= (string) $this->prng->int( 0, 99 ); + } + if ( $allow_mixed_case && $this->prng->chance( 15 ) ) { + $word = $this->random_case( $word ); + } + return $word; + } + + private function random_case( string $input ): string { + $out = ''; + for ( $i = 0; $i < strlen( $input ); $i++ ) { + $c = $input[ $i ]; + $out .= $this->prng->chance( 50 ) ? strtoupper( $c ) : strtolower( $c ); + } + return $out; + } + + /* + * --------- + * Rendering + * --------- + */ + + private function render_element( array $element ): string { + $out = '<' . $element['tag']; + + $rendered_attrs = array( ' data-fid="' . $element['fid'] . '"' ); + foreach ( $element['attrs'] as $attr ) { + $rendered_attrs[] = ' ' . $this->render_attr( $attr[0], $attr[1] ); + } + $out .= implode( '', $rendered_attrs ); + + if ( $element['void'] ) { + $out .= $this->prng->chance( 25 ) ? ' />' : '>'; + return $out; + } + + $out .= '>'; + + $child_bits = array(); + foreach ( $element['children'] as $child ) { + $child_bits[] = $this->render_element( $child ); + } + + /* + * Sprinkle text and comments between children — but never directly + * inside `html` or `head`, where character tokens would trigger + * insertion-mode changes (early body creation, head popping) that + * desynchronize the model from the parsed tree. + */ + $lower_tag = strtolower( $element['tag'] ); + $may_have_filler = ! in_array( $lower_tag, array( 'html', 'head' ), true ); + $filler_options = array( + '', + 'text', + ' more text ', + "\n ", + '& <escaped>', + '', + 'café ✓', + ); + $content = ''; + foreach ( $child_bits as $bit ) { + if ( $may_have_filler && $this->prng->chance( 40 ) ) { + $content .= $this->prng->choice( $filler_options ); + } + $content .= $bit; + } + if ( $may_have_filler && $this->prng->chance( 40 ) ) { + $content .= $this->prng->choice( $filler_options ); + } + if ( 'title' === $lower_tag ) { + // RAWTEXT: keep it plain. + $content = $this->prng->chance( 60 ) ? 'Fuzz Title' : ''; + } + + return $out . $content . ''; + } + + /** @param string|true $value */ + private function render_attr( string $name, $value ): string { + if ( true === $value ) { + return $name; + } + + $style = $this->prng->weighted( + array( + 'double' => 60, + 'single' => 20, + 'unquoted' => 20, + ) + ); + + if ( 'unquoted' === $style && ( '' === $value || strlen( $value ) !== strspn( $value, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789._:-' ) ) ) { + $style = 'double'; + } + + switch ( $style ) { + case 'unquoted': + return $name . '=' . $value; + case 'single': + return $name . "='" . str_replace( array( '&', "'", '<' ), array( '&', ''', '<' ), $value ) . "'"; + default: + return $name . '="' . str_replace( array( '&', '"', '<' ), array( '&', '"', '<' ), $value ) . '"'; + } + } + + /* + * ---------------- + * Model utilities + * ---------------- + */ + + /** Pre-order (document order) list of elements. */ + public static function flatten( array $element ): array { + $out = array( $element ); + foreach ( $element['children'] as $child ) { + foreach ( self::flatten( $child ) as $descendant ) { + $out[] = $descendant; + } + } + return $out; + } + + /** + * Pre-order list of ( element, ancestors ) pairs where ancestors is the + * chain from nearest ancestor to root — the same orientation as + * WP_HTML_Processor::get_breadcrumbs() reversed past self. + */ + public static function flatten_with_ancestors( array $element, array $ancestors = array() ): array { + $out = array( array( $element, $ancestors ) ); + $next_ancestors = array_merge( array( $element ), $ancestors ); + foreach ( $element['children'] as $child ) { + foreach ( self::flatten_with_ancestors( $child, $next_ancestors ) as $pair ) { + $out[] = $pair; + } + } + return $out; + } + + /** First attribute value for a name, ASCII case-insensitive; null if absent. */ + public static function get_attribute_value( array $element, string $name ) { + $comparable = ascii_strtolower( $name ); + foreach ( $element['attrs'] as $attr ) { + if ( ascii_strtolower( $attr[0] ) === $comparable ) { + return $attr[1]; + } + } + return null; + } +} diff --git a/tools/css-selector-fuzz/lib/Prng.php b/tools/css-selector-fuzz/lib/Prng.php new file mode 100644 index 0000000000000..b8d8737304277 --- /dev/null +++ b/tools/css-selector-fuzz/lib/Prng.php @@ -0,0 +1,65 @@ +key = $seed . "\x1f" . $label; + } + + /** Derives an independent child stream; consuming it does not affect this stream. */ + public function fork( string $label ): Prng { + return new Prng( $this->key, $label . ':' . $this->uint32() ); + } + + public function bytes( int $length ): string { + while ( strlen( $this->buffer ) < $length ) { + $this->buffer .= hash( 'sha256', $this->key . ':' . $this->counter++, true ); + } + $out = substr( $this->buffer, 0, $length ); + $this->buffer = substr( $this->buffer, $length ); + return $out; + } + + public function uint32(): int { + $parts = unpack( 'Nvalue', $this->bytes( 4 ) ); + return (int) $parts['value']; + } + + public function int( int $min, int $max ): int { + if ( $max <= $min ) { + return $min; + } + return $min + ( $this->uint32() % ( $max - $min + 1 ) ); + } + + public function chance( int $numerator, int $denominator = 100 ): bool { + return $this->int( 1, $denominator ) <= $numerator; + } + + public function choice( array $values ) { + return $values[ $this->int( 0, count( $values ) - 1 ) ]; + } + + /** @param array $weights value => weight */ + public function weighted( array $weights ) { + $total = array_sum( $weights ); + $pick = $this->int( 1, max( 1, (int) $total ) ); + foreach ( $weights as $value => $weight ) { + $pick -= $weight; + if ( $pick <= 0 ) { + return $value; + } + } + return array_key_first( $weights ); + } +} diff --git a/tools/css-selector-fuzz/lib/ReferenceMatcher.php b/tools/css-selector-fuzz/lib/ReferenceMatcher.php new file mode 100644 index 0000000000000..fd834a543041d --- /dev/null +++ b/tools/css-selector-fuzz/lib/ReferenceMatcher.php @@ -0,0 +1,253 @@ +' === $combinator ) { + return self::type_matches( $type, $ancestor_tags[0] ) + && self::explore_context( $rest, array_slice( $ancestor_tags, 1 ) ); + } + + // Descendant: try every matching ancestor. + $count = count( $ancestor_tags ); + for ( $i = 0; $i < $count; $i++ ) { + if ( + self::type_matches( $type, $ancestor_tags[ $i ] ) && + self::explore_context( $rest, array_slice( $ancestor_tags, $i + 1 ) ) + ) { + return true; + } + } + return false; + } + + public static function compound_matches( array $compound, array $element, bool $quirks ): bool { + if ( null !== $compound['type'] && ! self::type_matches( $compound['type'], $element['tag'] ) ) { + return false; + } + foreach ( (array) $compound['subs'] as $sub ) { + if ( ! self::sub_matches( $sub, $element, $quirks ) ) { + return false; + } + } + return true; + } + + private static function type_matches( string $type, string $tag ): bool { + return '*' === $type || ascii_strtolower( $type ) === ascii_strtolower( $tag ); + } + + private static function sub_matches( array $sub, array $element, bool $quirks ): bool { + switch ( $sub['kind'] ) { + case 'class': + return self::class_matches( $sub['name'], $element, $quirks ); + case 'id': + return self::id_matches( $sub['name'], $element, $quirks ); + case 'attr': + return self::attr_matches( $sub, $element ); + } + return false; + } + + private static function class_matches( string $wanted, array $element, bool $quirks ): bool { + $class_value = DocumentGenerator::get_attribute_value( $element, 'class' ); + if ( ! is_string( $class_value ) ) { + return false; + } + + $length = strlen( $class_value ); + $at = 0; + while ( $at < $length ) { + $at += strspn( $class_value, self::WHITESPACE, $at ); + if ( $at >= $length ) { + break; + } + $word_length = strcspn( $class_value, self::WHITESPACE, $at ); + $word = substr( $class_value, $at, $word_length ); + $at += $word_length; + + if ( + $quirks + ? ascii_strtolower( $word ) === ascii_strtolower( $wanted ) + : $word === $wanted + ) { + return true; + } + } + return false; + } + + private static function id_matches( string $wanted, array $element, bool $quirks ): bool { + $id = DocumentGenerator::get_attribute_value( $element, 'id' ); + if ( ! is_string( $id ) ) { + return false; + } + return $quirks + ? ascii_strtolower( $id ) === ascii_strtolower( $wanted ) + : $id === $wanted; + } + + private static function attr_matches( array $sub, array $element ): bool { + $attr_value = DocumentGenerator::get_attribute_value( $element, $sub['name'] ); + if ( null === $attr_value ) { + return false; + } + if ( null === $sub['matcher'] ) { + return true; + } + if ( true === $attr_value ) { + $attr_value = ''; + } + + $wanted = (string) $sub['value']; + $case_insensitive = 'case-insensitive' === $sub['modifier']; + if ( $case_insensitive ) { + $attr_value = ascii_strtolower( $attr_value ); + $wanted = ascii_strtolower( $wanted ); + } + + switch ( $sub['matcher'] ) { + case 'exact': + return $attr_value === $wanted; + + case 'one-of': + if ( '' === $wanted || strlen( $wanted ) !== strcspn( $wanted, self::WHITESPACE ) ) { + return false; + } + $length = strlen( $attr_value ); + $at = 0; + while ( $at < $length ) { + $at += strspn( $attr_value, self::WHITESPACE, $at ); + if ( $at >= $length ) { + break; + } + $word_length = strcspn( $attr_value, self::WHITESPACE, $at ); + if ( substr( $attr_value, $at, $word_length ) === $wanted ) { + return true; + } + $at += $word_length; + } + return false; + + case 'exact-or-hyphen-suffixed': + if ( $attr_value === $wanted ) { + return true; + } + return 0 === strncmp( $attr_value, $wanted . '-', strlen( $wanted ) + 1 ); + + case 'prefixed': + if ( '' === $wanted ) { + return false; + } + return 0 === strncmp( $attr_value, $wanted, strlen( $wanted ) ); + + case 'suffixed': + if ( '' === $wanted ) { + return false; + } + return strlen( $attr_value ) >= strlen( $wanted ) + && substr( $attr_value, -strlen( $wanted ) ) === $wanted; + + case 'contains': + if ( '' === $wanted ) { + return false; + } + return false !== strpos( $attr_value, $wanted ); + } + + return false; + } +} diff --git a/tools/css-selector-fuzz/lib/SelectorGenerator.php b/tools/css-selector-fuzz/lib/SelectorGenerator.php new file mode 100644 index 0000000000000..53347c083e79b --- /dev/null +++ b/tools/css-selector-fuzz/lib/SelectorGenerator.php @@ -0,0 +1,899 @@ +prng = $prng; + $this->pools = $pools; + } + + /** + * @param array $pools Pools from DocumentGenerator ( tags, classes, ids, attrNames, attrValues ). + * @return array{ + * bucket: string, + * selector: string, + * expectCompound: bool|null, + * expectComplex: bool|null, + * ast: array|null, + * } + */ + public static function generate( Prng $prng, array $pools, ?string $bucket = null ): array { + $generator = new self( $prng, $pools ); + + if ( null === $bucket ) { + $bucket = $prng->weighted( + array( + 'supported-compound' => 30, + 'supported-complex' => 25, + 'unsupported' => 15, + 'invalid' => 12, + 'chaos' => 8, + 'mutated' => 10, + ) + ); + } + + switch ( $bucket ) { + case 'supported-compound': + $ast = $generator->gen_complex_list( false ); + return array( + 'bucket' => $bucket, + 'selector' => $generator->render_complex_list( $ast ), + 'expectCompound' => true, + 'expectComplex' => true, + 'ast' => $ast, + ); + + case 'supported-complex': + $ast = $generator->gen_complex_list( true ); + return array( + 'bucket' => $bucket, + 'selector' => $generator->render_complex_list( $ast ), + 'expectCompound' => false, + 'expectComplex' => true, + 'ast' => $ast, + ); + + case 'unsupported': + return array( + 'bucket' => $bucket, + 'selector' => $generator->gen_unsupported(), + 'expectCompound' => false, + 'expectComplex' => false, + 'ast' => null, + ); + + case 'invalid': + return array( + 'bucket' => $bucket, + 'selector' => $generator->gen_invalid(), + 'expectCompound' => false, + 'expectComplex' => false, + 'ast' => null, + ); + + case 'chaos': + return array( + 'bucket' => $bucket, + 'selector' => $generator->gen_chaos(), + 'expectCompound' => null, + 'expectComplex' => null, + 'ast' => null, + ); + + case 'mutated': + default: + $ast = $generator->gen_complex_list( $generator->prng->chance( 50 ) ); + $rendered = $generator->render_complex_list( $ast ); + return array( + 'bucket' => 'mutated', + 'selector' => $generator->mutate( $rendered ), + 'expectCompound' => null, + 'expectComplex' => null, + 'ast' => null, + ); + } + } + + /* + * -------------- + * AST generation + * -------------- + * + * Canonical AST shapes (matching what AstExtractor produces from + * parsed WP_CSS_* objects): + * + * list: array of complex + * complex: array( 'context' => array( array( type, combinator ) ... right-to-left ), 'self' => compound ) + * compound: array( 'type' => string|null, 'subs' => array|null ) + * sub: array( 'kind' => 'class'|'id', 'name' => string ) + * | array( 'kind' => 'attr', 'name' => string, 'matcher' => string|null, + * 'value' => string|null, 'modifier' => string|null ) + */ + + private function gen_complex_list( bool $require_combinator ): array { + $count = $this->prng->weighted( + array( + 1 => 55, + 2 => 30, + 3 => 15, + ) + ); + + $list = array(); + $combinator_at = $require_combinator ? $this->prng->int( 0, $count - 1 ) : -1; + for ( $i = 0; $i < $count; $i++ ) { + $wants_combinators = $i === $combinator_at || ( $require_combinator && $this->prng->chance( 30 ) ); + $list[] = $this->gen_complex( $require_combinator ? $wants_combinators : false ); + } + return $list; + } + + private function gen_complex( bool $with_combinators ): array { + $context = array(); + if ( $with_combinators ) { + $context_count = $this->prng->int( 1, 3 ); + for ( $i = 0; $i < $context_count; $i++ ) { + $context[] = array( + $this->gen_type_name( true ), + $this->prng->chance( 50 ) ? ' ' : '>', + ); + } + } + + return array( + 'context' => $context, + 'self' => $this->gen_compound(), + ); + } + + private function gen_compound(): array { + $has_type = $this->prng->chance( 65 ); + $sub_count = $this->prng->weighted( + array( + 0 => 30, + 1 => 40, + 2 => 20, + 3 => 10, + ) + ); + if ( ! $has_type && 0 === $sub_count ) { + if ( $this->prng->chance( 50 ) ) { + $has_type = true; + } else { + $sub_count = 1; + } + } + + $subs = array(); + for ( $i = 0; $i < $sub_count; $i++ ) { + $subs[] = $this->gen_subclass(); + } + + return array( + 'type' => $has_type ? $this->gen_type_name( false ) : null, + 'subs' => array() === $subs ? null : $subs, + ); + } + + private function gen_type_name( bool $for_context ): string { + if ( $this->prng->chance( $for_context ? 25 : 12 ) ) { + return '*'; + } + $pool = $this->pools['tags'] ?? array(); + if ( array() !== $pool && $this->prng->chance( 70 ) ) { + $name = $this->prng->choice( $pool ); + return $this->prng->chance( 25 ) ? $this->random_case( $name ) : $name; + } + return $this->prng->choice( array( 'video', 'table', 'x-absent', 'object', 'span' ) ); + } + + private function gen_subclass(): array { + $kind = $this->prng->weighted( + array( + 'class' => 40, + 'id' => 25, + 'attr' => 35, + ) + ); + + switch ( $kind ) { + case 'class': + return array( + 'kind' => 'class', + 'name' => $this->pick_name( 'classes' ), + ); + case 'id': + return array( + 'kind' => 'id', + 'name' => $this->pick_name( 'ids' ), + ); + default: + return $this->gen_attr_selector(); + } + } + + private function gen_attr_selector(): array { + $name = $this->pick_name( 'attrNames' ); + + $matcher = $this->prng->weighted( + array( + '' => 25, + 'exact' => 20, + 'one-of' => 12, + 'exact-or-hyphen-suffixed' => 11, + 'prefixed' => 11, + 'suffixed' => 11, + 'contains' => 10, + ) + ); + $matcher = '' === $matcher ? null : $matcher; + + if ( null === $matcher ) { + return array( + 'kind' => 'attr', + 'name' => $name, + 'matcher' => null, + 'value' => null, + 'modifier' => null, + ); + } + + $modifier = $this->prng->weighted( + array( + '' => 70, + 'case-insensitive' => 18, + 'case-sensitive' => 12, + ) + ); + + return array( + 'kind' => 'attr', + 'name' => $name, + 'matcher' => $matcher, + 'value' => $this->gen_attr_value(), + 'modifier' => '' === $modifier ? null : $modifier, + ); + } + + private function gen_attr_value(): string { + $pool = $this->pools['attrValues'] ?? array(); + + $kind = $this->prng->weighted( + array( + 'pool' => 35, + 'pool-part' => 20, + 'pool-case' => 10, + 'empty' => 10, + 'word' => 15, + 'tricky' => 10, + ) + ); + + if ( in_array( $kind, array( 'pool', 'pool-part', 'pool-case' ), true ) && array() === $pool ) { + $kind = 'word'; + } + + switch ( $kind ) { + case 'pool': + return $this->prng->choice( $pool ); + + case 'pool-part': + $value = $this->prng->choice( $pool ); + if ( '' === $value ) { + return ''; + } + $points = utf8_codepoints( $value ); + $total = count( $points ); + $start = $this->prng->int( 0, max( 0, $total - 1 ) ); + $length = $this->prng->int( 1, $total - $start ); + $part = ''; + for ( $i = $start; $i < $start + $length; $i++ ) { + $part .= $points[ $i ][0]; + } + return $part; + + case 'pool-case': + return $this->random_case( $this->prng->choice( $pool ) ); + + case 'empty': + return ''; + + case 'word': + return $this->prng->choice( array( 'alpha', 'beta9', 'value', 'main-item', 'Z', 'i', 's', 'one two', 'x-y-z' ) ); + + case 'tricky': + default: + return $this->prng->choice( + array( + 'a b', + " lead", + "trail ", + "tab\there", + "line\nbreak", + 'quote"inside', + "apos'inside", + 'back\\slash', + '-', + '--', + '0digit', + 'ünïcode', + ) + ); + } + } + + private function pick_name( string $pool_key ): string { + $pool = $this->pools[ $pool_key ] ?? array(); + if ( array() !== $pool && $this->prng->chance( 65 ) ) { + $name = $this->prng->choice( $pool ); + if ( '' !== $name && $this->prng->chance( 20 ) ) { + $name = $this->random_case( $name ); + } + if ( '' !== $name ) { + return $name; + } + } + return $this->prng->choice( + array( + 'absent', + 'no-such-thing', + 'x', + '-lead', + '--double', + '_under', + 'Ünïcode', + 'with space', + '9starts-with-digit', + '-9hyphen-digit', + 'mixedCase', + ) + ); + } + + /* + * --------- + * Rendering + * --------- + */ + + private function render_complex_list( array $list ): string { + $bits = array(); + foreach ( $list as $complex ) { + $bits[] = $this->render_complex( $complex ); + } + + $out = $this->maybe_ws( 25 ); + foreach ( $bits as $i => $bit ) { + if ( $i > 0 ) { + $out .= $this->maybe_ws( 40 ) . ',' . $this->maybe_ws( 60 ); + } + $out .= $bit; + } + return $out . $this->maybe_ws( 25 ); + } + + private function render_complex( array $complex ): string { + $out = ''; + // Context selectors are stored right-to-left; render left-to-right. + $reversed = array_reverse( $complex['context'] ); + foreach ( $reversed as $pair ) { + list( $type, $combinator ) = $pair; + $out .= '*' === $type ? '*' : $this->render_ident( $type ); + if ( '>' === $combinator ) { + $out .= $this->maybe_ws( 50 ) . '>' . $this->maybe_ws( 50 ); + } else { + $out .= $this->ws(); + } + } + return $out . $this->render_compound( $complex['self'] ); + } + + private function render_compound( array $compound ): string { + $out = ''; + if ( null !== $compound['type'] ) { + $out .= '*' === $compound['type'] ? '*' : $this->render_ident( $compound['type'] ); + } + foreach ( (array) $compound['subs'] as $sub ) { + switch ( $sub['kind'] ) { + case 'class': + $out .= '.' . $this->render_ident( $sub['name'] ); + break; + case 'id': + $out .= '#' . $this->render_ident( $sub['name'] ); + break; + case 'attr': + $out .= $this->render_attr_selector( $sub ); + break; + } + } + return $out; + } + + private function render_attr_selector( array $sub ): string { + $out = '[' . $this->maybe_ws( 20 ) . $this->render_ident( $sub['name'] ) . $this->maybe_ws( 20 ); + + if ( null === $sub['matcher'] ) { + return $out . ']'; + } + + $matcher_strings = array( + 'exact' => '=', + 'one-of' => '~=', + 'exact-or-hyphen-suffixed' => '|=', + 'prefixed' => '^=', + 'suffixed' => '$=', + 'contains' => '*=', + ); + $out .= $matcher_strings[ $sub['matcher'] ] . $this->maybe_ws( 25 ); + + $value = $sub['value']; + $value_as_ident = '' !== $value && $this->can_render_as_ident( $value ) && $this->prng->chance( 45 ); + if ( $value_as_ident ) { + $out .= $this->render_ident( $value ); + } else { + $out .= $this->render_string( $value ); + } + + if ( null !== $sub['modifier'] ) { + // After an ident value, whitespace is mandatory before the modifier. + $out .= $value_as_ident ? $this->ws() : $this->maybe_ws( 60 ); + + if ( 'case-insensitive' === $sub['modifier'] ) { + $out .= $this->prng->chance( 70 ) ? 'i' : 'I'; + } else { + $out .= $this->prng->chance( 70 ) ? 's' : 'S'; + } + } + + return $out . $this->maybe_ws( 25 ) . ']'; + } + + /** + * Whether a value contains only codepoints this renderer is willing to + * put in an ident token (everything can be escaped, but a value ending + * in whitespace as an ident is fragile to read — strings handle those). + */ + private function can_render_as_ident( string $value ): bool { + return '' !== $value; + } + + /** + * Renders a name as a CSS ident token, escaping wherever required and + * sometimes where merely allowed. Parsing the result must yield $name. + */ + private function render_ident( string $name ): string { + $points = utf8_codepoints( $name ); + $count = count( $points ); + $out = ''; + + foreach ( $points as $i => $point ) { + list( $char, $cp ) = $point; + + $is_digit = $cp >= 0x30 && $cp <= 0x39; + $is_ident_char = ( + '-' === $char || + '_' === $char || + $is_digit || + ( $cp >= 0x41 && $cp <= 0x5A ) || + ( $cp >= 0x61 && $cp <= 0x7A ) || + $cp > 0x7F + ); + + $must_escape = ! $is_ident_char + || ( 0 === $i && $is_digit ) + || ( 1 === $i && '-' === $points[0][0] && $is_digit ) + || ( 1 === $count && '-' === $char ); + + if ( $must_escape || $this->prng->chance( 8 ) ) { + $out .= $this->render_escape( $char, $cp ); + } else { + $out .= $char; + } + } + + return $out; + } + + /** + * Renders one codepoint as a CSS escape sequence that decodes back to it. + */ + private function render_escape( string $char, int $cp ): string { + $is_hex_digit = ( $cp >= 0x30 && $cp <= 0x39 ) + || ( $cp >= 0x41 && $cp <= 0x46 ) + || ( $cp >= 0x61 && $cp <= 0x66 ); + $is_newline_like = "\n" === $char || "\r" === $char || "\f" === $char; + + /* + * Identity escapes are only safe for single-byte chars that are not + * hex digits (they would start a hex escape) and not newlines + * (backslash-newline is not a valid escape). + */ + $identity_ok = ! $is_hex_digit && ! $is_newline_like && $cp >= 0x20; + + if ( $identity_ok && $this->prng->chance( 35 ) ) { + return '\\' . $char; + } + + $hex = dechex( $cp ); + if ( $this->prng->chance( 25 ) && strlen( $hex ) < 6 ) { + $hex = str_pad( $hex, $this->prng->int( strlen( $hex ), 6 ), '0', STR_PAD_LEFT ); + } + if ( $this->prng->chance( 30 ) ) { + $hex = strtoupper( $hex ); + } + + // The trailing space is always emitted; it is consumed by the escape. + return '\\' . $hex . ' '; + } + + /** + * Renders a value as a CSS string token. Parsing must yield $value. + */ + private function render_string( string $value ): string { + $quote = $this->prng->chance( 60 ) ? '"' : "'"; + $out = $quote; + $points = utf8_codepoints( $value ); + + foreach ( $points as $point ) { + list( $char, $cp ) = $point; + + if ( "\n" === $char || "\r" === $char || "\f" === $char ) { + // Literal newlines end (break) the string; always hex-escape. + $out .= '\\' . dechex( $cp ) . ' '; + continue; + } + if ( $char === $quote || '\\' === $char ) { + $out .= $this->prng->chance( 60 ) ? '\\' . $char : '\\' . dechex( $cp ) . ' '; + continue; + } + if ( $this->prng->chance( 5 ) ) { + $out .= $this->render_escape( $char, $cp ); + continue; + } + $out .= $char; + } + + // Rarely add a backslash-newline line continuation (decodes to nothing). + if ( $this->prng->chance( 4 ) ) { + $out .= "\\\n"; + } + + return $out . $quote; + } + + private function ws(): string { + $options = array( ' ', ' ', ' ', "\t", "\n", "\f", "\r", ' ', " \t " ); + return $this->prng->choice( $options ); + } + + private function maybe_ws( int $percent ): string { + return $this->prng->chance( $percent ) ? $this->ws() : ''; + } + + private function random_case( string $input ): string { + $out = ''; + for ( $i = 0; $i < strlen( $input ); $i++ ) { + $c = $input[ $i ]; + $out .= $this->prng->chance( 50 ) ? strtoupper( $c ) : strtolower( $c ); + } + return $out; + } + + /* + * ------------------- + * Unsupported selectors + * ------------------- + */ + + private function gen_unsupported(): string { + $kind = $this->prng->weighted( + array( + 'pseudo-class' => 25, + 'pseudo-element' => 15, + 'sibling-combinator' => 20, + 'column-combinator' => 8, + 'namespace-type' => 12, + 'namespace-attr' => 8, + 'non-type-context' => 12, + ) + ); + + switch ( $kind ) { + case 'pseudo-class': + $pseudo = $this->prng->choice( + array( + ':hover', + ':focus', + ':first-child', + ':last-child', + ':nth-child(2n+1)', + ':nth-of-type(3)', + ':not(.excluded)', + ':is(div, span)', + ':where(*)', + ':root', + ':empty', + ':checked', + ':lang(en)', + ':has(> img)', + ) + ); + return $this->render_compound( $this->gen_compound() ) . $pseudo; + + case 'pseudo-element': + $pseudo = $this->prng->choice( array( '::before', '::after', '::first-line', '::first-letter', '::marker', '::placeholder' ) ); + return $this->render_compound( $this->gen_compound() ) . $pseudo; + + case 'sibling-combinator': + $combinator = $this->prng->choice( array( '+', '~' ) ); + return $this->render_compound( $this->gen_compound() ) + . $this->maybe_ws( 60 ) . $combinator . $this->maybe_ws( 60 ) + . $this->render_compound( $this->gen_compound() ); + + case 'column-combinator': + return $this->gen_type_name( true ) + . $this->maybe_ws( 50 ) . '||' . $this->maybe_ws( 50 ) + . $this->gen_type_name( true ); + + case 'namespace-type': + $ns = $this->prng->choice( array( 'svg', 'html', '*', '' ) ); + return $ns . '|' . $this->prng->choice( array( 'title', 'a', 'circle', 'div' ) ); + + case 'namespace-attr': + // `[ns|name]` — must not be confused with the `|=` matcher, + // so the char after `|` must not be `=`. + $ns = $this->prng->choice( array( 'xlink', 'svg', 'xml' ) ); + return '[' . $ns . '|href]'; + + case 'non-type-context': + default: + // A context selector that is not a bare type selector. + $context = $this->prng->choice( array( '.ctx', '#ctx', '[ctx]', 'div.ctx', 'div#ctx', 'div[ctx]', '*.ctx' ) ); + $joiner = $this->prng->chance( 50 ) + ? $this->ws() + : $this->maybe_ws( 50 ) . '>' . $this->maybe_ws( 50 ); + return $context . $joiner . $this->render_compound( $this->gen_compound() ); + } + } + + /* + * ----------------- + * Invalid selectors + * ----------------- + */ + + private function gen_invalid(): string { + $kind = $this->prng->weighted( + array( + 'template' => 45, + 'trailing-garbage' => 25, + 'leading-garbage' => 15, + 'comma-trouble' => 15, + ) + ); + + switch ( $kind ) { + case 'template': + return $this->prng->choice( + array( + '', + ' ', + "\t\n\f ", + '.', + '#', + '[', + ']', + '[]', + '[ ]', + '.5x', + '#5', + '. x', + '..a', + '.#a', + '[a', + '[a=', + '[a=]', + '[=b]', + '[a==b]', + '[a~b]', + '[a!=b]', + '[a=b', + '[a="b]', + "[a='b]", + "[a=\"b\nc\"]", + '[a=b x]', + '[a=b ix]', + '[a=b i', + '[5=b]', + 'a >', + '> a', + 'a > > b', + 'a >> b', + '>', + '-', + '\\', + "a\\\nb", + 'a/**/b', + '/* comment */ a', + '!important', + '@media screen', + '{}', + ';', + 'a;b', + 'a{color:red}', + '()', + 'a()', + '*5', + '%', + 'a%', + ) + ); + + case 'trailing-garbage': + $garbage = $this->prng->choice( array( ':', '(', ')', '{', '}', ';', '!', '@', '%', '/', '=', '|', '^', '$' ) ); + return $this->render_compound( $this->gen_compound() ) . $garbage; + + case 'leading-garbage': + $garbage = $this->prng->choice( array( '%', ';', ')', '}', '=', '~', '+', '/', ',' ) ); + return $garbage . $this->render_compound( $this->gen_compound() ); + + case 'comma-trouble': + default: + $compound = $this->render_compound( $this->gen_compound() ); + return $this->prng->choice( + array( + $compound . ',', + ',' . $compound, + $compound . ',,' . $compound, + $compound . ', ,' . $compound, + $compound . ' , ', + ) + ); + } + } + + /* + * ----- + * Chaos + * ----- + */ + + private function gen_chaos(): string { + $alphabets = array( + 'css' => '.#[]=~|^$*>+,:()"\'\\ \t\n-_', + 'ident' => 'abcXYZ019-_', + 'mixed' => '.#[]=~|^$*>+,:()"\'\\ abcXYZ019-_iIsS', + 'unicode' => '✓Ωé🙂', + ); + + $alphabet = $alphabets[ $this->prng->weighted( + array( + 'css' => 25, + 'ident' => 15, + 'mixed' => 45, + 'unicode' => 15, + ) + ) ]; + + if ( 'unicode' === $alphabet ) { + $points = utf8_codepoints( $alphabet . '.#[]= aZ9' ); + $length = $this->prng->int( 0, 24 ); + $out = ''; + for ( $i = 0; $i < $length; $i++ ) { + $out .= $this->prng->choice( $points )[0]; + } + return $out; + } + + $length = $this->prng->int( 0, 40 ); + $out = ''; + for ( $i = 0; $i < $length; $i++ ) { + $out .= $alphabet[ $this->prng->int( 0, strlen( $alphabet ) - 1 ) ]; + } + return $out; + } + + /* + * -------- + * Mutation + * -------- + */ + + private function mutate( string $selector ): string { + $mutation_count = $this->prng->int( 1, 4 ); + $alphabet = '.#[]=~|^$*>+,:()"\'\\ \t\niIsSabcXYZ019-_'; + + for ( $m = 0; $m < $mutation_count; $m++ ) { + $length = strlen( $selector ); + $kind = $this->prng->weighted( + array( + 'insert' => 30, + 'delete' => 25, + 'replace' => 25, + 'duplicate' => 10, + 'case-flip' => 10, + ) + ); + + switch ( $kind ) { + case 'insert': + $at = $this->prng->int( 0, $length ); + $char = $alphabet[ $this->prng->int( 0, strlen( $alphabet ) - 1 ) ]; + $selector = substr( $selector, 0, $at ) . $char . substr( $selector, $at ); + break; + + case 'delete': + if ( $length > 0 ) { + $at = $this->prng->int( 0, $length - 1 ); + $selector = substr( $selector, 0, $at ) . substr( $selector, $at + 1 ); + } + break; + + case 'replace': + if ( $length > 0 ) { + $at = $this->prng->int( 0, $length - 1 ); + $char = $alphabet[ $this->prng->int( 0, strlen( $alphabet ) - 1 ) ]; + $selector = substr( $selector, 0, $at ) . $char . substr( $selector, $at + 1 ); + } + break; + + case 'duplicate': + if ( $length > 0 ) { + $start = $this->prng->int( 0, $length - 1 ); + $span = $this->prng->int( 1, min( 6, $length - $start ) ); + $selector = substr( $selector, 0, $start + $span ) + . substr( $selector, $start, $span ) + . substr( $selector, $start + $span ); + } + break; + + case 'case-flip': + if ( $length > 0 ) { + $at = $this->prng->int( 0, $length - 1 ); + $char = $selector[ $at ]; + $flip = ctype_lower( $char ) ? strtoupper( $char ) : strtolower( $char ); + $selector = substr( $selector, 0, $at ) . $flip . substr( $selector, $at + 1 ); + } + break; + } + } + + return $selector; + } +} diff --git a/tools/css-selector-fuzz/lib/Worker.php b/tools/css-selector-fuzz/lib/Worker.php new file mode 100644 index 0000000000000..bfa1ec2a580e2 --- /dev/null +++ b/tools/css-selector-fuzz/lib/Worker.php @@ -0,0 +1,589 @@ +fork( 'document' ) ); + $selector = SelectorGenerator::generate( $prng->fork( 'selector' ), $document['pools'] ); + + $failures = array(); + $record = static function ( string $invariant, array $detail ) use ( &$failures ) { + $failures[] = array( + 'invariant' => $invariant, + 'detail' => $detail, + ); + }; + + self::check_document_model( $document, $record ); + + $selector_string = $selector['selector']; + + // --- Parse phase ------------------------------------------------- + + list( $compound_list, $compound_error ) = self::guard( + static function () use ( $selector_string ) { + return \WP_CSS_Compound_Selector_List::from_selectors( $selector_string ); + } + ); + list( $complex_list, $complex_error ) = self::guard( + static function () use ( $selector_string ) { + return \WP_CSS_Complex_Selector_List::from_selectors( $selector_string ); + } + ); + + if ( null !== $compound_error ) { + $record( 'parse-error', array( 'grammar' => 'compound', 'error' => self::describe_throwable( $compound_error ) ) ); + } + if ( null !== $complex_error ) { + $record( 'parse-error', array( 'grammar' => 'complex', 'error' => self::describe_throwable( $complex_error ) ) ); + } + + if ( null === $compound_error && null !== $selector['expectCompound'] && $selector['expectCompound'] !== ( null !== $compound_list ) ) { + $record( + 'parse-expectation', + array( + 'grammar' => 'compound', + 'expected' => $selector['expectCompound'] ? 'parse' : 'null', + 'actual' => null !== $compound_list ? 'parse' : 'null', + ) + ); + } + if ( null === $complex_error && null !== $selector['expectComplex'] && $selector['expectComplex'] !== ( null !== $complex_list ) ) { + $record( + 'parse-expectation', + array( + 'grammar' => 'complex', + 'expected' => $selector['expectComplex'] ? 'parse' : 'null', + 'actual' => null !== $complex_list ? 'parse' : 'null', + ) + ); + } + + if ( null !== $compound_list && null === $complex_list && null === $complex_error ) { + $record( 'compound-implies-complex', array() ); + } + + // Parse determinism: a second parse must agree with the first. + list( $compound_again, ) = self::guard( + static function () use ( $selector_string ) { + return \WP_CSS_Compound_Selector_List::from_selectors( $selector_string ); + } + ); + list( $complex_again, ) = self::guard( + static function () use ( $selector_string ) { + return \WP_CSS_Complex_Selector_List::from_selectors( $selector_string ); + } + ); + if ( ( null === $compound_list ) !== ( null === $compound_again ) || ( null === $complex_list ) !== ( null === $complex_again ) ) { + $record( 'parse-determinism', array( 'note' => 'null-ness changed between identical parses' ) ); + } + + // --- AST extraction ---------------------------------------------- + + $compound_ast = null; + $complex_ast = null; + + if ( null !== $compound_list ) { + list( $compound_ast, $shape_error ) = self::guard( + static function () use ( $compound_list ) { + return AstExtractor::from_compound_list( $compound_list ); + } + ); + if ( null !== $shape_error ) { + $record( 'ast-shape', array( 'grammar' => 'compound', 'error' => self::describe_throwable( $shape_error ) ) ); + } + } + if ( null !== $complex_list ) { + list( $complex_ast, $shape_error ) = self::guard( + static function () use ( $complex_list ) { + return AstExtractor::from_complex_list( $complex_list ); + } + ); + if ( null !== $shape_error ) { + $record( 'ast-shape', array( 'grammar' => 'complex', 'error' => self::describe_throwable( $shape_error ) ) ); + } + } + + if ( null !== $compound_ast && null !== $complex_ast && $compound_ast !== $complex_ast ) { + $record( + 'ast-cross-grammar', + array( + 'compoundAst' => $compound_ast, + 'complexAst' => $complex_ast, + ) + ); + } + + if ( null !== $selector['ast'] && null !== $complex_ast && $selector['ast'] !== $complex_ast ) { + $record( + 'ast-mismatch', + array( + 'generatedAst' => $selector['ast'], + 'parsedAst' => $complex_ast, + ) + ); + } + + // --- Match phase --------------------------------------------------- + + if ( null !== $complex_ast ) { + $expected = ReferenceMatcher::expected_html_processor_matches( $complex_ast, $document['model'], $document['quirks'] ); + self::check_select_matches( 'html', $selector_string, $document, $expected, $record ); + } elseif ( null === $complex_list && null === $complex_error ) { + self::check_select_rejection( 'html', $selector_string, $document, $record ); + } + + if ( null !== $compound_ast ) { + $expected = ReferenceMatcher::expected_tag_processor_matches( $compound_ast, $document['model'] ); + self::check_select_matches( 'tag', $selector_string, $document, $expected, $record ); + } elseif ( null === $compound_list && null === $compound_error ) { + self::check_select_rejection( 'tag', $selector_string, $document, $record ); + } + + $digest = sha1( + json_encode_safe( + array( + $selector_string, + $document['html'], + null !== $compound_list, + null !== $complex_list, + $compound_ast, + $complex_ast, + array_map( + static function ( $failure ) { + return $failure['invariant']; + }, + $failures + ), + ) + ) + ); + + return array( + 'seed' => $seed, + 'bucket' => $selector['bucket'], + 'digest' => $digest, + 'failures' => $failures, + 'selector' => $selector_string, + 'html' => $document['html'], + ); + } + + /** + * Verifies that both processors see exactly the modeled element list — + * this guards the oracle itself against renderer/model drift. + */ + private static function check_document_model( array $document, callable $record ): void { + $expected = array(); + foreach ( DocumentGenerator::flatten_with_ancestors( $document['model'] ) as $pair ) { + list( $element, $ancestors ) = $pair; + $expected[] = array( + strtoupper( ascii_strtolower( $element['tag'] ) ), + $element['fid'], + count( $ancestors ) + 1, + ); + } + + list( $actual, $error ) = self::guard( + static function () use ( $document ) { + $processor = \WP_HTML_Processor::create_full_parser( $document['html'] ); + $out = array(); + while ( $processor->next_tag() ) { + $fid = $processor->get_attribute( 'data-fid' ); + $out[] = array( + (string) $processor->get_tag(), + is_string( $fid ) ? $fid : '(missing)', + count( $processor->get_breadcrumbs() ), + ); + } + if ( null !== $processor->get_last_error() ) { + throw new \RuntimeException( 'Processor error: ' . $processor->get_last_error() ); + } + return $out; + } + ); + + if ( null !== $error ) { + $record( 'model-desync', array( 'processor' => 'html', 'error' => self::describe_throwable( $error ) ) ); + return; + } + + if ( $actual !== $expected ) { + $record( + 'model-desync', + array( + 'processor' => 'html', + 'expected' => $expected, + 'actual' => $actual, + ) + ); + } + + // The tag processor must see the same elements ( without breadcrumbs ). + $expected_tags = array(); + foreach ( $expected as $row ) { + $expected_tags[] = array( $row[0], $row[1] ); + } + + list( $actual_tags, $tag_error ) = self::guard( + static function () use ( $document ) { + $processor = new \WP_HTML_Tag_Processor( $document['html'] ); + $out = array(); + while ( $processor->next_tag() ) { + $fid = $processor->get_attribute( 'data-fid' ); + $out[] = array( + (string) $processor->get_tag(), + is_string( $fid ) ? $fid : '(missing)', + ); + } + return $out; + } + ); + + if ( null !== $tag_error ) { + $record( 'model-desync', array( 'processor' => 'tag', 'error' => self::describe_throwable( $tag_error ) ) ); + return; + } + + if ( $actual_tags !== $expected_tags ) { + $record( + 'model-desync', + array( + 'processor' => 'tag', + 'expected' => $expected_tags, + 'actual' => $actual_tags, + ) + ); + } + } + + /** + * Runs a select() loop on a parseable selector and compares the match set + * against the reference matcher. + * + * @param string $target 'html' or 'tag'. + */ + private static function check_select_matches( string $target, string $selector_string, array $document, array $expected, callable $record ): void { + Bootstrap::reset_doing_it_wrong(); + + list( $actual, $error ) = self::guard( + static function () use ( $target, $selector_string, $document ) { + $processor = 'html' === $target + ? \WP_HTML_Processor::create_full_parser( $document['html'] ) + : new \WP_HTML_Tag_Processor( $document['html'] ); + + $matches = array(); + $iterations = 0; + while ( $processor->select( $selector_string ) ) { + $fid = $processor->get_attribute( 'data-fid' ); + $matches[] = is_string( $fid ) ? $fid : '(missing-fid:' . $processor->get_tag() . ')'; + if ( ++$iterations > self::SELECT_ITERATION_LIMIT ) { + throw new \RuntimeException( 'select() did not terminate within the iteration limit.' ); + } + } + + if ( $processor instanceof \WP_HTML_Processor ) { + if ( null !== $processor->get_last_error() ) { + throw new \RuntimeException( 'Processor error state: ' . $processor->get_last_error() ); + } + if ( null !== $processor->get_unsupported_exception() ) { + throw new \RuntimeException( 'Processor unsupported state: ' . $processor->get_unsupported_exception()->getMessage() ); + } + } + + return $matches; + } + ); + + if ( null !== $error ) { + $record( + 'match-error', + array( + 'target' => $target, + 'error' => self::describe_throwable( $error ), + ) + ); + return; + } + + $doing_it_wrong = Bootstrap::doing_it_wrong_calls(); + if ( array() !== $doing_it_wrong ) { + $record( + 'doing-it-wrong-unexpected', + array( + 'target' => $target, + 'calls' => $doing_it_wrong, + ) + ); + } + + if ( $actual !== $expected ) { + $record( + 'match-mismatch-' . $target, + array( + 'expected' => $expected, + 'actual' => $actual, + ) + ); + } + } + + /** + * For unparseable selectors: select() must return false, leave the + * processor usable, and report misuse exactly once per call. + */ + private static function check_select_rejection( string $target, string $selector_string, array $document, callable $record ): void { + Bootstrap::reset_doing_it_wrong(); + + list( $results, $error ) = self::guard( + static function () use ( $target, $selector_string, $document ) { + $processor = 'html' === $target + ? \WP_HTML_Processor::create_full_parser( $document['html'] ) + : new \WP_HTML_Tag_Processor( $document['html'] ); + + // Two calls: the second exercises the parse cache. + return array( $processor->select( $selector_string ), $processor->select( $selector_string ) ); + } + ); + + if ( null !== $error ) { + $record( + 'match-error', + array( + 'target' => $target, + 'rejected' => true, + 'error' => self::describe_throwable( $error ), + ) + ); + return; + } + + if ( array( false, false ) !== $results ) { + $record( + 'select-on-null', + array( + 'target' => $target, + 'results' => $results, + ) + ); + } + + $doing_it_wrong = Bootstrap::doing_it_wrong_calls(); + if ( 2 !== count( $doing_it_wrong ) ) { + $record( + 'doing-it-wrong-missing', + array( + 'target' => $target, + 'expectedCalls' => 2, + 'calls' => $doing_it_wrong, + ) + ); + } + } + + /* + * ------------- + * Batch running + * ------------- + */ + + /** + * Runs a batch of sequential seeds. + * + * @return array Summary. + */ + public static function run_batch( array $options ): array { + Bootstrap::load(); + + $start_seed = option_int( $options, 'start-seed', 1 ); + $count = option_int( $options, 'count', 100 ); + $failures_out = option_string( $options, 'failures-out', null ); + $progress_file = option_string( $options, 'progress-file', null ); + $determinism_every = option_int( $options, 'determinism-every', 16 ); + $max_failures = option_int( $options, 'max-failures', 200 ); + + $started_at = microtime( true ); + $failures = 0; + $buckets = array(); + $signatures = array(); + $last_seed = null; + $stop_reason = 'completed'; + + for ( $seed = $start_seed; $seed < $start_seed + $count; $seed++ ) { + if ( $max_failures > 0 && $failures >= $max_failures ) { + $stop_reason = 'max-failures'; + break; + } + if ( null !== $progress_file ) { + file_put_contents( $progress_file, (string) $seed ); + } + + $result = self::run_case( $seed ); + + if ( $determinism_every > 0 && 0 === $seed % $determinism_every ) { + $repeat = self::run_case( $seed ); + if ( $repeat['digest'] !== $result['digest'] ) { + $result['failures'][] = array( + 'invariant' => 'case-determinism', + 'detail' => array( + 'firstDigest' => $result['digest'], + 'secondDigest' => $repeat['digest'], + ), + ); + } + } + + $buckets[ $result['bucket'] ] = ( $buckets[ $result['bucket'] ] ?? 0 ) + 1; + $last_seed = $seed; + + foreach ( $result['failures'] as $failure ) { + ++$failures; + $signature = self::signature( $failure ); + $signatures[ $signature ] = ( $signatures[ $signature ] ?? 0 ) + 1; + + $entry = array( + 'kind' => 'css-selector-fuzz-failure', + 'seed' => $result['seed'], + 'bucket' => $result['bucket'], + 'invariant' => $failure['invariant'], + 'signature' => $signature, + 'selector' => printable_bytes( $result['selector'] ), + 'selectorBase64' => base64_encode( $result['selector'] ), + 'htmlBase64' => base64_encode( $result['html'] ), + 'detail' => $failure['detail'], + ); + if ( null !== $failures_out ) { + append_ndjson( $failures_out, $entry ); + } else { + fwrite( STDERR, json_encode_safe( $entry ) . "\n" ); + } + } + } + + return array( + 'kind' => 'css-selector-fuzz-batch-summary', + 'startSeed' => $start_seed, + 'count' => $count, + 'lastSeed' => $last_seed, + 'failures' => $failures, + 'buckets' => $buckets, + 'signatures' => $signatures, + 'stopReason' => $stop_reason, + 'durationMs' => (int) round( 1000 * ( microtime( true ) - $started_at ) ), + ); + } + + /** Stable identity for de-duplicating equivalent failures. */ + private static function signature( array $failure ): string { + $parts = array( $failure['invariant'] ); + if ( isset( $failure['detail']['grammar'] ) ) { + $parts[] = $failure['detail']['grammar']; + } + if ( isset( $failure['detail']['target'] ) ) { + $parts[] = $failure['detail']['target']; + } + if ( isset( $failure['detail']['error']['class'] ) ) { + $parts[] = $failure['detail']['error']['class']; + $parts[] = preg_replace( '/[0-9]+/', 'N', (string) ( $failure['detail']['error']['message'] ?? '' ) ); + } + return substr( sha1( implode( '|', $parts ) ), 0, 12 ) . ':' . $failure['invariant']; + } + + /* + * ------- + * Helpers + * ------- + */ + + /** + * Calls $fn with PHP warnings/notices converted to exceptions. + * + * @return array{0: mixed, 1: \Throwable|null} + */ + private static function guard( callable $fn ): array { + set_error_handler( + static function ( $severity, $message, $file, $line ) { + if ( E_DEPRECATED === $severity || E_USER_DEPRECATED === $severity ) { + return true; + } + throw new \ErrorException( $message, 0, $severity, $file, $line ); + } + ); + try { + return array( $fn(), null ); + } catch ( \Throwable $e ) { + return array( null, $e ); + } finally { + restore_error_handler(); + } + } + + public static function describe_throwable( \Throwable $e ): array { + $root = repo_root() . DIRECTORY_SEPARATOR; + return array( + 'class' => get_class( $e ), + 'message' => $e->getMessage(), + 'at' => str_replace( $root, '', $e->getFile() ) . ':' . $e->getLine(), + 'trace' => array_slice( + array_map( + static function ( $frame ) use ( $root ) { + $location = isset( $frame['file'] ) + ? str_replace( $root, '', $frame['file'] ) . ':' . ( $frame['line'] ?? '?' ) + : '[internal]'; + $callable = ( $frame['class'] ?? '' ) . ( $frame['type'] ?? '' ) . ( $frame['function'] ?? '' ); + return $location . ' ' . $callable; + }, + $e->getTrace() + ), + 0, + 6 + ), + ); + } +} diff --git a/tools/css-selector-fuzz/lib/autoload.php b/tools/css-selector-fuzz/lib/autoload.php new file mode 100644 index 0000000000000..ffc0e572ed9c1 --- /dev/null +++ b/tools/css-selector-fuzz/lib/autoload.php @@ -0,0 +1,9 @@ + array() ); + $count = count( $argv ); + for ( $i = 1; $i < $count; $i++ ) { + $arg = $argv[ $i ]; + if ( 0 === strpos( $arg, '--' ) ) { + $name = substr( $arg, 2 ); + if ( false !== strpos( $name, '=' ) ) { + list( $name, $value ) = explode( '=', $name, 2 ); + $options[ $name ] = $value; + } elseif ( $i + 1 < $count && 0 !== strpos( $argv[ $i + 1 ], '--' ) ) { + $options[ $name ] = $argv[ ++$i ]; + } else { + $options[ $name ] = true; + } + } else { + $options['_'][] = $arg; + } + } + return $options; +} + +function option_string( array $options, string $name, ?string $default = null ): ?string { + if ( ! array_key_exists( $name, $options ) || true === $options[ $name ] ) { + return $default; + } + return (string) $options[ $name ]; +} + +function option_int( array $options, string $name, int $default ): int { + $value = option_string( $options, $name, null ); + return null === $value ? $default : (int) $value; +} + +function option_float( array $options, string $name, float $default ): float { + $value = option_string( $options, $name, null ); + return null === $value ? $default : (float) $value; +} + +function option_bool( array $options, string $name, bool $default ): bool { + if ( ! array_key_exists( $name, $options ) ) { + return $default; + } + $value = $options[ $name ]; + if ( true === $value ) { + return true; + } + return in_array( strtolower( (string) $value ), array( '1', 'true', 'yes', 'on' ), true ); +} + +function ensure_dir( string $dir ): void { + if ( ! is_dir( $dir ) && ! mkdir( $dir, 0777, true ) && ! is_dir( $dir ) ) { + throw new \RuntimeException( "Could not create directory: {$dir}" ); + } +} + +function json_encode_safe( $value ): string { + $encoded = json_encode( $value, JSON_UNESCAPED_SLASHES | JSON_INVALID_UTF8_SUBSTITUTE ); + if ( false === $encoded ) { + $encoded = json_encode( array( 'jsonError' => json_last_error_msg() ) ); + } + return $encoded; +} + +function write_json_file( string $path, $value ): void { + file_put_contents( $path, json_encode_safe( $value ) . "\n" ); +} + +function read_json_file( string $path ): ?array { + if ( ! is_file( $path ) ) { + return null; + } + $decoded = json_decode( (string) file_get_contents( $path ), true ); + return is_array( $decoded ) ? $decoded : null; +} + +function append_ndjson( string $path, array $value ): void { + file_put_contents( $path, json_encode_safe( $value ) . "\n", FILE_APPEND | LOCK_EX ); +} + +function timestamp(): string { + return gmdate( 'Ymd-His' ); +} + +/** + * Renders bytes for human inspection: printable ASCII passes through, + * everything else becomes \xHH. + */ +function printable_bytes( string $bytes, int $max_length = 4096 ): string { + $out = ''; + $truncated = strlen( $bytes ) > $max_length; + $bytes = substr( $bytes, 0, $max_length ); + for ( $i = 0; $i < strlen( $bytes ); $i++ ) { + $c = $bytes[ $i ]; + $o = ord( $c ); + if ( $o >= 0x20 && $o <= 0x7E ) { + $out .= '\\' === $c ? '\\\\' : $c; + } else { + $out .= sprintf( '\\x%02X', $o ); + } + } + return $out . ( $truncated ? '…(truncated)' : '' ); +} + +function git_metadata(): array { + $head = trim( (string) shell_exec( 'git -C ' . escapeshellarg( repo_root() ) . ' rev-parse HEAD 2>/dev/null' ) ); + $branch = trim( (string) shell_exec( 'git -C ' . escapeshellarg( repo_root() ) . ' rev-parse --abbrev-ref HEAD 2>/dev/null' ) ); + return array( + 'head' => '' !== $head ? $head : null, + 'branch' => '' !== $branch ? $branch : null, + ); +} + +function ascii_strtolower( string $input ): string { + return strtr( $input, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz' ); +} + +/** + * Splits a valid UTF-8 string into codepoints. + * + * @return array Pairs of ( utf8 bytes, codepoint value ). + */ +function utf8_codepoints( string $input ): array { + $out = array(); + $len = strlen( $input ); + $i = 0; + while ( $i < $len ) { + $byte = ord( $input[ $i ] ); + if ( $byte < 0x80 ) { + $size = 1; + $cp = $byte; + } elseif ( 0xC0 === ( $byte & 0xE0 ) ) { + $size = 2; + $cp = $byte & 0x1F; + } elseif ( 0xE0 === ( $byte & 0xF0 ) ) { + $size = 3; + $cp = $byte & 0x0F; + } else { + $size = 4; + $cp = $byte & 0x07; + } + $size = min( $size, $len - $i ); + for ( $j = 1; $j < $size; $j++ ) { + $cp = ( $cp << 6 ) | ( ord( $input[ $i + $j ] ) & 0x3F ); + } + $out[] = array( substr( $input, $i, $size ), $cp ); + $i += $size; + } + return $out; +} diff --git a/tools/css-selector-fuzz/lib/wp-stubs.php b/tools/css-selector-fuzz/lib/wp-stubs.php new file mode 100644 index 0000000000000..ec9b154ee58d6 --- /dev/null +++ b/tools/css-selector-fuzz/lib/wp-stubs.php @@ -0,0 +1,62 @@ + (string) $function_name, + 'message' => (string) $message, + ); + } +} + +if ( ! function_exists( '_deprecated_argument' ) ) { + function _deprecated_argument( $function_name, $version, $message = '' ) { + } +} + +if ( ! function_exists( 'wp_trigger_error' ) ) { + function wp_trigger_error( $function_name, $message, $error_level = E_USER_NOTICE ) { + $GLOBALS['css_selector_fuzz_doing_it_wrong'][] = array( + 'function' => (string) $function_name, + 'message' => (string) $message, + ); + } +} + +if ( ! function_exists( 'wp_kses_uri_attributes' ) ) { + function wp_kses_uri_attributes() { + return array( + 'action', + 'archive', + 'background', + 'cite', + 'classid', + 'codebase', + 'data', + 'formaction', + 'href', + 'icon', + 'longdesc', + 'manifest', + 'poster', + 'profile', + 'src', + 'usemap', + 'xmlns', + ); + } +} diff --git a/tools/css-selector-fuzz/replay.php b/tools/css-selector-fuzz/replay.php new file mode 100644 index 0000000000000..38ffb8a43678e --- /dev/null +++ b/tools/css-selector-fuzz/replay.php @@ -0,0 +1,91 @@ +#!/usr/bin/env php + bar' [--html '
…
'] + */ + +require_once __DIR__ . '/lib/autoload.php'; + +use CssSelectorFuzz\Bootstrap; +use CssSelectorFuzz\Worker; +use function CssSelectorFuzz\json_encode_safe; +use function CssSelectorFuzz\option_bool; +use function CssSelectorFuzz\option_int; +use function CssSelectorFuzz\option_string; +use function CssSelectorFuzz\parse_cli_options; +use function CssSelectorFuzz\printable_bytes; + +$options = parse_cli_options( $argv ); + +$probe_selector = option_string( $options, 'selector', null ); +if ( null !== $probe_selector ) { + // Quick probe mode: parse a selector and report what the API does with it. + Bootstrap::load(); + + $compound = \WP_CSS_Compound_Selector_List::from_selectors( $probe_selector ); + $complex = \WP_CSS_Complex_Selector_List::from_selectors( $probe_selector ); + + $report = array( + 'selector' => printable_bytes( $probe_selector ), + 'compoundList' => null === $compound ? null : \CssSelectorFuzz\AstExtractor::from_compound_list( $compound ), + 'complexList' => null === $complex ? null : \CssSelectorFuzz\AstExtractor::from_complex_list( $complex ), + ); + + $html = option_string( $options, 'html', null ); + if ( null !== $html && null !== $complex ) { + $processor = \WP_HTML_Processor::create_full_parser( $html ); + $matches = array(); + while ( $processor->select( $probe_selector ) ) { + $matches[] = array( + 'tag' => $processor->get_tag(), + 'breadcrumbs' => $processor->get_breadcrumbs(), + ); + } + $report['htmlProcessorMatches'] = $matches; + } + + echo json_encode_safe( $report ) . "\n"; + exit( 0 ); +} + +$seed = option_int( $options, 'seed', -1 ); +if ( $seed < 0 ) { + echo "Usage: php tools/css-selector-fuzz/replay.php --seed N [--json] [--show-html]\n"; + echo " php tools/css-selector-fuzz/replay.php --selector 'div > .cls' [--html '
…
']\n"; + exit( 1 ); +} + +$result = Worker::run_case( $seed ); + +if ( option_bool( $options, 'json', false ) ) { + echo json_encode_safe( $result ) . "\n"; + exit( array() === $result['failures'] ? 0 : 2 ); +} + +echo "seed: {$result['seed']}\n"; +echo "bucket: {$result['bucket']}\n"; +echo 'selector: ' . printable_bytes( $result['selector'] ) . "\n"; +echo "digest: {$result['digest']}\n"; + +if ( option_bool( $options, 'show-html', false ) ) { + echo "html: " . printable_bytes( $result['html'] ) . "\n"; +} + +if ( array() === $result['failures'] ) { + echo "failures: none\n"; + exit( 0 ); +} + +echo 'failures: ' . count( $result['failures'] ) . "\n"; +foreach ( $result['failures'] as $i => $failure ) { + echo "--- failure {$i}: {$failure['invariant']} ---\n"; + echo json_encode_safe( $failure['detail'] ) . "\n"; +} +exit( 2 ); diff --git a/tools/css-selector-fuzz/runner.php b/tools/css-selector-fuzz/runner.php new file mode 100644 index 0000000000000..3dbdf0ee66cbe --- /dev/null +++ b/tools/css-selector-fuzz/runner.php @@ -0,0 +1,267 @@ +#!/usr/bin/env php + array( 'pipe', 'r' ), + 1 => array( 'pipe', 'w' ), + 2 => array( 'pipe', 'w' ), + ); + + $started = microtime( true ); + $proc = proc_open( $command, $descriptors, $pipes, repo_root() ); + if ( ! is_resource( $proc ) ) { + return array( + 'code' => null, + 'timedOut' => false, + 'stdout' => '', + 'stderr' => 'proc_open failed', + 'durationMs' => 0, + ); + } + + fclose( $pipes[0] ); + stream_set_blocking( $pipes[1], false ); + stream_set_blocking( $pipes[2], false ); + + $stdout = ''; + $stderr = ''; + $timed_out = false; + $deadline = $started + $timeout_ms / 1000; + + while ( true ) { + $status = proc_get_status( $proc ); + $stdout .= (string) stream_get_contents( $pipes[1] ); + $stderr .= (string) stream_get_contents( $pipes[2] ); + + if ( ! $status['running'] ) { + $code = $status['exitcode']; + break; + } + if ( microtime( true ) > $deadline ) { + $timed_out = true; + proc_terminate( $proc, 9 ); + $code = null; + break; + } + usleep( 10000 ); + } + + $stdout .= (string) stream_get_contents( $pipes[1] ); + $stderr .= (string) stream_get_contents( $pipes[2] ); + fclose( $pipes[1] ); + fclose( $pipes[2] ); + proc_close( $proc ); + + return array( + 'code' => $code, + 'timedOut' => $timed_out, + 'stdout' => $stdout, + 'stderr' => $stderr, + 'durationMs' => (int) round( 1000 * ( microtime( true ) - $started ) ), + ); +} + +/** Extracts the batch summary from worker stdout, or null. */ +function css_selector_fuzz_worker_summary( string $stdout ): ?array { + foreach ( array_reverse( explode( "\n", trim( $stdout ) ) ) as $line ) { + $decoded = json_decode( $line, true ); + if ( is_array( $decoded ) && 'css-selector-fuzz-batch-summary' === ( $decoded['kind'] ?? null ) ) { + return $decoded; + } + } + return null; +} + +$options = parse_cli_options( $argv ); +if ( option_bool( $options, 'help', false ) || option_bool( $options, 'h', false ) ) { + echo "Usage: php tools/css-selector-fuzz/runner.php [--start-seed N] [--max-seeds N] [--duration-seconds N] [--chunk-size N] [--timeout-ms N] [--output-dir DIR] [--stop-on-failure]\n"; + exit( 0 ); +} + +$start_seed = option_int( $options, 'start-seed', 1 ); +$max_seeds = option_int( $options, 'max-seeds', 1000 ); +$duration_seconds = option_int( $options, 'duration-seconds', 120 ); +$chunk_size = max( 1, option_int( $options, 'chunk-size', 200 ) ); +$timeout_ms = option_int( $options, 'timeout-ms', 0 ); +$stop_on_failure = option_bool( $options, 'stop-on-failure', false ); +$output_dir = option_string( $options, 'output-dir', repo_root() . '/artifacts/css-selector-fuzz/run-' . timestamp() ); + +if ( $max_seeds < 1 ) { + fwrite( STDERR, "--max-seeds must be at least 1; refusing to run unbounded.\n" ); + exit( 1 ); +} +if ( 0 === $timeout_ms ) { + // Generous per-chunk budget: ~50ms per case plus startup. + $timeout_ms = $chunk_size * 50 + 10000; +} + +ensure_dir( $output_dir ); +$failures_path = $output_dir . '/failures.ndjson'; +$state_path = $output_dir . '/state.json'; +$worker_script = __DIR__ . '/worker.php'; + +$state = array( + 'kind' => 'css-selector-fuzz-runner-state', + 'startedAt' => gmdate( 'c' ), + 'updatedAt' => gmdate( 'c' ), + 'git' => git_metadata(), + 'phpVersion' => PHP_VERSION, + 'outputDir' => $output_dir, + 'startSeed' => $start_seed, + 'maxSeeds' => $max_seeds, + 'durationSeconds' => $duration_seconds, + 'chunkSize' => $chunk_size, + 'casesCompleted' => 0, + 'failures' => 0, + 'crashes' => 0, + 'buckets' => array(), + 'signatures' => array(), + 'nextSeed' => $start_seed, + 'stopReason' => null, +); +write_json_file( $state_path, $state ); + +$deadline = $duration_seconds > 0 ? microtime( true ) + $duration_seconds : null; +$seed = $start_seed; +$end_seed = $start_seed + $max_seeds; + +while ( $seed < $end_seed ) { + if ( null !== $deadline && microtime( true ) > $deadline ) { + $state['stopReason'] = 'duration-elapsed'; + break; + } + + $count = min( $chunk_size, $end_seed - $seed ); + $args = array( + $worker_script, + '--start-seed', + (string) $seed, + '--count', + (string) $count, + '--failures-out', + $failures_path, + '--progress-file', + $output_dir . '/progress.txt', + ); + + $proc = css_selector_fuzz_run_php( $args, $timeout_ms ); + $summary = css_selector_fuzz_worker_summary( $proc['stdout'] ); + + if ( null === $summary ) { + /* + * The worker crashed, hung, or died fatally. Re-run each seed of the + * chunk in its own process to attribute the crash. + */ + fwrite( STDERR, "chunk seed={$seed} count={$count}: worker crashed/hung; isolating…\n" ); + for ( $isolated = $seed; $isolated < $seed + $count; $isolated++ ) { + $single = css_selector_fuzz_run_php( + array( + $worker_script, + '--start-seed', + (string) $isolated, + '--count', + '1', + '--failures-out', + $failures_path, + '--determinism-every', + '0', + ), + max( 5000, (int) ( $timeout_ms / $count ) + 5000 ) + ); + $single_summary = css_selector_fuzz_worker_summary( $single['stdout'] ); + if ( null === $single_summary ) { + ++$state['crashes']; + ++$state['failures']; + append_ndjson( + $failures_path, + array( + 'kind' => 'css-selector-fuzz-failure', + 'seed' => $isolated, + 'invariant' => $single['timedOut'] ? 'worker-timeout' : 'worker-crash', + 'signature' => $single['timedOut'] ? 'worker-timeout' : 'worker-crash', + 'exitCode' => $single['code'], + 'stderrTail' => substr( $single['stderr'], -2000 ), + ) + ); + $key = $single['timedOut'] ? 'worker-timeout' : 'worker-crash'; + $state['signatures'][ $key ] = ( $state['signatures'][ $key ] ?? 0 ) + 1; + } else { + ++$state['casesCompleted']; + $state['failures'] += $single_summary['failures']; + foreach ( $single_summary['signatures'] as $signature => $signature_count ) { + $state['signatures'][ $signature ] = ( $state['signatures'][ $signature ] ?? 0 ) + $signature_count; + } + } + } + } else { + $state['casesCompleted'] += array_sum( $summary['buckets'] ); + $state['failures'] += $summary['failures']; + foreach ( $summary['buckets'] as $bucket => $bucket_count ) { + $state['buckets'][ $bucket ] = ( $state['buckets'][ $bucket ] ?? 0 ) + $bucket_count; + } + foreach ( $summary['signatures'] as $signature => $signature_count ) { + $state['signatures'][ $signature ] = ( $state['signatures'][ $signature ] ?? 0 ) + $signature_count; + } + } + + $seed += $count; + $state['nextSeed'] = $seed; + $state['updatedAt'] = gmdate( 'c' ); + write_json_file( $state_path, $state ); + + if ( $stop_on_failure && $state['failures'] > 0 ) { + $state['stopReason'] = 'stop-on-failure'; + break; + } +} + +if ( null === $state['stopReason'] ) { + $state['stopReason'] = 'max-seeds'; +} +$state['updatedAt'] = gmdate( 'c' ); +write_json_file( $state_path, $state ); + +echo json_encode_safe( $state ) . "\n"; +exit( 0 === $state['failures'] ? 0 : 2 ); diff --git a/tools/css-selector-fuzz/tests/self-check.php b/tools/css-selector-fuzz/tests/self-check.php new file mode 100644 index 0000000000000..e92cc3ecd3f7c --- /dev/null +++ b/tools/css-selector-fuzz/tests/self-check.php @@ -0,0 +1,131 @@ +#!/usr/bin/env php +bytes( 64 ) === $b->bytes( 64 ), 'Identical seeds produce identical streams.' ); + +$c = new Prng( '42', 'label' ); +$d = new Prng( '43', 'label' ); +check( $c->bytes( 64 ) !== $d->bytes( 64 ), 'Different seeds produce different streams.' ); + +$e = new Prng( '42', 'fork-test' ); +$f = new Prng( '42', 'fork-test' ); +$fork1 = $e->fork( 'x' ); +$fork2 = $f->fork( 'x' ); +check( $fork1->bytes( 32 ) === $fork2->bytes( 32 ), 'Forked streams are deterministic.' ); + +// --- utf8_codepoints -------------------------------------------------------- + +$points = utf8_codepoints( "a\u{E9}\u{1F600}" ); +check( 3 === count( $points ), 'utf8_codepoints splits into 3 codepoints.' ); +check( 0x61 === $points[0][1] && 0xE9 === $points[1][1] && 0x1F600 === $points[2][1], 'utf8_codepoints decodes values.' ); + +// --- Document generator: model matches parse for many seeds --------------- +// ( Worker::run_case checks this per case as model-desync; here only a couple +// of seeds are sampled for a fast signal. ) + +for ( $seed = 1; $seed <= 3; $seed++ ) { + $document = DocumentGenerator::generate( new Prng( (string) $seed, 'self-check-doc' ) ); + check( is_string( $document['html'] ) && '' !== $document['html'], "Document {$seed} renders." ); + check( str_contains( $document['html'], 'data-fid' ) || false !== strpos( $document['html'], 'data-fid' ), "Document {$seed} has fids." ); +} + +// --- Selector generator expectations over many seeds ----------------------- + +$by_bucket = array(); +for ( $seed = 1; $seed <= 400; $seed++ ) { + $prng = new Prng( (string) $seed, 'self-check-selector' ); + $document = DocumentGenerator::generate( $prng->fork( 'doc' ) ); + $selector = SelectorGenerator::generate( $prng->fork( 'sel' ), $document['pools'] ); + + $by_bucket[ $selector['bucket'] ] = ( $by_bucket[ $selector['bucket'] ] ?? 0 ) + 1; + + $compound = WP_CSS_Compound_Selector_List::from_selectors( $selector['selector'] ); + $complex = WP_CSS_Complex_Selector_List::from_selectors( $selector['selector'] ); + + if ( null !== $selector['expectCompound'] ) { + check( + $selector['expectCompound'] === ( null !== $compound ), + "Seed {$seed} ({$selector['bucket']}): compound parse expectation for: " . \CssSelectorFuzz\printable_bytes( $selector['selector'] ) + ); + } + if ( null !== $selector['expectComplex'] ) { + check( + $selector['expectComplex'] === ( null !== $complex ), + "Seed {$seed} ({$selector['bucket']}): complex parse expectation for: " . \CssSelectorFuzz\printable_bytes( $selector['selector'] ) + ); + } +} + +check( count( $by_bucket ) >= 5, 'Bucket variety: saw ' . count( $by_bucket ) . ' buckets.' ); + +// --- Known-answer matching cases ------------------------------------------- + +$known_html = '' + . '
' + . '
' + . ''; + +function select_fids( string $html, string $selector ): array { + $processor = WP_HTML_Processor::create_full_parser( $html ); + $out = array(); + while ( $processor->select( $selector ) ) { + $out[] = $processor->get_attribute( 'data-fid' ); + } + return $out; +} + +check( array( 'e4' ) === select_fids( $known_html, '#x' ), 'Known: #x.' ); +check( array( 'e3', 'e4' ) === select_fids( $known_html, '.b' ), 'Known: .b.' ); +check( array( 'e4' ) === select_fids( $known_html, 'div > span.b' ), 'Known: div > span.b.' ); +check( array( 'e7' ) === select_fids( $known_html, 'section em' ), 'Known: section em.' ); +check( array() === select_fids( $known_html, 'section > em' ), 'Known: section > em matches nothing.' ); +check( array( 'e4' ) === select_fids( $known_html, '[data-v|="hello"]' ), 'Known: [data-v|=hello].' ); +check( array( 'e7' ) === select_fids( $known_html, '[lang^="en"]' ), 'Known: [lang^=en].' ); + +// --- Worker end-to-end on a few seeds --------------------------------------- + +for ( $seed = 1; $seed <= 5; $seed++ ) { + $first = Worker::run_case( $seed ); + $second = Worker::run_case( $seed ); + check( $first['digest'] === $second['digest'], "Seed {$seed}: case digest is deterministic." ); +} + +if ( 0 === $failures ) { + echo "self-check OK\n"; + exit( 0 ); +} +echo "self-check FAILED: {$failures} failure(s)\n"; +exit( 1 ); diff --git a/tools/css-selector-fuzz/worker.php b/tools/css-selector-fuzz/worker.php new file mode 100644 index 0000000000000..bdcde442aa943 --- /dev/null +++ b/tools/css-selector-fuzz/worker.php @@ -0,0 +1,34 @@ +#!/usr/bin/env php + 'css-selector-fuzz-worker-fatal', + 'error' => \CssSelectorFuzz\Worker::describe_throwable( $e ), + ) + ) . "\n" + ); + exit( 1 ); +} From d01451c0f1584663881435fbe13b2e9b3dbbc175 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 13:00:32 +0200 Subject: [PATCH 157/634] CSS selector fuzz: add metamorphic invariants Oracle-free relations checked on every otherwise-clean case whose selector parses: meaning-preserving transforms (re-render with aggressive no-op escapes, type-name case fold, subclass reorder, explicit universal, list-branch duplication) must keep the select() match set byte-identical, and AST-preserving transforms must parse to exactly the transformed AST. Validated two ways: against core with the three FINDINGS.md fixes applied, 1000 seeds run clean; against unpatched core the transforms independently re-find Bug 1 (identity escapes after multibyte) and Bug 3 (off-by-one length guard) without consulting the reference matcher. ASTs containing invalid UTF-8 (parseable chaos/mutated inputs pass raw bytes through into AST names) are excluded: the renderer can only round-trip valid UTF-8. --- tools/css-selector-fuzz/README.md | 9 + tools/css-selector-fuzz/lib/Metamorph.php | 165 ++++++++++++++++++ .../lib/SelectorGenerator.php | 15 +- tools/css-selector-fuzz/lib/Worker.php | 160 +++++++++++++++-- tools/css-selector-fuzz/lib/autoload.php | 1 + 5 files changed, 337 insertions(+), 13 deletions(-) create mode 100644 tools/css-selector-fuzz/lib/Metamorph.php diff --git a/tools/css-selector-fuzz/README.md b/tools/css-selector-fuzz/README.md index 03c2c51d654f7..291bec6cab6f9 100644 --- a/tools/css-selector-fuzz/README.md +++ b/tools/css-selector-fuzz/README.md @@ -37,6 +37,15 @@ produces the same document, the same selector, and the same verdict. `_doing_it_wrong` fires exactly once per call (also via the parse cache), and the processor remains usable. - The processor ends with no `get_last_error()`/unsupported state. + - Metamorphic relations (oracle-free, run on otherwise-clean cases whose + selector parsed): meaning-preserving transforms of the selector must + select exactly the same elements as the original, and AST-preserving + transforms must parse to exactly the transformed AST. Transforms: + re-render with fresh whitespace/quoting and aggressive no-op escapes, + ASCII-case-fold of type names, subclass reordering within a compound, + explicit `*` for an omitted type, and selector-list branch duplication. + Skipped for ASTs containing invalid UTF-8 (reachable only from + chaos/mutated inputs), which the renderer cannot round-trip. - Repeating a case yields a byte-identical result digest (determinism). ## Usage diff --git a/tools/css-selector-fuzz/lib/Metamorph.php b/tools/css-selector-fuzz/lib/Metamorph.php new file mode 100644 index 0000000000000..017b65fdd09f5 --- /dev/null +++ b/tools/css-selector-fuzz/lib/Metamorph.php @@ -0,0 +1,165 @@ + + */ + public static function variants( array $list_ast, Prng $prng ): array { + /* + * The WP parser passes raw bytes through: a selector that is not + * valid UTF-8 yields AST names that are not valid UTF-8 (it does + * not substitute U+FFFD). The renderer can only round-trip valid + * UTF-8 names, so such ASTs (only reachable from chaos/mutated + * inputs) are not transformable. + */ + if ( ! self::ast_strings_are_utf8( $list_ast ) ) { + return array(); + } + + $out = array(); + + $out[] = array( + 'name' => 'rerender', + 'selector' => SelectorGenerator::render( $prng->fork( 'rerender' ), $list_ast, true ), + 'ast' => $list_ast, + 'astMustMatch' => true, + ); + + $typecase = self::map_types( + $list_ast, + static function ( string $type ) use ( $prng ): string { + if ( '*' === $type ) { + return $type; + } + $out = ''; + for ( $i = 0; $i < strlen( $type ); $i++ ) { + $c = $type[ $i ]; + $out .= $prng->chance( 50 ) ? strtoupper( $c ) : strtolower( $c ); + } + return $out; + } + ); + if ( $typecase !== $list_ast ) { + $out[] = array( + 'name' => 'typecase', + 'selector' => SelectorGenerator::render( $prng->fork( 'typecase' ), $typecase ), + 'ast' => $typecase, + 'astMustMatch' => true, + ); + } + + $reordered = self::rotate_subs( $list_ast ); + if ( $reordered !== $list_ast ) { + $out[] = array( + 'name' => 'subs-reorder', + 'selector' => SelectorGenerator::render( $prng->fork( 'subs-reorder' ), $reordered ), + 'ast' => $reordered, + 'astMustMatch' => true, + ); + } + + $universal = self::explicit_universal( $list_ast ); + if ( $universal !== $list_ast ) { + $out[] = array( + 'name' => 'universal', + 'selector' => SelectorGenerator::render( $prng->fork( 'universal' ), $universal ), + 'ast' => $universal, + 'astMustMatch' => true, + ); + } + + $duplicated = $list_ast; + $duplicated[] = $list_ast[ $prng->int( 0, count( $list_ast ) - 1 ) ]; + $out[] = array( + 'name' => 'dup-branch', + 'selector' => SelectorGenerator::render( $prng->fork( 'dup-branch' ), $duplicated ), + 'ast' => $duplicated, + 'astMustMatch' => true, + ); + + return $out; + } + + /** Whether every string anywhere in the AST is valid UTF-8. */ + private static function ast_strings_are_utf8( $node ): bool { + if ( is_string( $node ) ) { + return (bool) preg_match( '//u', $node ); + } + if ( is_array( $node ) ) { + foreach ( $node as $child ) { + if ( ! self::ast_strings_are_utf8( $child ) ) { + return false; + } + } + } + return true; + } + + /** Applies $fn to every type-selector name: compound types and context types. */ + private static function map_types( array $list_ast, callable $fn ): array { + foreach ( $list_ast as &$complex ) { + foreach ( $complex['context'] as &$pair ) { + $pair[0] = $fn( $pair[0] ); + } + unset( $pair ); + if ( null !== $complex['self']['type'] ) { + $complex['self']['type'] = $fn( $complex['self']['type'] ); + } + } + unset( $complex ); + return $list_ast; + } + + /** Rotates the subclass list of every compound that has two or more. */ + private static function rotate_subs( array $list_ast ): array { + foreach ( $list_ast as &$complex ) { + $subs = $complex['self']['subs']; + if ( is_array( $subs ) && count( $subs ) >= 2 ) { + $subs[] = array_shift( $subs ); + $complex['self']['subs'] = $subs; + } + } + unset( $complex ); + return $list_ast; + } + + /** Writes an explicit `*` wherever a compound omitted its type selector. */ + private static function explicit_universal( array $list_ast ): array { + foreach ( $list_ast as &$complex ) { + if ( null === $complex['self']['type'] && null !== $complex['self']['subs'] ) { + $complex['self']['type'] = '*'; + } + } + unset( $complex ); + return $list_ast; + } +} diff --git a/tools/css-selector-fuzz/lib/SelectorGenerator.php b/tools/css-selector-fuzz/lib/SelectorGenerator.php index 53347c083e79b..0b8f0c5c7a5f2 100644 --- a/tools/css-selector-fuzz/lib/SelectorGenerator.php +++ b/tools/css-selector-fuzz/lib/SelectorGenerator.php @@ -36,12 +36,25 @@ class SelectorGenerator { private $prng; /** @var array */ private $pools; + /** @var bool Escape ident codepoints aggressively when rendering. */ + private $escape_boost = false; private function __construct( Prng $prng, array $pools ) { $this->prng = $prng; $this->pools = $pools; } + /** + * Renders a canonical complex-list AST to a selector string. Parsing the + * result must yield exactly the given AST. With $escape_boost, idents are + * escaped far more often (exercises the escape decoder on no-op escapes). + */ + public static function render( Prng $prng, array $list_ast, bool $escape_boost = false ): string { + $generator = new self( $prng, array() ); + $generator->escape_boost = $escape_boost; + return $generator->render_complex_list( $list_ast ); + } + /** * @param array $pools Pools from DocumentGenerator ( tags, classes, ids, attrNames, attrValues ). * @return array{ @@ -520,7 +533,7 @@ private function render_ident( string $name ): string { || ( 1 === $i && '-' === $points[0][0] && $is_digit ) || ( 1 === $count && '-' === $char ); - if ( $must_escape || $this->prng->chance( 8 ) ) { + if ( $must_escape || $this->prng->chance( $this->escape_boost ? 50 : 8 ) ) { $out .= $this->render_escape( $char, $cp ); } else { $out .= $char; diff --git a/tools/css-selector-fuzz/lib/Worker.php b/tools/css-selector-fuzz/lib/Worker.php index bfa1ec2a580e2..15542649e0709 100644 --- a/tools/css-selector-fuzz/lib/Worker.php +++ b/tools/css-selector-fuzz/lib/Worker.php @@ -28,6 +28,13 @@ * - select-on-null: select() returned true for an unparseable selector. * - processor-error: the processor entered an error/unsupported state. * - case-determinism: running the full case twice gave different digests. + * - metamorphic-parse: a meaning-preserving transform of a parseable + * selector no longer parses. + * - metamorphic-ast: an AST-preserving transform parsed to a + * different AST. + * - metamorphic-mismatch: a meaning-preserving transform selected a + * different element set than the original. + * - metamorphic-error: parsing/matching a transformed selector raised. */ class Worker { @@ -172,9 +179,10 @@ static function () use ( $complex_list ) { // --- Match phase --------------------------------------------------- + $html_matches = null; if ( null !== $complex_ast ) { - $expected = ReferenceMatcher::expected_html_processor_matches( $complex_ast, $document['model'], $document['quirks'] ); - self::check_select_matches( 'html', $selector_string, $document, $expected, $record ); + $expected = ReferenceMatcher::expected_html_processor_matches( $complex_ast, $document['model'], $document['quirks'] ); + $html_matches = self::check_select_matches( 'html', $selector_string, $document, $expected, $record ); } elseif ( null === $complex_list && null === $complex_error ) { self::check_select_rejection( 'html', $selector_string, $document, $record ); } @@ -186,6 +194,15 @@ static function () use ( $complex_list ) { self::check_select_rejection( 'tag', $selector_string, $document, $record ); } + // --- Metamorphic phase ---------------------------------------------- + // Oracle-free relations: meaning-preserving transforms of the selector + // must select exactly the same elements. Run only on otherwise-clean + // cases so a single root cause does not multiply into noise. + + if ( null !== $complex_ast && null !== $html_matches && array() === $failures ) { + self::check_metamorphic( $complex_ast, $html_matches, $document, $prng->fork( 'metamorph' ), $record ); + } + $digest = sha1( json_encode_safe( array( @@ -304,19 +321,17 @@ static function () use ( $document ) { } /** - * Runs a select() loop on a parseable selector and compares the match set - * against the reference matcher. + * Runs a select() loop over the document, collecting matched data-fids. * * @param string $target 'html' or 'tag'. + * @return array{0: string[]|null, 1: \Throwable|null} */ - private static function check_select_matches( string $target, string $selector_string, array $document, array $expected, callable $record ): void { - Bootstrap::reset_doing_it_wrong(); - - list( $actual, $error ) = self::guard( - static function () use ( $target, $selector_string, $document ) { + private static function collect_matches( string $target, string $selector_string, string $html ): array { + return self::guard( + static function () use ( $target, $selector_string, $html ) { $processor = 'html' === $target - ? \WP_HTML_Processor::create_full_parser( $document['html'] ) - : new \WP_HTML_Tag_Processor( $document['html'] ); + ? \WP_HTML_Processor::create_full_parser( $html ) + : new \WP_HTML_Tag_Processor( $html ); $matches = array(); $iterations = 0; @@ -340,6 +355,19 @@ static function () use ( $target, $selector_string, $document ) { return $matches; } ); + } + + /** + * Runs a select() loop on a parseable selector and compares the match set + * against the reference matcher. + * + * @param string $target 'html' or 'tag'. + * @return string[]|null The actual match set, or null when matching failed. + */ + private static function check_select_matches( string $target, string $selector_string, array $document, array $expected, callable $record ): ?array { + Bootstrap::reset_doing_it_wrong(); + + list( $actual, $error ) = self::collect_matches( $target, $selector_string, $document['html'] ); if ( null !== $error ) { $record( @@ -349,7 +377,7 @@ static function () use ( $target, $selector_string, $document ) { 'error' => self::describe_throwable( $error ), ) ); - return; + return null; } $doing_it_wrong = Bootstrap::doing_it_wrong_calls(); @@ -372,6 +400,111 @@ static function () use ( $target, $selector_string, $document ) { ) ); } + + return $actual; + } + + /** + * Checks the metamorphic relations: each meaning-preserving transform of + * the parsed selector must parse, must (for AST-preserving transforms) + * parse to exactly the transformed AST, and must select exactly the same + * elements the original selector selected. + * + * @param array $complex_ast Canonical AST of the original selector. + * @param string[] $html_matches The original's WP_HTML_Processor match set. + */ + private static function check_metamorphic( array $complex_ast, array $html_matches, array $document, Prng $prng, callable $record ): void { + foreach ( Metamorph::variants( $complex_ast, $prng ) as $variant ) { + $transform = $variant['name']; + $variant_selector = $variant['selector']; + + list( $variant_list, $parse_error ) = self::guard( + static function () use ( $variant_selector ) { + return \WP_CSS_Complex_Selector_List::from_selectors( $variant_selector ); + } + ); + + if ( null !== $parse_error ) { + $record( + 'metamorphic-error', + array( + 'transform' => $transform, + 'selector' => printable_bytes( $variant_selector ), + 'error' => self::describe_throwable( $parse_error ), + ) + ); + continue; + } + + if ( null === $variant_list ) { + $record( + 'metamorphic-parse', + array( + 'transform' => $transform, + 'selector' => printable_bytes( $variant_selector ), + ) + ); + continue; + } + + if ( $variant['astMustMatch'] ) { + list( $variant_ast, $shape_error ) = self::guard( + static function () use ( $variant_list ) { + return AstExtractor::from_complex_list( $variant_list ); + } + ); + if ( null !== $shape_error ) { + $record( + 'metamorphic-error', + array( + 'transform' => $transform, + 'selector' => printable_bytes( $variant_selector ), + 'error' => self::describe_throwable( $shape_error ), + ) + ); + continue; + } + if ( $variant_ast !== $variant['ast'] ) { + $record( + 'metamorphic-ast', + array( + 'transform' => $transform, + 'selector' => printable_bytes( $variant_selector ), + 'expectedAst' => $variant['ast'], + 'parsedAst' => $variant_ast, + ) + ); + continue; + } + } + + Bootstrap::reset_doing_it_wrong(); + list( $variant_matches, $match_error ) = self::collect_matches( 'html', $variant_selector, $document['html'] ); + + if ( null !== $match_error ) { + $record( + 'metamorphic-error', + array( + 'transform' => $transform, + 'selector' => printable_bytes( $variant_selector ), + 'error' => self::describe_throwable( $match_error ), + ) + ); + continue; + } + + if ( $variant_matches !== $html_matches ) { + $record( + 'metamorphic-mismatch', + array( + 'transform' => $transform, + 'selector' => printable_bytes( $variant_selector ), + 'expected' => $html_matches, + 'actual' => $variant_matches, + ) + ); + } + } } /** @@ -528,6 +661,9 @@ private static function signature( array $failure ): string { if ( isset( $failure['detail']['target'] ) ) { $parts[] = $failure['detail']['target']; } + if ( isset( $failure['detail']['transform'] ) ) { + $parts[] = $failure['detail']['transform']; + } if ( isset( $failure['detail']['error']['class'] ) ) { $parts[] = $failure['detail']['error']['class']; $parts[] = preg_replace( '/[0-9]+/', 'N', (string) ( $failure['detail']['error']['message'] ?? '' ) ); diff --git a/tools/css-selector-fuzz/lib/autoload.php b/tools/css-selector-fuzz/lib/autoload.php index ffc0e572ed9c1..bc22e73f42f9c 100644 --- a/tools/css-selector-fuzz/lib/autoload.php +++ b/tools/css-selector-fuzz/lib/autoload.php @@ -6,4 +6,5 @@ require_once __DIR__ . '/SelectorGenerator.php'; require_once __DIR__ . '/AstExtractor.php'; require_once __DIR__ . '/ReferenceMatcher.php'; +require_once __DIR__ . '/Metamorph.php'; require_once __DIR__ . '/Worker.php'; From 43d2f68521025c36ef223da039a8a668bf93bb6d Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 13:07:07 +0200 Subject: [PATCH 158/634] CSS selector fuzz: add path-directed generation bucket Synthesizes selectors from a real element of the generated model tree: type from its tag, subclasses from its actual classes/id/attributes (with operators derived from the real value: prefixes, suffixes, substrings, whitespace words, hyphen prefixes, case-flipped operands under the i modifier), and a context chain drawn from its actual ancestors where > is only used for the immediately-next ancestor. The element is guaranteed by construction to be in the match set; a near-miss flip (wrong type/class/attribute, combinator tighten/loosen) inverts or preserves that guarantee. The guarantee is checked against the reference matcher as the new path-expectation invariant, so a generator/oracle disagreement is itself a finding. Positive-match rate for combinator-bearing selectors: 68.3% in this bucket vs 13.9% in supported-complex (3000-seed measurement); 1000 seeds run clean against core with the three known fixes applied. --- tools/css-selector-fuzz/README.md | 11 +- .../lib/SelectorGenerator.php | 348 +++++++++++++++++- tools/css-selector-fuzz/lib/Worker.php | 37 +- 3 files changed, 383 insertions(+), 13 deletions(-) diff --git a/tools/css-selector-fuzz/README.md b/tools/css-selector-fuzz/README.md index 291bec6cab6f9..e8a0f918a0852 100644 --- a/tools/css-selector-fuzz/README.md +++ b/tools/css-selector-fuzz/README.md @@ -12,10 +12,19 @@ produces the same document, the same selector, and the same verdict. 1. Generate a random HTML document from a structurally "safe" element set so the model tree is provably identical to the parsed tree (this is itself verified every case — `model-desync`). -2. Generate a selector in one of six buckets: +2. Generate a selector in one of seven buckets: - `supported-compound` — must parse in both grammars; carries intended AST. - `supported-complex` — uses `>`/descendant combinators; must parse only in the complex grammar; carries intended AST. + - `path-directed` — synthesized from a real element of the generated tree + (type from its tag, subclasses from its actual classes/id/attributes, + context chain from its actual ancestors), guaranteed by construction to + match that element — or flipped into a near-miss (wrong type/class/attr + guarantees a non-match; loosening `>` to descendant must keep matching). + The guarantee is asserted against the reference matcher + (`path-expectation`), making most match assertions non-vacuous: + measured positive-match rate for combinator selectors is ~68% in this + bucket vs ~14% in `supported-complex`. - `unsupported` — valid CSS the API intentionally rejects (pseudo-classes and -elements, `+`/`~`/`||` combinators, namespaces, non-type context selectors); must not parse. diff --git a/tools/css-selector-fuzz/lib/SelectorGenerator.php b/tools/css-selector-fuzz/lib/SelectorGenerator.php index 0b8f0c5c7a5f2..25490e4a90bc2 100644 --- a/tools/css-selector-fuzz/lib/SelectorGenerator.php +++ b/tools/css-selector-fuzz/lib/SelectorGenerator.php @@ -26,6 +26,7 @@ class SelectorGenerator { const BUCKETS = array( 'supported-compound', 'supported-complex', + 'path-directed', 'unsupported', 'invalid', 'chaos', @@ -56,31 +57,48 @@ public static function render( Prng $prng, array $list_ast, bool $escape_boost = } /** - * @param array $pools Pools from DocumentGenerator ( tags, classes, ids, attrNames, attrValues ). + * @param array $pools Pools from DocumentGenerator ( tags, classes, ids, attrNames, attrValues ). + * @param array|null $model Root element model; enables the path-directed bucket. * @return array{ * bucket: string, * selector: string, * expectCompound: bool|null, * expectComplex: bool|null, * ast: array|null, + * mustMatchFid: string|null, + * mustNotMatchFid: string|null, * } */ - public static function generate( Prng $prng, array $pools, ?string $bucket = null ): array { + public static function generate( Prng $prng, array $pools, ?array $model = null, ?string $bucket = null ): array { $generator = new self( $prng, $pools ); if ( null === $bucket ) { $bucket = $prng->weighted( - array( - 'supported-compound' => 30, - 'supported-complex' => 25, - 'unsupported' => 15, - 'invalid' => 12, - 'chaos' => 8, - 'mutated' => 10, - ) + null === $model + ? array( + 'supported-compound' => 30, + 'supported-complex' => 25, + 'unsupported' => 15, + 'invalid' => 12, + 'chaos' => 8, + 'mutated' => 10, + ) + : array( + 'supported-compound' => 24, + 'supported-complex' => 20, + 'path-directed' => 22, + 'unsupported' => 12, + 'invalid' => 10, + 'chaos' => 6, + 'mutated' => 6, + ) ); } + if ( 'path-directed' === $bucket && null === $model ) { + $bucket = 'supported-complex'; + } + switch ( $bucket ) { case 'supported-compound': $ast = $generator->gen_complex_list( false ); @@ -102,6 +120,9 @@ public static function generate( Prng $prng, array $pools, ?string $bucket = nul 'ast' => $ast, ); + case 'path-directed': + return $generator->gen_path_directed( $model ); + case 'unsupported': return array( 'bucket' => $bucket, @@ -399,6 +420,313 @@ private function pick_name( string $pool_key ): string { ); } + /* + * ------------------------ + * Path-directed generation + * ------------------------ + * + * Synthesizes a selector from a real element of the model tree so that + * the selector is guaranteed (by construction) to match that element: + * the type comes from its tag, subclasses from its actual classes / id / + * attributes, and the context chain from its actual ancestor tags with + * combinators consistent with the real nesting. Optionally one feature + * is then flipped into a "near-miss" that is guaranteed NOT to match + * the element ( or, for combinator loosening, still guaranteed to ). + */ + + private function gen_path_directed( array $model ): array { + $pairs = DocumentGenerator::flatten_with_ancestors( $model ); + + // Bias toward elements deep enough for a meaningful context chain. + $deep = array(); + foreach ( $pairs as $pair ) { + if ( count( $pair[1] ) >= 2 ) { + $deep[] = $pair; + } + } + if ( array() !== $deep && $this->prng->chance( 75 ) ) { + $pair = $this->prng->choice( $deep ); + } else { + $pair = $this->prng->choice( $pairs ); + } + list( $element, $ancestors ) = $pair; + + $compound = $this->path_compound_for( $element ); + $context = array() !== $ancestors && $this->prng->chance( 75 ) + ? $this->path_context_for( $ancestors ) + : array(); + + $list = array( + array( + 'context' => $context, + 'self' => $compound, + ), + ); + + $must_match = $element['fid']; + $must_not_match = null; + + if ( $this->prng->chance( 40 ) ) { + list( $list, $must_match, $must_not_match ) = $this->path_near_miss( $list, $element ); + } elseif ( $this->prng->chance( 20 ) ) { + // Extra unrelated branch: a list union can only add matches. + $list[] = $this->gen_complex( $this->prng->chance( 30 ) ); + } + + $has_context = false; + foreach ( $list as $complex ) { + if ( array() !== $complex['context'] ) { + $has_context = true; + break; + } + } + + return array( + 'bucket' => 'path-directed', + 'selector' => $this->render_complex_list( $list ), + 'expectCompound' => ! $has_context, + 'expectComplex' => true, + 'ast' => $list, + 'mustMatchFid' => $must_match, + 'mustNotMatchFid' => $must_not_match, + ); + } + + /** A compound selector built only from features the element really has. */ + private function path_compound_for( array $element ): array { + $tag = ascii_strtolower( $element['tag'] ); + + $features = array(); + + $class_value = DocumentGenerator::get_attribute_value( $element, 'class' ); + if ( is_string( $class_value ) ) { + foreach ( preg_split( '/[ \t\n\f\r]+/', $class_value, -1, PREG_SPLIT_NO_EMPTY ) as $word ) { + $features[] = array( 'kind' => 'class', 'name' => $word ); + } + } + + $id_value = DocumentGenerator::get_attribute_value( $element, 'id' ); + if ( is_string( $id_value ) && '' !== $id_value ) { + $features[] = array( 'kind' => 'id', 'name' => $id_value ); + } + + $seen_attrs = array(); + foreach ( $element['attrs'] as $attr ) { + $lower = ascii_strtolower( $attr[0] ); + if ( isset( $seen_attrs[ $lower ] ) || 'data-fid' === $lower ) { + continue; + } + $seen_attrs[ $lower ] = true; + $features[] = $this->path_attr_feature( $lower, $attr[1] ); + } + + $subs = array(); + $available = count( $features ); + if ( $available > 0 ) { + $want = min( $available, $this->prng->weighted( array( 0 => 25, 1 => 40, 2 => 25, 3 => 10 ) ) ); + for ( $i = 0; $i < $want; $i++ ) { + $at = $this->prng->int( 0, count( $features ) - 1 ); + $subs[] = $features[ $at ]; + array_splice( $features, $at, 1 ); + } + } + + $type = null; + if ( array() === $subs || $this->prng->chance( 70 ) ) { + $type = $this->prng->chance( 12 ) ? '*' : ( $this->prng->chance( 30 ) ? $this->random_case( $tag ) : $tag ); + } + + return array( + 'type' => $type, + 'subs' => array() === $subs ? null : $subs, + ); + } + + /** An attribute selector that the (name, value) pair satisfies. */ + private function path_attr_feature( string $name, $value ): array { + $presence = array( + 'kind' => 'attr', + 'name' => $this->prng->chance( 15 ) ? $this->random_case( $name ) : $name, + 'matcher' => null, + 'value' => null, + 'modifier' => null, + ); + + if ( true === $value ) { + // A boolean attribute has the empty string as its value. + $value = ''; + } + if ( ! is_string( $value ) || $this->prng->chance( 30 ) ) { + return $presence; + } + + $points = utf8_codepoints( $value ); + $total = count( $points ); + + $candidates = array( array( 'exact', $value ) ); + + foreach ( preg_split( '/[ \t\n\f\r]+/', $value, -1, PREG_SPLIT_NO_EMPTY ) as $word ) { + $candidates[] = array( 'one-of', $word ); + break; + } + + $hyphen_at = strpos( $value, '-' ); + $candidates[] = array( 'exact-or-hyphen-suffixed', false === $hyphen_at ? $value : substr( $value, 0, $hyphen_at ) ); + + if ( $total > 0 ) { + $slice = static function ( array $points, int $start, int $length ): string { + $out = ''; + for ( $i = $start; $i < $start + $length; $i++ ) { + $out .= $points[ $i ][0]; + } + return $out; + }; + + $candidates[] = array( 'prefixed', $slice( $points, 0, $this->prng->int( 1, $total ) ) ); + $length = $this->prng->int( 1, $total ); + $candidates[] = array( 'suffixed', $slice( $points, $total - $length, $length ) ); + $start = $this->prng->int( 0, $total - 1 ); + $candidates[] = array( 'contains', $slice( $points, $start, $this->prng->int( 1, $total - $start ) ) ); + } + + list( $matcher, $operand ) = $this->prng->choice( $candidates ); + + /* + * `|=` with an operand cut at a hyphen only matches when the operand + * is non-empty and actually a value prefix; an operand equal to the + * value always matches. Guard the degenerate empty-operand cases. + */ + if ( 'exact-or-hyphen-suffixed' === $matcher && '' === $operand && '' !== $value ) { + $matcher = 'exact'; + $operand = $value; + } + if ( in_array( $matcher, array( 'one-of', 'prefixed', 'suffixed', 'contains' ), true ) && '' === $operand ) { + return $presence; + } + + $modifier = null; + if ( $this->prng->chance( 25 ) ) { + if ( $this->prng->chance( 60 ) ) { + $modifier = 'case-insensitive'; + $operand = $this->random_case( $operand ); + } else { + $modifier = 'case-sensitive'; + } + } + + return array( + 'kind' => 'attr', + 'name' => $presence['name'], + 'matcher' => $matcher, + 'value' => $operand, + 'modifier' => $modifier, + ); + } + + /** + * A context chain ( right-to-left ( type, combinator ) pairs ) drawn from + * the element's real ancestors so the chain is satisfied by construction: + * `>` is only used for the immediately-next ancestor, descendant + * combinators may skip generations. + * + * @param array $ancestors Nearest-first ancestor elements. + */ + private function path_context_for( array $ancestors ): array { + $chain = array(); + $pos = 0; + $count = count( $ancestors ); + + while ( $pos < $count && ( array() === $chain || $this->prng->chance( 45 ) ) ) { + $jump = $this->prng->chance( 65 ) ? 0 : $this->prng->int( 0, $count - 1 - $pos ); + $at = $pos + $jump; + + $combinator = ( 0 === $jump && $this->prng->chance( 55 ) ) ? '>' : ' '; + $tag = ascii_strtolower( $ancestors[ $at ]['tag'] ); + $type = $this->prng->chance( 12 ) + ? '*' + : ( $this->prng->chance( 25 ) ? $this->random_case( $tag ) : $tag ); + + $chain[] = array( $type, $combinator ); + $pos = $at + 1; + } + + return $chain; + } + + /** + * Flips one feature of the guaranteed-match selector. Most flips + * guarantee the element no longer matches; loosening a `>` to a + * descendant combinator must keep it matching. + * + * @return array{0: array, 1: string|null, 2: string|null} list, mustMatchFid, mustNotMatchFid. + */ + private function path_near_miss( array $list, array $element ): array { + $complex = $list[0]; + $compound = $complex['self']; + $fid = $element['fid']; + + $flips = array( 'wrong-class', 'wrong-attr' ); + if ( null !== $compound['type'] && '*' !== $compound['type'] ) { + $flips[] = 'wrong-type'; + } + foreach ( $complex['context'] as $pair ) { + if ( '>' === $pair[1] ) { + $flips[] = 'loosen-combinator'; + } + $flips[] = 'tighten-combinator'; + break; + } + + switch ( $this->prng->choice( $flips ) ) { + case 'wrong-type': + $tag = ascii_strtolower( $element['tag'] ); + do { + $other = $this->prng->choice( DocumentGenerator::SAFE_TAGS ); + } while ( $other === $tag ); + $complex['self']['type'] = $this->prng->chance( 25 ) ? $this->random_case( $other ) : $other; + return array( array( $complex ), null, $fid ); + + case 'wrong-attr': + $subs = (array) $complex['self']['subs']; + $subs[] = array( + 'kind' => 'attr', + 'name' => 'zz-no-such-attr', + 'matcher' => null, + 'value' => null, + 'modifier' => null, + ); + $complex['self']['subs'] = $subs; + return array( array( $complex ), null, $fid ); + + case 'loosen-combinator': + // Replacing every `>` with a descendant combinator can only + // widen the context; the element must still match. + foreach ( $complex['context'] as &$pair ) { + $pair[1] = ' '; + } + unset( $pair ); + $list[0] = $complex; + return array( $list, $fid, null ); + + case 'tighten-combinator': + // May or may not still match; no membership expectation. + $at = $this->prng->int( 0, count( $complex['context'] ) - 1 ); + $complex['context'][ $at ][1] = '>'; + $list[0] = $complex; + return array( $list, null, null ); + + case 'wrong-class': + default: + $subs = (array) $complex['self']['subs']; + $subs[] = array( + 'kind' => 'class', + 'name' => 'zz-no-such-class', + ); + $complex['self']['subs'] = $subs; + return array( array( $complex ), null, $fid ); + } + } + /* * --------- * Rendering diff --git a/tools/css-selector-fuzz/lib/Worker.php b/tools/css-selector-fuzz/lib/Worker.php index 15542649e0709..59982794d4aa5 100644 --- a/tools/css-selector-fuzz/lib/Worker.php +++ b/tools/css-selector-fuzz/lib/Worker.php @@ -35,6 +35,9 @@ * - metamorphic-mismatch: a meaning-preserving transform selected a * different element set than the original. * - metamorphic-error: parsing/matching a transformed selector raised. + * - path-expectation: a path-directed selector's guaranteed + * (non-)membership does not hold in the reference + * matcher ( generator/oracle defect ). */ class Worker { @@ -57,7 +60,7 @@ public static function run_case( int $seed ): array { $prng = new Prng( (string) $seed, 'css-selector-fuzz-case' ); $document = DocumentGenerator::generate( $prng->fork( 'document' ) ); - $selector = SelectorGenerator::generate( $prng->fork( 'selector' ), $document['pools'] ); + $selector = SelectorGenerator::generate( $prng->fork( 'selector' ), $document['pools'], $document['model'] ); $failures = array(); $record = static function ( string $invariant, array $detail ) use ( &$failures ) { @@ -181,7 +184,37 @@ static function () use ( $complex_list ) { $html_matches = null; if ( null !== $complex_ast ) { - $expected = ReferenceMatcher::expected_html_processor_matches( $complex_ast, $document['model'], $document['quirks'] ); + $expected = ReferenceMatcher::expected_html_processor_matches( $complex_ast, $document['model'], $document['quirks'] ); + + /* + * Path-directed selectors are guaranteed by construction to match + * ( or, for near-misses, not to match ) a specific element. The + * reference matcher disagreeing means the generator or the + * reference matcher itself is wrong — a fuzzer-side defect. + */ + $must_match = $selector['mustMatchFid'] ?? null; + $must_not_match = $selector['mustNotMatchFid'] ?? null; + if ( null !== $must_match && ! in_array( $must_match, $expected, true ) ) { + $record( + 'path-expectation', + array( + 'expectation' => 'must-match', + 'fid' => $must_match, + 'expected' => $expected, + ) + ); + } + if ( null !== $must_not_match && in_array( $must_not_match, $expected, true ) ) { + $record( + 'path-expectation', + array( + 'expectation' => 'must-not-match', + 'fid' => $must_not_match, + 'expected' => $expected, + ) + ); + } + $html_matches = self::check_select_matches( 'html', $selector_string, $document, $expected, $record ); } elseif ( null === $complex_list && null === $complex_error ) { self::check_select_rejection( 'html', $selector_string, $document, $record ); From c97d0714e79e99e9ee67c8f076405eb353593e84 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 13:21:15 +0200 Subject: [PATCH 159/634] CSS selector fuzz: parser-derived oracle tree and wild HTML MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the model==parse-tree precondition with TreeCapture: the processor's own parse, captured once per case as flat rows in visit order (tag, attributes, nearest-first ancestor tags — context selectors are type-only, so rows are everything matching can observe). The reference matcher and path-directed generator now consume rows, which also keeps match comparison correct under restructuring: select() emits matches in visit (token) order, not final-DOM order. For safe documents the capture must still agree with the generated model (model-desync, now also covering attributes and quirks mode); that per-case soundness check is what justifies trusting the capture on wild documents. Add WildDocumentGenerator: misnesting, implied end tags and table sections, stray/unclosed tags, foreign content, and five doctype variants, tuned around the processor's unsupported constructs (it bails on foster parenting, complex adoption-agency runs, non-whitespace table text, FORM end tags over open elements); residual bails are absorbed by bounded deterministic regeneration. 1500 seeds clean against core with the three known fixes applied; all three known bug classes still detected on unpatched core. --- tools/css-selector-fuzz/README.md | 19 +- .../lib/DocumentGenerator.php | 37 ++ .../lib/ReferenceMatcher.php | 99 ++--- .../lib/SelectorGenerator.php | 46 +-- tools/css-selector-fuzz/lib/TreeCapture.php | 114 ++++++ .../lib/WildDocumentGenerator.php | 362 ++++++++++++++++++ tools/css-selector-fuzz/lib/Worker.php | 180 +++++---- tools/css-selector-fuzz/lib/autoload.php | 2 + 8 files changed, 717 insertions(+), 142 deletions(-) create mode 100644 tools/css-selector-fuzz/lib/TreeCapture.php create mode 100644 tools/css-selector-fuzz/lib/WildDocumentGenerator.php diff --git a/tools/css-selector-fuzz/README.md b/tools/css-selector-fuzz/README.md index e8a0f918a0852..48d5192927a59 100644 --- a/tools/css-selector-fuzz/README.md +++ b/tools/css-selector-fuzz/README.md @@ -9,10 +9,19 @@ produces the same document, the same selector, and the same verdict. ## What a case does -1. Generate a random HTML document from a structurally "safe" element set so - the model tree is provably identical to the parsed tree (this is itself - verified every case — `model-desync`). -2. Generate a selector in one of seven buckets: +1. Generate a random HTML document — 70% from a structurally "safe" element + set with a known model tree, 30% "wild" (misnested, implied-end-tag, + foreign-content, varied-doctype token soup with no model). +2. Capture the processor's own view of the document as the matching oracle's + ground truth (`TreeCapture`): a flat list of rows in visit order, each + carrying the element's tag, attributes, and ancestor tag list (context + selectors are type-only, so that is everything matching can observe). + For safe documents the capture must agree with the generated model + (`model-desync`) — that soundness check is what justifies trusting the + capture on wild documents. Wild documents that hit a construct the + processor bails on (foster parenting, complex adoption-agency runs) are + deterministically regenerated a bounded number of times. +3. Generate a selector in one of seven buckets: - `supported-compound` — must parse in both grammars; carries intended AST. - `supported-complex` — uses `>`/descendant combinators; must parse only in the complex grammar; carries intended AST. @@ -32,7 +41,7 @@ produces the same document, the same selector, and the same verdict. - `chaos` — arbitrary bytes; no parse expectation. - `mutated` — a supported selector with random byte mutations; no parse expectation. -3. Check invariants: +4. Check invariants: - No PHP error/warning/exception from parsing or matching, ever. - Parse result (instance vs `null`) matches the bucket's expectation. - Anything the compound grammar parses, the complex grammar parses, and diff --git a/tools/css-selector-fuzz/lib/DocumentGenerator.php b/tools/css-selector-fuzz/lib/DocumentGenerator.php index 70e3ab80d2a39..e435edce409c9 100644 --- a/tools/css-selector-fuzz/lib/DocumentGenerator.php +++ b/tools/css-selector-fuzz/lib/DocumentGenerator.php @@ -437,6 +437,43 @@ public static function flatten_with_ancestors( array $element, array $ancestors return $out; } + /** + * Flat element rows ( the TreeCapture row shape ) derived from a model: + * pre-order, tags uppercased, attribute names lowercased with the first + * of duplicates winning — directly comparable to a TreeCapture of the + * rendered document. + */ + public static function rows_from_model( array $model ): array { + $rows = array(); + foreach ( self::flatten_with_ancestors( $model ) as $pair ) { + list( $element, $ancestors ) = $pair; + + $attrs = array(); + $seen = array(); + foreach ( $element['attrs'] as $attr ) { + $lower = ascii_strtolower( $attr[0] ); + if ( isset( $seen[ $lower ] ) ) { + continue; + } + $seen[ $lower ] = true; + $attrs[] = array( $lower, $attr[1] ); + } + + $ancestor_tags = array(); + foreach ( $ancestors as $ancestor ) { + $ancestor_tags[] = strtoupper( ascii_strtolower( $ancestor['tag'] ) ); + } + + $rows[] = array( + 'tag' => strtoupper( ascii_strtolower( $element['tag'] ) ), + 'fid' => $element['fid'], + 'attrs' => $attrs, + 'ancestorTags' => $ancestor_tags, + ); + } + return $rows; + } + /** First attribute value for a name, ASCII case-insensitive; null if absent. */ public static function get_attribute_value( array $element, string $name ) { $comparable = ascii_strtolower( $name ); diff --git a/tools/css-selector-fuzz/lib/ReferenceMatcher.php b/tools/css-selector-fuzz/lib/ReferenceMatcher.php index fd834a543041d..6af3301cd080b 100644 --- a/tools/css-selector-fuzz/lib/ReferenceMatcher.php +++ b/tools/css-selector-fuzz/lib/ReferenceMatcher.php @@ -2,9 +2,14 @@ namespace CssSelectorFuzz; /** - * Independent implementation of the supported CSS selector semantics, - * operating on the document model produced by DocumentGenerator and the - * canonical selector AST. + * Independent implementation of the supported CSS selector semantics. + * + * Operates on flat element "rows" in visit order — either derived from the + * generated document model or captured from the processor itself + * ( TreeCapture ). Each row carries the element's tag, attributes, and + * ( for the html processor view ) its nearest-first ancestor tag list, + * which is all the supported grammar can observe: context selectors are + * type-only. * * Semantics follow the CSS Selectors Level 4 specification: * - Tag names match ASCII case-insensitively (HTML documents). @@ -24,19 +29,18 @@ class ReferenceMatcher { const WHITESPACE = " \t\r\n\f"; /** - * Expected match list for WP_HTML_Processor::select() over a full document. + * Expected match list for WP_HTML_Processor::select(). * * @param array $list_ast Canonical complex selector list AST. - * @param array $model Root element model ( the `html` element ). + * @param array $rows Element rows in visit order, with ancestorTags. * @param bool $quirks Whether the document parses in quirks mode. - * @return string[] data-fid values in document order. + * @return string[] data-fid values in visit order. */ - public static function expected_html_processor_matches( array $list_ast, array $model, bool $quirks ): array { + public static function expected_html_matches_rows( array $list_ast, array $rows, bool $quirks ): array { $out = array(); - foreach ( DocumentGenerator::flatten_with_ancestors( $model ) as $pair ) { - list( $element, $ancestors ) = $pair; - if ( self::list_matches( $list_ast, $element, $ancestors, $quirks ) ) { - $out[] = $element['fid']; + foreach ( $rows as $row ) { + if ( self::list_matches_row( $list_ast, $row, $quirks ) ) { + $out[] = $row['fid']; } } return $out; @@ -48,39 +52,48 @@ public static function expected_html_processor_matches( array $list_ast, array $ * compound selector list never inspects ancestors. * * @param array $list_ast Canonical complex selector list AST ( contexts must be empty ). - * @param array $model Root element model. - * @return string[] data-fid values in document order. + * @param array $rows Tag-view element rows in token order. + * @return string[] data-fid values in token order. */ - public static function expected_tag_processor_matches( array $list_ast, array $model ): array { + public static function expected_tag_matches_rows( array $list_ast, array $rows ): array { $out = array(); - foreach ( DocumentGenerator::flatten( $model ) as $element ) { - if ( self::list_matches( $list_ast, $element, array(), false ) ) { - $out[] = $element['fid']; + foreach ( $rows as $row ) { + $matched = false; + foreach ( $list_ast as $complex ) { + if ( self::compound_matches( $complex['self'], $row, false ) ) { + $matched = true; + break; + } + } + if ( $matched ) { + $out[] = $row['fid']; } } return $out; } - public static function list_matches( array $list_ast, array $element, array $ancestors, bool $quirks ): bool { + /** Back-compat: expected html-processor matches from a generated model. */ + public static function expected_html_processor_matches( array $list_ast, array $model, bool $quirks ): array { + return self::expected_html_matches_rows( $list_ast, DocumentGenerator::rows_from_model( $model ), $quirks ); + } + + /** Back-compat: expected tag-processor matches from a generated model. */ + public static function expected_tag_processor_matches( array $list_ast, array $model ): array { + return self::expected_tag_matches_rows( $list_ast, DocumentGenerator::rows_from_model( $model ) ); + } + + public static function list_matches_row( array $list_ast, array $row, bool $quirks ): bool { foreach ( $list_ast as $complex ) { - if ( self::complex_matches( $complex, $element, $ancestors, $quirks ) ) { + if ( + self::compound_matches( $complex['self'], $row, $quirks ) && + self::explore_context( $complex['context'], $row['ancestorTags'] ) + ) { return true; } } return false; } - private static function complex_matches( array $complex, array $element, array $ancestors, bool $quirks ): bool { - if ( ! self::compound_matches( $complex['self'], $element, $quirks ) ) { - return false; - } - $ancestor_tags = array(); - foreach ( $ancestors as $ancestor ) { - $ancestor_tags[] = $ancestor['tag']; - } - return self::explore_context( $complex['context'], $ancestor_tags ); - } - /** * @param array $context Right-to-left ( type, combinator ) pairs. * @param string[] $ancestor_tags Nearest-ancestor-first tag names. @@ -114,12 +127,12 @@ private static function explore_context( array $context, array $ancestor_tags ): return false; } - public static function compound_matches( array $compound, array $element, bool $quirks ): bool { - if ( null !== $compound['type'] && ! self::type_matches( $compound['type'], $element['tag'] ) ) { + public static function compound_matches( array $compound, array $row, bool $quirks ): bool { + if ( null !== $compound['type'] && ! self::type_matches( $compound['type'], $row['tag'] ) ) { return false; } foreach ( (array) $compound['subs'] as $sub ) { - if ( ! self::sub_matches( $sub, $element, $quirks ) ) { + if ( ! self::sub_matches( $sub, $row, $quirks ) ) { return false; } } @@ -130,20 +143,20 @@ private static function type_matches( string $type, string $tag ): bool { return '*' === $type || ascii_strtolower( $type ) === ascii_strtolower( $tag ); } - private static function sub_matches( array $sub, array $element, bool $quirks ): bool { + private static function sub_matches( array $sub, array $row, bool $quirks ): bool { switch ( $sub['kind'] ) { case 'class': - return self::class_matches( $sub['name'], $element, $quirks ); + return self::class_matches( $sub['name'], $row, $quirks ); case 'id': - return self::id_matches( $sub['name'], $element, $quirks ); + return self::id_matches( $sub['name'], $row, $quirks ); case 'attr': - return self::attr_matches( $sub, $element ); + return self::attr_matches( $sub, $row ); } return false; } - private static function class_matches( string $wanted, array $element, bool $quirks ): bool { - $class_value = DocumentGenerator::get_attribute_value( $element, 'class' ); + private static function class_matches( string $wanted, array $row, bool $quirks ): bool { + $class_value = DocumentGenerator::get_attribute_value( $row, 'class' ); if ( ! is_string( $class_value ) ) { return false; } @@ -170,8 +183,8 @@ private static function class_matches( string $wanted, array $element, bool $qui return false; } - private static function id_matches( string $wanted, array $element, bool $quirks ): bool { - $id = DocumentGenerator::get_attribute_value( $element, 'id' ); + private static function id_matches( string $wanted, array $row, bool $quirks ): bool { + $id = DocumentGenerator::get_attribute_value( $row, 'id' ); if ( ! is_string( $id ) ) { return false; } @@ -180,8 +193,8 @@ private static function id_matches( string $wanted, array $element, bool $quirks : $id === $wanted; } - private static function attr_matches( array $sub, array $element ): bool { - $attr_value = DocumentGenerator::get_attribute_value( $element, $sub['name'] ); + private static function attr_matches( array $sub, array $row ): bool { + $attr_value = DocumentGenerator::get_attribute_value( $row, $sub['name'] ); if ( null === $attr_value ) { return false; } diff --git a/tools/css-selector-fuzz/lib/SelectorGenerator.php b/tools/css-selector-fuzz/lib/SelectorGenerator.php index 25490e4a90bc2..a7956ce709e11 100644 --- a/tools/css-selector-fuzz/lib/SelectorGenerator.php +++ b/tools/css-selector-fuzz/lib/SelectorGenerator.php @@ -58,7 +58,8 @@ public static function render( Prng $prng, array $list_ast, bool $escape_boost = /** * @param array $pools Pools from DocumentGenerator ( tags, classes, ids, attrNames, attrValues ). - * @param array|null $model Root element model; enables the path-directed bucket. + * @param array|null $rows Element rows ( TreeCapture shape ) with real + * fids; enables the path-directed bucket. * @return array{ * bucket: string, * selector: string, @@ -69,12 +70,12 @@ public static function render( Prng $prng, array $list_ast, bool $escape_boost = * mustNotMatchFid: string|null, * } */ - public static function generate( Prng $prng, array $pools, ?array $model = null, ?string $bucket = null ): array { + public static function generate( Prng $prng, array $pools, ?array $rows = null, ?string $bucket = null ): array { $generator = new self( $prng, $pools ); if ( null === $bucket ) { $bucket = $prng->weighted( - null === $model + null === $rows || array() === $rows ? array( 'supported-compound' => 30, 'supported-complex' => 25, @@ -95,7 +96,7 @@ public static function generate( Prng $prng, array $pools, ?array $model = null, ); } - if ( 'path-directed' === $bucket && null === $model ) { + if ( 'path-directed' === $bucket && ( null === $rows || array() === $rows ) ) { $bucket = 'supported-complex'; } @@ -121,7 +122,7 @@ public static function generate( Prng $prng, array $pools, ?array $model = null, ); case 'path-directed': - return $generator->gen_path_directed( $model ); + return $generator->gen_path_directed( $rows ); case 'unsupported': return array( @@ -434,26 +435,21 @@ private function pick_name( string $pool_key ): string { * the element ( or, for combinator loosening, still guaranteed to ). */ - private function gen_path_directed( array $model ): array { - $pairs = DocumentGenerator::flatten_with_ancestors( $model ); - + private function gen_path_directed( array $rows ): array { // Bias toward elements deep enough for a meaningful context chain. $deep = array(); - foreach ( $pairs as $pair ) { - if ( count( $pair[1] ) >= 2 ) { - $deep[] = $pair; + foreach ( $rows as $row ) { + if ( count( $row['ancestorTags'] ) >= 2 ) { + $deep[] = $row; } } - if ( array() !== $deep && $this->prng->chance( 75 ) ) { - $pair = $this->prng->choice( $deep ); - } else { - $pair = $this->prng->choice( $pairs ); - } - list( $element, $ancestors ) = $pair; + $element = array() !== $deep && $this->prng->chance( 75 ) + ? $this->prng->choice( $deep ) + : $this->prng->choice( $rows ); $compound = $this->path_compound_for( $element ); - $context = array() !== $ancestors && $this->prng->chance( 75 ) - ? $this->path_context_for( $ancestors ) + $context = array() !== $element['ancestorTags'] && $this->prng->chance( 75 ) + ? $this->path_context_for( $element['ancestorTags'] ) : array(); $list = array( @@ -492,7 +488,7 @@ private function gen_path_directed( array $model ): array { ); } - /** A compound selector built only from features the element really has. */ + /** A compound selector built only from features the element row really has. */ private function path_compound_for( array $element ): array { $tag = ascii_strtolower( $element['tag'] ); @@ -513,7 +509,7 @@ private function path_compound_for( array $element ): array { $seen_attrs = array(); foreach ( $element['attrs'] as $attr ) { $lower = ascii_strtolower( $attr[0] ); - if ( isset( $seen_attrs[ $lower ] ) || 'data-fid' === $lower ) { + if ( isset( $seen_attrs[ $lower ] ) ) { continue; } $seen_attrs[ $lower ] = true; @@ -629,19 +625,19 @@ private function path_attr_feature( string $name, $value ): array { * `>` is only used for the immediately-next ancestor, descendant * combinators may skip generations. * - * @param array $ancestors Nearest-first ancestor elements. + * @param string[] $ancestor_tags Nearest-first ancestor tag names. */ - private function path_context_for( array $ancestors ): array { + private function path_context_for( array $ancestor_tags ): array { $chain = array(); $pos = 0; - $count = count( $ancestors ); + $count = count( $ancestor_tags ); while ( $pos < $count && ( array() === $chain || $this->prng->chance( 45 ) ) ) { $jump = $this->prng->chance( 65 ) ? 0 : $this->prng->int( 0, $count - 1 - $pos ); $at = $pos + $jump; $combinator = ( 0 === $jump && $this->prng->chance( 55 ) ) ? '>' : ' '; - $tag = ascii_strtolower( $ancestors[ $at ]['tag'] ); + $tag = ascii_strtolower( $ancestor_tags[ $at ] ); $type = $this->prng->chance( 12 ) ? '*' : ( $this->prng->chance( 25 ) ? $this->random_case( $tag ) : $tag ); diff --git a/tools/css-selector-fuzz/lib/TreeCapture.php b/tools/css-selector-fuzz/lib/TreeCapture.php new file mode 100644 index 0000000000000..9edc3b0541757 --- /dev/null +++ b/tools/css-selector-fuzz/lib/TreeCapture.php @@ -0,0 +1,114 @@ +, + * ancestorTags: string[] nearest-first ) + * tag row: same without ancestorTags. + */ +class TreeCapture { + + const CAPTURE_ITERATION_LIMIT = 20000; + + /** + * @return array{ + * htmlRows: array|null, + * tagRows: array|null, + * quirks: bool, + * error: string|null, + * } + */ + public static function capture( string $html ): array { + $out = array( + 'htmlRows' => null, + 'tagRows' => null, + 'quirks' => false, + 'error' => null, + ); + + $processor = \WP_HTML_Processor::create_full_parser( $html ); + $rows = array(); + $iterations = 0; + while ( $processor->next_tag() ) { + if ( ++$iterations > self::CAPTURE_ITERATION_LIMIT ) { + $out['error'] = 'html-capture-iteration-limit'; + return $out; + } + $breadcrumbs = $processor->get_breadcrumbs(); + array_pop( $breadcrumbs ); + $rows[] = array( + 'tag' => (string) $processor->get_tag(), + 'fid' => self::fid_of( $processor ), + 'attrs' => self::attrs_of( $processor ), + 'ancestorTags' => array_reverse( $breadcrumbs ), + ); + } + + if ( null !== $processor->get_last_error() ) { + $out['error'] = 'html-processor-error: ' . $processor->get_last_error(); + return $out; + } + if ( null !== $processor->get_unsupported_exception() ) { + $out['error'] = 'html-processor-unsupported: ' . $processor->get_unsupported_exception()->getMessage(); + return $out; + } + + $out['htmlRows'] = $rows; + $out['quirks'] = $processor->is_quirks_mode(); + + $tag_processor = new \WP_HTML_Tag_Processor( $html ); + $tag_rows = array(); + $iterations = 0; + while ( $tag_processor->next_tag() ) { + if ( ++$iterations > self::CAPTURE_ITERATION_LIMIT ) { + $out['error'] = 'tag-capture-iteration-limit'; + return $out; + } + $tag_rows[] = array( + 'tag' => (string) $tag_processor->get_tag(), + 'fid' => self::fid_of( $tag_processor ), + 'attrs' => self::attrs_of( $tag_processor ), + ); + } + $out['tagRows'] = $tag_rows; + + return $out; + } + + /** The element's data-fid, or the same placeholder collect_matches() uses. */ + private static function fid_of( $processor ): string { + $fid = $processor->get_attribute( 'data-fid' ); + return is_string( $fid ) ? $fid : '(missing-fid:' . $processor->get_tag() . ')'; + } + + /** + * All attributes as ( lowercase name, decoded value ) pairs, excluding + * data-fid ( stored separately, mirroring the generated model's shape ). + * + * @return array + */ + private static function attrs_of( $processor ): array { + $attrs = array(); + foreach ( (array) $processor->get_attribute_names_with_prefix( '' ) as $name ) { + if ( 'data-fid' === $name ) { + continue; + } + $value = $processor->get_attribute( $name ); + $attrs[] = array( $name, true === $value ? true : (string) $value ); + } + return $attrs; + } +} diff --git a/tools/css-selector-fuzz/lib/WildDocumentGenerator.php b/tools/css-selector-fuzz/lib/WildDocumentGenerator.php new file mode 100644 index 0000000000000..78ae5a329f162 --- /dev/null +++ b/tools/css-selector-fuzz/lib/WildDocumentGenerator.php @@ -0,0 +1,362 @@ + '', + 'html' => '', + 'legacy-compat' => '', + 'quirky' => '', + 'limited' => '', + ); + + /** @var Prng */ + private $prng; + private $fid_counter = 0; + private $pools; + + private function __construct( Prng $prng ) { + $this->prng = $prng; + $this->pools = array( + 'tags' => array( 'html', 'head', 'body' ), + 'classes' => array(), + 'ids' => array(), + 'attrNames' => array(), + 'attrValues' => array(), + ); + } + + /** + * @return array{model: null, html: string, pools: array, wild: true, doctype: string} + */ + public static function generate( Prng $prng ): array { + $generator = new self( $prng ); + return $generator->build(); + } + + private function build(): array { + $doctype_kind = $this->prng->weighted( + array( + 'none' => 25, + 'html' => 45, + 'legacy-compat' => 10, + 'quirky' => 12, + 'limited' => 8, + ) + ); + + $out = self::DOCTYPES[ $doctype_kind ]; + + if ( $this->prng->chance( 15 ) ) { + $out .= 'render_attrs( $this->random_attrs() ) . '>'; + } + if ( $this->prng->chance( 10 ) ) { + $out .= 'render_attrs( $this->random_attrs() ) . '>'; + } + + $max_elements = $this->prng->int( 4, 35 ); + $token_budget = $this->prng->int( 8, 70 ); + $open = array(); + + for ( $i = 0; $i < $token_budget; $i++ ) { + $in_table = $this->in_table_context( $open ); + + $kind = $this->prng->weighted( + array( + 'start' => 42, + 'void' => $in_table ? 0 : 8, + 'end' => 24, + 'text' => 16, + 'comment' => 5, + 'stray' => $in_table ? 0 : 5, + ) + ); + + switch ( $kind ) { + case 'start': + if ( $this->fid_counter >= $max_elements ) { + break; + } + $tag = $in_table + ? $this->prng->choice( array( 'caption', 'colgroup', 'thead', 'tbody', 'tfoot', 'tr', 'tr', 'td', 'td', 'th' ) ) + : $this->prng->choice( self::TAGS ); + if ( 'a' === $tag && in_array( 'a', $open, true ) ) { + // A nested
immediately runs the adoption agency. + $tag = 'span'; + } + $this->pools['tags'][] = $tag; + $out .= '<' . $this->maybe_case( $tag ) + . ' data-fid="w' . $this->fid_counter++ . '"' + . $this->render_attrs( $this->random_attrs() ) . '>'; + $open[] = $tag; + break; + + case 'void': + if ( $this->fid_counter >= $max_elements ) { + break; + } + $tag = $this->prng->choice( self::VOID_TAGS ); + $this->pools['tags'][] = $tag; + $out .= '<' . $this->maybe_case( $tag ) + . ' data-fid="w' . $this->fid_counter++ . '"' + . $this->render_attrs( $this->random_attrs() ) + . ( $this->prng->chance( 25 ) ? ' />' : '>' ); + break; + + case 'end': + if ( array() === $open ) { + break; + } + $pick = $this->prng->weighted( + array( + 'top' => 60, + 'random' => 40, + ) + ); + if ( 'top' === $pick ) { + $tag = array_pop( $open ); + } else { + /* + * Close a non-top open element: misnesting. Never + * across a formatting element — the processor only + * supports the trivial adoption-agency cases and + * bails on the rest ( "any other end tag" / + * "common ancestor" / reconstruction-with-rewind ). + */ + $formatting = array( 'a', 'b', 'i', 'em', 'strong', 'u', 's', 'code', 'small' ); + $lowest = count( $open ) - 1; + while ( $lowest > 0 && ! in_array( $open[ $lowest ], $formatting, true ) ) { + $lowest--; + } + if ( in_array( $open[ $lowest ], $formatting, true ) ) { + $lowest++; + } + if ( $lowest > count( $open ) - 1 ) { + $tag = array_pop( $open ); + } else { + $at = $this->prng->int( $lowest, count( $open ) - 1 ); + $tag = $open[ $at ]; + array_splice( $open, $at, 1 ); + } + } + $out .= 'maybe_case( $tag ) . '>'; + break; + + case 'text': + // Non-whitespace text in table context is unsupported + // (pending-table-character-tokens), keep it whitespace. + $out .= $in_table + ? "\n " + : $this->prng->choice( + array( + 'text', + ' wild text ', + "\n", + '& <x>', + 'café ✓', + 'a < b', + ) + ); + break; + + case 'comment': + $out .= ''; + break; + + case 'stray': + // An end tag for something that is not open. + // No formatting tags here: a stray formatting end tag + // runs the adoption agency's unsupported branches. + $out .= 'prng->choice( array( 'div', 'p', 'table', 'tr', 'li', 'span', 'x-wild' ) ) . '>'; + break; + } + } + + // Leave roughly half of the still-open elements unclosed. + foreach ( array_reverse( $open ) as $tag ) { + if ( $this->prng->chance( 50 ) ) { + $out .= 'maybe_case( $tag ) . '>'; + } + } + + foreach ( $this->pools as $key => $values ) { + $this->pools[ $key ] = array_values( array_unique( $values ) ); + } + + return array( + 'model' => null, + 'html' => $out, + 'pools' => $this->pools, + 'wild' => true, + 'doctype' => $doctype_kind, + ); + } + + /** + * Whether the insertion point is in table context outside any cell or + * caption — where arbitrary content would foster-parent (unsupported). + */ + private function in_table_context( array $open ): bool { + for ( $i = count( $open ) - 1; $i >= 0; $i-- ) { + $tag = $open[ $i ]; + if ( in_array( $tag, array( 'td', 'th', 'caption' ), true ) ) { + return false; + } + if ( in_array( $tag, array( 'table', 'thead', 'tbody', 'tfoot', 'tr', 'colgroup' ), true ) ) { + return true; + } + } + return false; + } + + /** @return array */ + private function random_attrs(): array { + $attrs = array(); + $count = $this->prng->weighted( array( 0 => 30, 1 => 35, 2 => 25, 3 => 10 ) ); + + for ( $i = 0; $i < $count; $i++ ) { + $name = $this->prng->choice( DocumentGenerator::ATTR_NAMES ); + + $lower = ascii_strtolower( $name ); + if ( 'class' === $lower ) { + $words = array(); + $n = $this->prng->int( 1, 3 ); + for ( $j = 0; $j < $n; $j++ ) { + $word = $this->random_word(); + $words[] = $word; + $this->pools['classes'][] = $word; + } + $value = implode( ' ', $words ); + } elseif ( 'id' === $lower ) { + $value = $this->random_word(); + $this->pools['ids'][] = $value; + } elseif ( $this->prng->chance( 15 ) ) { + $value = true; + } else { + $value = $this->random_word(); + if ( $this->prng->chance( 20 ) ) { + $value .= ' ' . $this->random_word(); + } + } + + $this->pools['attrNames'][] = $lower; + if ( is_string( $value ) ) { + $this->pools['attrValues'][] = $value; + } + $attrs[] = array( $name, $value ); + } + + return $attrs; + } + + private function render_attrs( array $attrs ): string { + $out = ''; + foreach ( $attrs as $attr ) { + list( $name, $value ) = $attr; + if ( true === $value ) { + $out .= ' ' . $name; + continue; + } + $out .= ' ' . $name . '="' . str_replace( array( '&', '"', '<' ), array( '&', '"', '<' ), $value ) . '"'; + } + return $out; + } + + private function random_word(): string { + $stems = array( 'wild', 'soup', 'alpha', 'beta', 'item', 'note', 'x', 'mixedCase', 'Über', 'main-thing', '--var', '_u' ); + $word = $this->prng->choice( $stems ); + if ( $this->prng->chance( 30 ) ) { + $word .= (string) $this->prng->int( 0, 99 ); + } + return $word; + } + + private function maybe_case( string $tag ): string { + if ( ! $this->prng->chance( 15 ) ) { + return $tag; + } + $out = ''; + for ( $i = 0; $i < strlen( $tag ); $i++ ) { + $c = $tag[ $i ]; + $out .= $this->prng->chance( 50 ) ? strtoupper( $c ) : strtolower( $c ); + } + return $out; + } +} diff --git a/tools/css-selector-fuzz/lib/Worker.php b/tools/css-selector-fuzz/lib/Worker.php index 59982794d4aa5..df7e48e8506e2 100644 --- a/tools/css-selector-fuzz/lib/Worker.php +++ b/tools/css-selector-fuzz/lib/Worker.php @@ -58,9 +58,8 @@ class Worker { public static function run_case( int $seed ): array { Bootstrap::load(); - $prng = new Prng( (string) $seed, 'css-selector-fuzz-case' ); - $document = DocumentGenerator::generate( $prng->fork( 'document' ) ); - $selector = SelectorGenerator::generate( $prng->fork( 'selector' ), $document['pools'], $document['model'] ); + $prng = new Prng( (string) $seed, 'css-selector-fuzz-case' ); + $is_wild = $prng->chance( 30 ); $failures = array(); $record = static function ( string $invariant, array $detail ) use ( &$failures ) { @@ -70,7 +69,70 @@ public static function run_case( int $seed ): array { ); }; - self::check_document_model( $document, $record ); + /* + * The processor's own parse is the matching oracle's ground truth. + * For safe (model-built) documents the model must agree with the + * capture — that soundness check is what lets the capture be trusted + * on wild documents, where no model exists. + * + * Wild documents that hit one of the processor's unsupported + * constructs (it bails on foster parenting, complex adoption-agency + * runs, …) are deterministically regenerated a bounded number of + * times so nearly every wild case carries a usable ground truth. + */ + $document = null; + $capture = null; + $capture_error = null; + $attempts = $is_wild ? 8 : 1; + for ( $attempt = 0; $attempt < $attempts; $attempt++ ) { + $document = $is_wild + ? WildDocumentGenerator::generate( $prng->fork( "wild-document:{$attempt}" ) ) + : DocumentGenerator::generate( $prng->fork( 'document' ) ); + + list( $capture, $capture_error ) = self::guard( + static function () use ( $document ) { + return TreeCapture::capture( $document['html'] ); + } + ); + + if ( null === $capture_error && null === $capture['error'] ) { + break; + } + } + + $rows = null; + $tag_rows = null; + $quirks = false; + + if ( null !== $capture_error ) { + $record( 'model-desync', array( 'phase' => 'capture', 'error' => self::describe_throwable( $capture_error ) ) ); + } elseif ( null !== $capture['error'] ) { + if ( ! $is_wild ) { + $record( 'model-desync', array( 'phase' => 'capture', 'error' => $capture['error'] ) ); + } + // Wild markup the processor cannot fully visit is skipped: + // parsing invariants still run, matching has no ground truth. + } else { + $rows = $capture['htmlRows']; + $tag_rows = $capture['tagRows']; + $quirks = $capture['quirks']; + + if ( ! $is_wild ) { + self::check_capture_against_model( $document, $capture, $record ); + } + } + + $path_rows = null; + if ( null !== $rows ) { + $path_rows = array(); + foreach ( $rows as $row ) { + if ( 0 !== strpos( $row['fid'], '(missing-fid:' ) ) { + $path_rows[] = $row; + } + } + } + + $selector = SelectorGenerator::generate( $prng->fork( 'selector' ), $document['pools'], $path_rows ); $selector_string = $selector['selector']; @@ -183,8 +245,8 @@ static function () use ( $complex_list ) { // --- Match phase --------------------------------------------------- $html_matches = null; - if ( null !== $complex_ast ) { - $expected = ReferenceMatcher::expected_html_processor_matches( $complex_ast, $document['model'], $document['quirks'] ); + if ( null !== $complex_ast && null !== $rows ) { + $expected = ReferenceMatcher::expected_html_matches_rows( $complex_ast, $rows, $quirks ); /* * Path-directed selectors are guaranteed by construction to match @@ -220,8 +282,8 @@ static function () use ( $complex_list ) { self::check_select_rejection( 'html', $selector_string, $document, $record ); } - if ( null !== $compound_ast ) { - $expected = ReferenceMatcher::expected_tag_processor_matches( $compound_ast, $document['model'] ); + if ( null !== $compound_ast && null !== $tag_rows ) { + $expected = ReferenceMatcher::expected_tag_matches_rows( $compound_ast, $tag_rows ); self::check_select_matches( 'tag', $selector_string, $document, $expected, $record ); } elseif ( null === $compound_list && null === $compound_error ) { self::check_select_rejection( 'tag', $selector_string, $document, $record ); @@ -266,45 +328,38 @@ static function ( $failure ) { } /** - * Verifies that both processors see exactly the modeled element list — - * this guards the oracle itself against renderer/model drift. + * Verifies that the processor's captured view of a safe (model-built) + * document agrees with the generated model — this guards the oracle + * itself against renderer/model drift, and is what justifies trusting + * the capture on wild documents. */ - private static function check_document_model( array $document, callable $record ): void { - $expected = array(); - foreach ( DocumentGenerator::flatten_with_ancestors( $document['model'] ) as $pair ) { - list( $element, $ancestors ) = $pair; - $expected[] = array( - strtoupper( ascii_strtolower( $element['tag'] ) ), - $element['fid'], - count( $ancestors ) + 1, - ); - } - - list( $actual, $error ) = self::guard( - static function () use ( $document ) { - $processor = \WP_HTML_Processor::create_full_parser( $document['html'] ); - $out = array(); - while ( $processor->next_tag() ) { - $fid = $processor->get_attribute( 'data-fid' ); - $out[] = array( - (string) $processor->get_tag(), - is_string( $fid ) ? $fid : '(missing)', - count( $processor->get_breadcrumbs() ), - ); + private static function check_capture_against_model( array $document, array $capture, callable $record ): void { + $model_rows = DocumentGenerator::rows_from_model( $document['model'] ); + + $normalize = static function ( array $rows, bool $with_ancestors ): array { + $out = array(); + foreach ( $rows as $row ) { + $attrs = array(); + foreach ( $row['attrs'] as $attr ) { + $attrs[ $attr[0] ] = $attr[1]; } - if ( null !== $processor->get_last_error() ) { - throw new \RuntimeException( 'Processor error: ' . $processor->get_last_error() ); + ksort( $attrs ); + $normalized = array( + 'tag' => $row['tag'], + 'fid' => $row['fid'], + 'attrs' => $attrs, + ); + if ( $with_ancestors ) { + $normalized['ancestorTags'] = $row['ancestorTags']; } - return $out; + $out[] = $normalized; } - ); - - if ( null !== $error ) { - $record( 'model-desync', array( 'processor' => 'html', 'error' => self::describe_throwable( $error ) ) ); - return; - } + return $out; + }; - if ( $actual !== $expected ) { + $expected = $normalize( $model_rows, true ); + $actual = $normalize( $capture['htmlRows'], true ); + if ( $expected !== $actual ) { $record( 'model-desync', array( @@ -315,33 +370,9 @@ static function () use ( $document ) { ); } - // The tag processor must see the same elements ( without breadcrumbs ). - $expected_tags = array(); - foreach ( $expected as $row ) { - $expected_tags[] = array( $row[0], $row[1] ); - } - - list( $actual_tags, $tag_error ) = self::guard( - static function () use ( $document ) { - $processor = new \WP_HTML_Tag_Processor( $document['html'] ); - $out = array(); - while ( $processor->next_tag() ) { - $fid = $processor->get_attribute( 'data-fid' ); - $out[] = array( - (string) $processor->get_tag(), - is_string( $fid ) ? $fid : '(missing)', - ); - } - return $out; - } - ); - - if ( null !== $tag_error ) { - $record( 'model-desync', array( 'processor' => 'tag', 'error' => self::describe_throwable( $tag_error ) ) ); - return; - } - - if ( $actual_tags !== $expected_tags ) { + $expected_tags = $normalize( $model_rows, false ); + $actual_tags = $normalize( $capture['tagRows'], false ); + if ( $expected_tags !== $actual_tags ) { $record( 'model-desync', array( @@ -351,6 +382,17 @@ static function () use ( $document ) { ) ); } + + if ( $document['quirks'] !== $capture['quirks'] ) { + $record( + 'model-desync', + array( + 'processor' => 'quirks', + 'expected' => $document['quirks'], + 'actual' => $capture['quirks'], + ) + ); + } } /** diff --git a/tools/css-selector-fuzz/lib/autoload.php b/tools/css-selector-fuzz/lib/autoload.php index bc22e73f42f9c..2a26cbdb9f407 100644 --- a/tools/css-selector-fuzz/lib/autoload.php +++ b/tools/css-selector-fuzz/lib/autoload.php @@ -3,6 +3,8 @@ require_once __DIR__ . '/Prng.php'; require_once __DIR__ . '/Bootstrap.php'; require_once __DIR__ . '/DocumentGenerator.php'; +require_once __DIR__ . '/WildDocumentGenerator.php'; +require_once __DIR__ . '/TreeCapture.php'; require_once __DIR__ . '/SelectorGenerator.php'; require_once __DIR__ . '/AstExtractor.php'; require_once __DIR__ . '/ReferenceMatcher.php'; From 37ec7f0a238082ff0daef8d75f13ec5b421288ef Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 13:34:37 +0200 Subject: [PATCH 160/634] CSS selector fuzz: add lexbor differential oracle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Third, independent matching opinion alongside the WP implementation and the fuzzer's ReferenceMatcher. A batched C harness (lexbor/harness.c, built by lexbor/build.sh against liblexbor pinned to v3.0.0) reads {html, selector} cases over a persistent pipe and answers with lexbor's element tree and matched data-fid sets; the worker auto-detects it. The differential runs on no-quirks documents whose selector parsed, is gated on WP and lexbor agreeing on the element tree (multiset of fid/tag/ancestry — isolating the selector layer from tree construction), and compares match-fid multisets (lexbor reports in document order, WP in visit order). Verdict: lexbor != reference is a fuzzer-oracle problem (lexbor-divergence); reference == lexbor != WP is a high-confidence WP finding (existing match-mismatch-html with no divergence on the case). Confirmed on known Bug 2: reference and lexbor both return the empty set for [x^=""] where WP matches elements. lexbor quirks compensated for (all candidate upstream reports): - #368, open at v3.0.0: class/#id match case-insensitively even in no-quirks mode. Detected by startup probe; lexbor is compared against the reference run with class/ID folding, and quirks documents are excluded from the differential. - Uppercase I/S attribute modifiers are rejected; the non-ASCII ident-codepoint table omits U+00B7 and U+00C0-U+00F6. Both sidestepped by handing lexbor a deterministic canonical re-render of the verified AST (lowercase modifiers, non-ASCII hex-escaped) — byte-level parsing is already covered by AST round-trip and metamorphic invariants. - One callback per matching list branch: LXB_SELECTORS_OPT_MATCH_FIRST. 800 seeds against patched core: 408 compared, 0 divergences. --- tools/css-selector-fuzz/README.md | 34 +++ tools/css-selector-fuzz/lexbor/build.sh | 42 +++ tools/css-selector-fuzz/lexbor/harness.c | 267 ++++++++++++++++++ tools/css-selector-fuzz/lib/LexborOracle.php | 191 +++++++++++++ tools/css-selector-fuzz/lib/Metamorph.php | 17 +- .../lib/SelectorGenerator.php | 100 +++++++ tools/css-selector-fuzz/lib/Worker.php | 116 ++++++++ tools/css-selector-fuzz/lib/autoload.php | 1 + tools/css-selector-fuzz/lib/util.php | 15 + 9 files changed, 767 insertions(+), 16 deletions(-) create mode 100644 tools/css-selector-fuzz/lexbor/build.sh create mode 100644 tools/css-selector-fuzz/lexbor/harness.c create mode 100644 tools/css-selector-fuzz/lib/LexborOracle.php diff --git a/tools/css-selector-fuzz/README.md b/tools/css-selector-fuzz/README.md index 48d5192927a59..3f73c562a6857 100644 --- a/tools/css-selector-fuzz/README.md +++ b/tools/css-selector-fuzz/README.md @@ -64,8 +64,42 @@ produces the same document, the same selector, and the same verdict. explicit `*` for an omitted type, and selector-list branch duplication. Skipped for ASTs containing invalid UTF-8 (reachable only from chaos/mutated inputs), which the renderer cannot round-trip. + - lexbor differential (third, independent oracle; requires the harness — + see below): on no-quirks documents whose selector parsed, a canonical + re-render of the verified AST is matched by liblexbor and compared, + as a multiset of fids, against the reference matcher. Gated on WP and + lexbor building the same element tree (fid/tag/ancestry), so it tests + the selector layer, not tree construction. Verdicts: `lexbor-divergence` + (lexbor ≠ reference) is a fuzzer-oracle problem; `match-mismatch-html` + with no accompanying divergence means reference == lexbor ≠ WP — a + high-confidence WP finding. - Repeating a case yields a byte-identical result digest (determinism). +## lexbor harness + +Build with `sh tools/css-selector-fuzz/lexbor/build.sh` (clones and builds +liblexbor, pinned to v3.0.0 = `2ae88a1c6b52`). The worker auto-detects the +binary at `tools/css-selector-fuzz/lexbor/harness` and reports per-batch +tallies (`compared` / `tree-gated` / `skipped-quirks` / `off`). + +Known lexbor issues compensated for at this pin: + +- [#368](https://github.com/lexbor/lexbor/issues/368) (open at v3.0.0): + class and `#id` selectors match ASCII case-insensitively even in + no-quirks documents (`[id=…]` attribute matching is correctly + case-sensitive). Detected by a startup probe; when present, lexbor is + compared against the reference matcher run with quirks-style class/ID + folding, and quirks-mode documents are excluded from the differential + entirely (the reference matcher is the sole quirks authority). +- lexbor rejects uppercase `I`/`S` attribute-selector modifiers, and its + non-ASCII ident-codepoint table omits U+00B7 and U+00C0–U+00F6 (it + starts at U+00F8), rejecting e.g. `.Über` while accepting `.über`. + Both sidestepped by the canonical re-render (lowercase modifiers, all + non-ASCII hex-escaped); both are candidate upstream reports, not WP + findings. +- `lxb_selectors_find` reports a node once per matching selector-list + branch; `LXB_SELECTORS_OPT_MATCH_FIRST` dedupes. + ## Usage Bounded fuzz run (process-isolated chunks, crash/hang attribution): diff --git a/tools/css-selector-fuzz/lexbor/build.sh b/tools/css-selector-fuzz/lexbor/build.sh new file mode 100644 index 0000000000000..186a7e5b703b6 --- /dev/null +++ b/tools/css-selector-fuzz/lexbor/build.sh @@ -0,0 +1,42 @@ +#!/bin/sh +# +# Builds the lexbor differential harness. +# +# Pinned lexbor version: v3.0.0 (2ae88a1c6b5261830eff73ee12bb3cdf805f3cfe). +# Note: lexbor issue #368 ("Class/ID selectors are ASCII case-insensitive +# even in no-quirks mode") is still OPEN at this version; the PHP adapter +# detects it at startup and compensates (see LexborOracle.php). +# +# Usage: +# sh tools/css-selector-fuzz/lexbor/build.sh [lexbor-src-dir] +# +# Produces tools/css-selector-fuzz/lexbor/harness. + +set -e + +HERE="$(cd "$(dirname "$0")" && pwd)" +SRC="${1:-/tmp/lexbor-src}" +PIN="2ae88a1c6b5261830eff73ee12bb3cdf805f3cfe" + +if [ ! -d "$SRC" ]; then + echo "Cloning lexbor into $SRC ..." + git clone https://github.com/lexbor/lexbor "$SRC" +fi + +git -C "$SRC" checkout --quiet "$PIN" + +if [ ! -f "$SRC/build/liblexbor_static.a" ]; then + echo "Building liblexbor_static ..." + mkdir -p "$SRC/build" + cd "$SRC/build" + cmake -DCMAKE_BUILD_TYPE=Release -DLEXBOR_BUILD_SHARED=OFF \ + -DLEXBOR_BUILD_STATIC=ON -DLEXBOR_BUILD_TESTS=OFF \ + -DLEXBOR_BUILD_EXAMPLES=OFF .. > /dev/null + make -j8 lexbor_static > /dev/null + cd "$HERE" +fi + +cc -O2 -Wall -Wextra -o "$HERE/harness" "$HERE/harness.c" \ + -I "$SRC/source" "$SRC/build/liblexbor_static.a" + +echo "Built $HERE/harness (lexbor $PIN)" diff --git a/tools/css-selector-fuzz/lexbor/harness.c b/tools/css-selector-fuzz/lexbor/harness.c new file mode 100644 index 0000000000000..a33a198090ddf --- /dev/null +++ b/tools/css-selector-fuzz/lexbor/harness.c @@ -0,0 +1,267 @@ +/* + * lexbor differential harness for the CSS selector fuzzer. + * + * Reads one case per line from stdin: + * + * base64(html) "\t" base64(selector) "\n" + * + * For each case, parses the HTML with lexbor, parses the selector with the + * lexbor CSS selectors module, runs lxb_selectors_find over the whole + * document, and emits: + * + * R "\t" TAG "\t" FID "\t" ANC1,ANC2,... one per element, document + * pre-order; ancestors are + * nearest-first uppercase tags + * M "\t" FID one per match, in find order + * X "\t" parse selector did not parse + * X "\t" html html did not parse + * D end of case (then flush) + * + * FID is the element's data-fid attribute value, or "(missing-fid:TAG)" + * for elements without one (matching the fuzzer's placeholder convention). + * Tags are ASCII-uppercased. + * + * Build: see build.sh next to this file. Pinned lexbor version recorded + * there and in the fuzzer README. + */ + +#include +#include +#include + +#include +#include +#include + +#define MAX_DEPTH 512 + +static unsigned char * +b64_decode(const char *in, size_t in_len, size_t *out_len) +{ + static const signed char table[256] = { + ['A'] = 0, ['B'] = 1, ['C'] = 2, ['D'] = 3, ['E'] = 4, + ['F'] = 5, ['G'] = 6, ['H'] = 7, ['I'] = 8, ['J'] = 9, + ['K'] = 10, ['L'] = 11, ['M'] = 12, ['N'] = 13, ['O'] = 14, + ['P'] = 15, ['Q'] = 16, ['R'] = 17, ['S'] = 18, ['T'] = 19, + ['U'] = 20, ['V'] = 21, ['W'] = 22, ['X'] = 23, ['Y'] = 24, + ['Z'] = 25, ['a'] = 26, ['b'] = 27, ['c'] = 28, ['d'] = 29, + ['e'] = 30, ['f'] = 31, ['g'] = 32, ['h'] = 33, ['i'] = 34, + ['j'] = 35, ['k'] = 36, ['l'] = 37, ['m'] = 38, ['n'] = 39, + ['o'] = 40, ['p'] = 41, ['q'] = 42, ['r'] = 43, ['s'] = 44, + ['t'] = 45, ['u'] = 46, ['v'] = 47, ['w'] = 48, ['x'] = 49, + ['y'] = 50, ['z'] = 51, ['0'] = 52, ['1'] = 53, ['2'] = 54, + ['3'] = 55, ['4'] = 56, ['5'] = 57, ['6'] = 58, ['7'] = 59, + ['8'] = 60, ['9'] = 61, ['+'] = 62, ['/'] = 63, + }; + + unsigned char *out = malloc(in_len / 4 * 3 + 4); + size_t o = 0; + unsigned int acc = 0; + int bits = 0; + + if (out == NULL) { + return NULL; + } + + for (size_t i = 0; i < in_len; i++) { + unsigned char c = (unsigned char) in[i]; + if (c == '=' || c == '\n' || c == '\r') { + continue; + } + if (c != 'A' && table[c] == 0 && c != 'A') { + if (c != 'A') { + /* invalid chars are skipped; base64 here is machine-made */ + } + } + acc = (acc << 6) | (unsigned int) table[c]; + bits += 6; + if (bits >= 8) { + bits -= 8; + out[o++] = (unsigned char) ((acc >> bits) & 0xFF); + } + } + + *out_len = o; + return out; +} + +static void +put_upper(const lxb_char_t *name, size_t len) +{ + for (size_t i = 0; i < len; i++) { + unsigned char c = name[i]; + if (c >= 'a' && c <= 'z') { + c = (unsigned char) (c - 'a' + 'A'); + } + putchar(c); + } +} + +static void +put_fid(lxb_dom_node_t *node) +{ + lxb_dom_element_t *element = lxb_dom_interface_element(node); + size_t value_len = 0; + const lxb_char_t *value = lxb_dom_element_get_attribute( + element, (const lxb_char_t *) "data-fid", 8, &value_len); + + if (value != NULL) { + fwrite(value, 1, value_len, stdout); + return; + } + + size_t name_len = 0; + const lxb_char_t *name = lxb_dom_element_qualified_name(element, &name_len); + fputs("(missing-fid:", stdout); + put_upper(name, name_len); + putchar(')'); +} + +struct walk_state { + const lxb_char_t *stack[MAX_DEPTH]; /* uppercase emitted on the fly */ + size_t stack_len[MAX_DEPTH]; + int depth; +}; + +static void +walk(lxb_dom_node_t *node, struct walk_state *state) +{ + for (lxb_dom_node_t *child = node->first_child; child != NULL; + child = child->next) { + if (child->type != LXB_DOM_NODE_TYPE_ELEMENT) { + continue; + } + + size_t name_len = 0; + const lxb_char_t *name = lxb_dom_element_qualified_name( + lxb_dom_interface_element(child), &name_len); + + fputs("R\t", stdout); + put_upper(name, name_len); + putchar('\t'); + put_fid(child); + putchar('\t'); + for (int i = state->depth - 1; i >= 0; i--) { + put_upper(state->stack[i], state->stack_len[i]); + if (i > 0) { + putchar(','); + } + } + putchar('\n'); + + if (state->depth < MAX_DEPTH) { + state->stack[state->depth] = name; + state->stack_len[state->depth] = name_len; + state->depth++; + walk(child, state); + state->depth--; + } + } +} + +static lxb_status_t +find_callback(lxb_dom_node_t *node, lxb_css_selector_specificity_t spec, + void *ctx) +{ + (void) spec; + (void) ctx; + fputs("M\t", stdout); + put_fid(node); + putchar('\n'); + return LXB_STATUS_OK; +} + +int +main(void) +{ + char *line = NULL; + size_t line_cap = 0; + ssize_t line_len; + + while ((line_len = getline(&line, &line_cap, stdin)) > 0) { + char *tab = memchr(line, '\t', (size_t) line_len); + if (tab == NULL) { + fputs("X\tprotocol\nD\n", stdout); + fflush(stdout); + continue; + } + + size_t html_len = 0; + size_t selector_len = 0; + unsigned char *html = b64_decode(line, (size_t) (tab - line), &html_len); + unsigned char *selector = b64_decode( + tab + 1, (size_t) (line + line_len - tab - 1), &selector_len); + + if (html == NULL || selector == NULL) { + fputs("X\tprotocol\nD\n", stdout); + fflush(stdout); + free(html); + free(selector); + continue; + } + + lxb_html_document_t *document = lxb_html_document_create(); + if (lxb_html_document_parse(document, html, html_len) + != LXB_STATUS_OK) { + fputs("X\thtml\nD\n", stdout); + fflush(stdout); + lxb_html_document_destroy(document); + free(html); + free(selector); + continue; + } + + struct walk_state state = { .depth = 0 }; + walk(lxb_dom_interface_node(document), &state); + + /* + * Parser and selectors engine are created per case: + * lxb_css_selector_list_destroy_memory() releases the parser's + * whole arena, so reuse across cases is unsafe. + */ + lxb_css_parser_t *parser = lxb_css_parser_create(); + lxb_selectors_t *selectors = lxb_selectors_create(); + if (lxb_css_parser_init(parser, NULL) != LXB_STATUS_OK + || lxb_selectors_init(selectors) != LXB_STATUS_OK) { + fputs("X\tinit\nD\n", stdout); + fflush(stdout); + lxb_selectors_destroy(selectors, true); + lxb_css_parser_destroy(parser, true); + lxb_html_document_destroy(document); + free(html); + free(selector); + continue; + } + + /* Report each node once even when several list branches match. */ + lxb_selectors_opt_set(selectors, LXB_SELECTORS_OPT_MATCH_FIRST); + + lxb_css_selector_list_t *list = lxb_css_selectors_parse( + parser, selector, selector_len); + + if (parser->status != LXB_STATUS_OK || list == NULL) { + fputs("X\tparse\n", stdout); + } + else { + lxb_status_t status = lxb_selectors_find( + selectors, lxb_dom_interface_node(document), list, + find_callback, NULL); + if (status != LXB_STATUS_OK) { + fputs("X\tfind\n", stdout); + } + lxb_css_selector_list_destroy_memory(list); + } + + fputs("D\n", stdout); + fflush(stdout); + + lxb_selectors_destroy(selectors, true); + lxb_css_parser_destroy(parser, true); + lxb_html_document_destroy(document); + free(html); + free(selector); + } + + free(line); + return EXIT_SUCCESS; +} diff --git a/tools/css-selector-fuzz/lib/LexborOracle.php b/tools/css-selector-fuzz/lib/LexborOracle.php new file mode 100644 index 0000000000000..a7a6864aa62ab --- /dev/null +++ b/tools/css-selector-fuzz/lib/LexborOracle.php @@ -0,0 +1,191 @@ + fuzzer-oracle problem ( investigate + * the fuzzer, 'lexbor-divergence' ). + * reference == lexbor != WP => high-confidence WP finding ( the + * regular match-mismatch-html failure + * with no accompanying divergence ). + * + * Known bug compensated for: lexbor #368 — class and #id selectors match + * ASCII case-insensitively even in no-quirks mode ( attribute selectors + * like [id=x] are correctly case-sensitive ). Detected by probe at startup; + * when present, lexbor is compared against the reference matcher run with + * quirks-style class/ID folding. Open at the pinned v3.0.0. + */ +class LexborOracle { + + const READ_TIMEOUT_SECONDS = 5; + + /** @var resource|null */ + private static $process = null; + /** @var array|null */ + private static $pipes = null; + /** @var bool|null */ + private static $available = null; + /** @var bool */ + private static $issue368 = false; + + public static function harness_path(): string { + return dirname( __DIR__ ) . '/lexbor/harness'; + } + + /** Whether the harness is built, starts, and answered the probes. */ + public static function available(): bool { + if ( null !== self::$available ) { + return self::$available; + } + + self::$available = false; + if ( ! is_executable( self::harness_path() ) || ! self::start() ) { + return false; + } + + // Probe: sanity plus issue-#368 detection. + $sane = self::query( '
', 'div.a' ); + if ( null === $sane || array( 'x' ) !== $sane['matches'] ) { + self::stop(); + return false; + } + + $folded = self::query( '
', '.A' ); + self::$issue368 = null !== $folded && array( 'x' ) === $folded['matches']; + self::$available = true; + return true; + } + + /** Whether the pinned lexbor exhibits issue #368 ( class/ID case folding ). */ + public static function has_issue_368(): bool { + return self::$issue368; + } + + /** + * Runs one case through lexbor. + * + * @return array{ + * rows: array, + * matches: string[], + * error: string|null, + * }|null Null when the harness is unavailable or misbehaved ( the + * harness is stopped; the caller should skip the differential ). + */ + public static function query( string $html, string $selector ): ?array { + if ( null === self::$process && ! self::start() ) { + return null; + } + + $line = base64_encode( $html ) . "\t" . base64_encode( $selector ) . "\n"; + $written = fwrite( self::$pipes[0], $line ); + fflush( self::$pipes[0] ); + if ( strlen( $line ) !== $written ) { + self::stop(); + self::$available = false; + return null; + } + + $rows = array(); + $matches = array(); + $error = null; + + while ( true ) { + $response = self::read_line(); + if ( null === $response ) { + self::stop(); + self::$available = false; + return null; + } + if ( 'D' === $response ) { + break; + } + + $parts = explode( "\t", $response ); + switch ( $parts[0] ) { + case 'R': + $rows[] = array( + 'tag' => $parts[1] ?? '', + 'fid' => $parts[2] ?? '', + 'ancestorTags' => '' === ( $parts[3] ?? '' ) ? array() : explode( ',', $parts[3] ), + ); + break; + case 'M': + $matches[] = $parts[1] ?? ''; + break; + case 'X': + $error = $parts[1] ?? 'unknown'; + break; + } + } + + return array( + 'rows' => $rows, + 'matches' => $matches, + 'error' => $error, + ); + } + + private static function start(): bool { + $descriptors = array( + 0 => array( 'pipe', 'r' ), + 1 => array( 'pipe', 'w' ), + 2 => array( 'file', '/dev/null', 'w' ), + ); + + $process = proc_open( array( self::harness_path() ), $descriptors, $pipes ); + if ( ! is_resource( $process ) ) { + return false; + } + + self::$process = $process; + self::$pipes = $pipes; + stream_set_blocking( $pipes[1], false ); + return true; + } + + private static function stop(): void { + if ( null === self::$process ) { + return; + } + @fclose( self::$pipes[0] ); + @fclose( self::$pipes[1] ); + @proc_terminate( self::$process, 9 ); + @proc_close( self::$process ); + self::$process = null; + self::$pipes = null; + } + + /** Reads one newline-terminated line with a timeout; null on failure. */ + private static function read_line(): ?string { + $line = ''; + $deadline = microtime( true ) + self::READ_TIMEOUT_SECONDS; + + while ( true ) { + $read = array( self::$pipes[1] ); + $write = null; + $except = null; + $left = $deadline - microtime( true ); + if ( $left <= 0 ) { + return null; + } + $ready = stream_select( $read, $write, $except, 0, (int) ( $left * 1e6 ) ); + if ( false === $ready || 0 === $ready ) { + return null; + } + $chunk = fgets( self::$pipes[1] ); + if ( false === $chunk ) { + return null; + } + $line .= $chunk; + if ( str_ends_with( $line, "\n" ) ) { + return substr( $line, 0, -1 ); + } + } + } +} diff --git a/tools/css-selector-fuzz/lib/Metamorph.php b/tools/css-selector-fuzz/lib/Metamorph.php index 017b65fdd09f5..44e0e434ff4b2 100644 --- a/tools/css-selector-fuzz/lib/Metamorph.php +++ b/tools/css-selector-fuzz/lib/Metamorph.php @@ -41,7 +41,7 @@ public static function variants( array $list_ast, Prng $prng ): array { * UTF-8 names, so such ASTs (only reachable from chaos/mutated * inputs) are not transformable. */ - if ( ! self::ast_strings_are_utf8( $list_ast ) ) { + if ( ! ast_strings_are_utf8( $list_ast ) ) { return array(); } @@ -109,21 +109,6 @@ static function ( string $type ) use ( $prng ): string { return $out; } - /** Whether every string anywhere in the AST is valid UTF-8. */ - private static function ast_strings_are_utf8( $node ): bool { - if ( is_string( $node ) ) { - return (bool) preg_match( '//u', $node ); - } - if ( is_array( $node ) ) { - foreach ( $node as $child ) { - if ( ! self::ast_strings_are_utf8( $child ) ) { - return false; - } - } - } - return true; - } - /** Applies $fn to every type-selector name: compound types and context types. */ private static function map_types( array $list_ast, callable $fn ): array { foreach ( $list_ast as &$complex ) { diff --git a/tools/css-selector-fuzz/lib/SelectorGenerator.php b/tools/css-selector-fuzz/lib/SelectorGenerator.php index a7956ce709e11..131c3e970cefb 100644 --- a/tools/css-selector-fuzz/lib/SelectorGenerator.php +++ b/tools/css-selector-fuzz/lib/SelectorGenerator.php @@ -56,6 +56,106 @@ public static function render( Prng $prng, array $list_ast, bool $escape_boost = return $generator->render_complex_list( $list_ast ); } + /** + * Renders a canonical complex-list AST deterministically with minimal + * escaping: single spaces around combinators, `, ` between branches, + * double-quoted attribute values, lowercase `i`/`s` modifiers, and all + * non-ASCII codepoints hex-escaped. Used to hand a semantically-identical + * selector to external engines: lexbor rejects some byte-level forms WP + * correctly accepts ( uppercase I/S attribute modifiers; raw non-ASCII + * ident codepoints in U+00B7, U+00C0-U+00F6 — its non-ASCII ident table + * starts at U+00F8 ). Escaping sidesteps codepoint classification. + */ + public static function render_canonical( array $list_ast ): string { + $branches = array(); + foreach ( $list_ast as $complex ) { + $out = ''; + foreach ( array_reverse( $complex['context'] ) as $pair ) { + list( $type, $combinator ) = $pair; + $out .= '*' === $type ? '*' : self::canonical_ident( $type ); + $out .= '>' === $combinator ? ' > ' : ' '; + } + + $compound = $complex['self']; + if ( null !== $compound['type'] ) { + $out .= '*' === $compound['type'] ? '*' : self::canonical_ident( $compound['type'] ); + } + foreach ( (array) $compound['subs'] as $sub ) { + switch ( $sub['kind'] ) { + case 'class': + $out .= '.' . self::canonical_ident( $sub['name'] ); + break; + case 'id': + $out .= '#' . self::canonical_ident( $sub['name'] ); + break; + case 'attr': + $out .= '[' . self::canonical_ident( $sub['name'] ); + if ( null !== $sub['matcher'] ) { + $matchers = array( + 'exact' => '=', + 'one-of' => '~=', + 'exact-or-hyphen-suffixed' => '|=', + 'prefixed' => '^=', + 'suffixed' => '$=', + 'contains' => '*=', + ); + $out .= $matchers[ $sub['matcher'] ] . self::canonical_string( (string) $sub['value'] ); + if ( 'case-insensitive' === $sub['modifier'] ) { + $out .= ' i'; + } elseif ( 'case-sensitive' === $sub['modifier'] ) { + $out .= ' s'; + } + } + $out .= ']'; + break; + } + } + $branches[] = $out; + } + return implode( ', ', $branches ); + } + + private static function canonical_ident( string $name ): string { + $points = utf8_codepoints( $name ); + $count = count( $points ); + $out = ''; + + foreach ( $points as $i => $point ) { + list( $char, $cp ) = $point; + + $is_digit = $cp >= 0x30 && $cp <= 0x39; + $is_ident_char = ( + '-' === $char || + '_' === $char || + $is_digit || + ( $cp >= 0x41 && $cp <= 0x5A ) || + ( $cp >= 0x61 && $cp <= 0x7A ) + ); + + $must_escape = ! $is_ident_char + || ( 0 === $i && $is_digit ) + || ( 1 === $i && '-' === $points[0][0] && $is_digit ) + || ( 1 === $count && '-' === $char ); + + $out .= $must_escape ? '\\' . dechex( $cp ) . ' ' : $char; + } + + return $out; + } + + private static function canonical_string( string $value ): string { + $out = '"'; + foreach ( utf8_codepoints( $value ) as $point ) { + list( $char, $cp ) = $point; + if ( '"' === $char || '\\' === $char || $cp < 0x20 || $cp > 0x7E ) { + $out .= '\\' . dechex( $cp ) . ' '; + } else { + $out .= $char; + } + } + return $out . '"'; + } + /** * @param array $pools Pools from DocumentGenerator ( tags, classes, ids, attrNames, attrValues ). * @param array|null $rows Element rows ( TreeCapture shape ) with real diff --git a/tools/css-selector-fuzz/lib/Worker.php b/tools/css-selector-fuzz/lib/Worker.php index df7e48e8506e2..49b79fd39241a 100644 --- a/tools/css-selector-fuzz/lib/Worker.php +++ b/tools/css-selector-fuzz/lib/Worker.php @@ -245,6 +245,7 @@ static function () use ( $complex_list ) { // --- Match phase --------------------------------------------------- $html_matches = null; + $lexbor_state = 'off'; if ( null !== $complex_ast && null !== $rows ) { $expected = ReferenceMatcher::expected_html_matches_rows( $complex_ast, $rows, $quirks ); @@ -278,6 +279,8 @@ static function () use ( $complex_list ) { } $html_matches = self::check_select_matches( 'html', $selector_string, $document, $expected, $record ); + + $lexbor_state = self::check_lexbor_differential( $complex_ast, $selector_string, $document, $rows, $quirks, $expected, $record ); } elseif ( null === $complex_list && null === $complex_error ) { self::check_select_rejection( 'html', $selector_string, $document, $record ); } @@ -324,6 +327,7 @@ static function ( $failure ) { 'failures' => $failures, 'selector' => $selector_string, 'html' => $document['html'], + 'lexbor' => $lexbor_state, ); } @@ -479,6 +483,115 @@ private static function check_select_matches( string $target, string $selector_s return $actual; } + /** + * Runs the lexbor differential — the THIRD, independent matching opinion. + * + * Quirks-mode documents are excluded ( lexbor #368 makes its quirks + * behavior untrustworthy and WP's quirks class/ID folding is owned by + * ReferenceMatcher ). The comparison only runs when lexbor built the + * same element tree as WP ( fid/tag/ancestry multiset ), so it tests + * the selector layer, not tree construction. + * + * Verdict triage: + * - 'lexbor-divergence' lexbor != reference: a fuzzer-oracle problem + * ( or an un-compensated lexbor bug ) — never a + * WP verdict on its own. + * - 'lexbor-parse-reject' lexbor refused a selector WP accepted. + * - match-mismatch-html with NO lexbor-divergence on the same case + * means reference == lexbor != WP: a + * high-confidence WP finding. + * + * @return string Tally state: off|skipped-quirks|error|tree-gated|compared. + */ + private static function check_lexbor_differential( array $complex_ast, string $selector_string, array $document, array $rows, bool $quirks, array $expected, callable $record ): string { + if ( ! LexborOracle::available() ) { + return 'off'; + } + if ( $quirks ) { + return 'skipped-quirks'; + } + + /* + * lexbor receives a canonical re-render of the (already verified) + * AST rather than the original byte form: the differential targets + * matching semantics, while byte-level parsing (escapes, whitespace, + * modifier case — lexbor e.g. rejects uppercase I/S modifiers) is + * covered by the AST round-trip and metamorphic invariants. ASTs + * containing invalid UTF-8 cannot be re-rendered and are skipped. + */ + if ( ! ast_strings_are_utf8( $complex_ast ) ) { + return 'skipped-utf8'; + } + $canonical = SelectorGenerator::render_canonical( $complex_ast ); + + $lex = LexborOracle::query( $document['html'], $canonical ); + if ( null === $lex ) { + return 'error'; + } + + if ( 'parse' === $lex['error'] ) { + $record( + 'lexbor-parse-reject', + array( + 'note' => 'lexbor rejected the canonical form of a selector the WP parser accepted', + 'canonical' => printable_bytes( $canonical ), + ) + ); + return 'compared'; + } + if ( null !== $lex['error'] ) { + return 'error'; + } + + if ( ! self::trees_agree( $rows, $lex['rows'] ) ) { + return 'tree-gated'; + } + + /* + * lexbor #368: class/#id match ASCII case-insensitively even in + * no-quirks documents. Compare lexbor against the reference run + * with quirks-style class/ID folding ( the only thing the flag + * affects ) so the rest of the semantics still get differential + * coverage; WP itself is still held to the strict expectation. + */ + $expected_for_lexbor = LexborOracle::has_issue_368() + ? ReferenceMatcher::expected_html_matches_rows( $complex_ast, $rows, true ) + : $expected; + + // lexbor reports in document order, WP/reference in visit order — + // compare as multisets. + $lex_matches = $lex['matches']; + sort( $lex_matches ); + sort( $expected_for_lexbor ); + + if ( $lex_matches !== $expected_for_lexbor ) { + $record( + 'lexbor-divergence', + array( + 'reference' => $expected_for_lexbor, + 'lexbor' => $lex_matches, + 'issue368' => LexborOracle::has_issue_368(), + ) + ); + } + + return 'compared'; + } + + /** Multiset equality of ( tag, fid, ancestry ) between WP and lexbor rows. */ + private static function trees_agree( array $wp_rows, array $lexbor_rows ): bool { + $serialize = static function ( array $rows ): array { + $out = array(); + foreach ( $rows as $row ) { + $out[] = $row['tag'] . '|' . $row['fid'] . '|' . implode( ',', $row['ancestorTags'] ); + } + sort( $out ); + return $out; + }; + + return $serialize( $wp_rows ) === $serialize( $lexbor_rows ); + } + /** * Checks the metamorphic relations: each meaning-preserving transform of * the parsed selector must parse, must (for AST-preserving transforms) @@ -660,6 +773,7 @@ public static function run_batch( array $options ): array { $failures = 0; $buckets = array(); $signatures = array(); + $lexbor = array(); $last_seed = null; $stop_reason = 'completed'; @@ -688,6 +802,7 @@ public static function run_batch( array $options ): array { } $buckets[ $result['bucket'] ] = ( $buckets[ $result['bucket'] ] ?? 0 ) + 1; + $lexbor[ $result['lexbor'] ] = ( $lexbor[ $result['lexbor'] ] ?? 0 ) + 1; $last_seed = $seed; foreach ( $result['failures'] as $failure ) { @@ -722,6 +837,7 @@ public static function run_batch( array $options ): array { 'failures' => $failures, 'buckets' => $buckets, 'signatures' => $signatures, + 'lexbor' => $lexbor, 'stopReason' => $stop_reason, 'durationMs' => (int) round( 1000 * ( microtime( true ) - $started_at ) ), ); diff --git a/tools/css-selector-fuzz/lib/autoload.php b/tools/css-selector-fuzz/lib/autoload.php index 2a26cbdb9f407..6ebdcbc75d6c3 100644 --- a/tools/css-selector-fuzz/lib/autoload.php +++ b/tools/css-selector-fuzz/lib/autoload.php @@ -9,4 +9,5 @@ require_once __DIR__ . '/AstExtractor.php'; require_once __DIR__ . '/ReferenceMatcher.php'; require_once __DIR__ . '/Metamorph.php'; +require_once __DIR__ . '/LexborOracle.php'; require_once __DIR__ . '/Worker.php'; diff --git a/tools/css-selector-fuzz/lib/util.php b/tools/css-selector-fuzz/lib/util.php index 01e7dc20b7a73..6fe6662a6a3b8 100644 --- a/tools/css-selector-fuzz/lib/util.php +++ b/tools/css-selector-fuzz/lib/util.php @@ -118,6 +118,21 @@ function git_metadata(): array { ); } +/** Whether every string anywhere in a nested array is valid UTF-8. */ +function ast_strings_are_utf8( $node ): bool { + if ( is_string( $node ) ) { + return (bool) preg_match( '//u', $node ); + } + if ( is_array( $node ) ) { + foreach ( $node as $child ) { + if ( ! ast_strings_are_utf8( $child ) ) { + return false; + } + } + } + return true; +} + function ascii_strtolower( string $input ): string { return strtr( $input, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz' ); } From 7b3bbcf032b31bb7f154b98c3ae0d25036cf8763 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 13:46:11 +0200 Subject: [PATCH 161/634] CSS selector fuzz: coverage measurement + unreachable-branch generators MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add coverage.php (phpdbg opcode log, chunked to bound memory) reporting line coverage of src/wp-includes/html-api/css/. Add the edge-escape selector bucket to reach branches the structural generators cannot: hex escapes for NUL / surrogate / over-max codepoints (decode to U+FFFD) and raw NUL / CR / CRLF / FF in the selector input (normalize_selector_input). Two invalid templates ([ a, [a="x\) added for attribute/string parse guards. Result: 376/401 lines (93.8%); 388/401 = 96.8% of reachable code. The 25 unreached lines are itemized in COVERAGE.md: 12 are a phpdbg case-label artifact (bodies verified executing), 13 are defensive guards the public API cannot reach (e.g. the match-time unsupported-combinator arm — the parser only emits ' ' and '>'). --- tools/css-selector-fuzz/COVERAGE.md | 75 ++++++++++ tools/css-selector-fuzz/README.md | 9 ++ tools/css-selector-fuzz/coverage.php | 92 ++++++++++++ .../lib/SelectorGenerator.php | 140 ++++++++++++++++-- 4 files changed, 307 insertions(+), 9 deletions(-) create mode 100644 tools/css-selector-fuzz/COVERAGE.md create mode 100644 tools/css-selector-fuzz/coverage.php diff --git a/tools/css-selector-fuzz/COVERAGE.md b/tools/css-selector-fuzz/COVERAGE.md new file mode 100644 index 0000000000000..e69e34cf38a17 --- /dev/null +++ b/tools/css-selector-fuzz/COVERAGE.md @@ -0,0 +1,75 @@ +# CSS Selector Fuzzer — Coverage Report + +Line coverage of `src/wp-includes/html-api/css/` under the fuzzer, measured +with phpdbg's opcode log over 3000 deterministic seeds: + + phpdbg -qrr tools/css-selector-fuzz/coverage.php --seeds 3000 --list-uncovered + +| file | covered / executable | % | +|---|---|---| +| class-wp-css-attribute-selector.php | 102 / 112 | 91.1% | +| class-wp-css-class-selector.php | 10 / 10 | 100% | +| class-wp-css-complex-selector-list.php | 16 / 16 | 100% | +| class-wp-css-complex-selector.php | 59 / 66 | 89.4% | +| class-wp-css-compound-selector-list.php | 27 / 28 | 96.4% | +| class-wp-css-compound-selector.php | 29 / 32 | 90.6% | +| class-wp-css-id-selector.php | 12 / 12 | 100% | +| class-wp-css-selector-parser-matcher.php | 106 / 108 | 98.1% | +| class-wp-css-type-selector.php | 15 / 17 | 88.2% | +| **TOTAL** | **376 / 401** | **93.8%** | + +The 25 unreached lines are all accounted for below. Twelve are a phpdbg +measurement artifact (the code executes); the other thirteen are defensive +guards that the public entry points cannot reach. Effective coverage of +reachable code is **388 / 401 = 96.8%**. + +## phpdbg `case`-label artifact (12 lines — code executes) + +phpdbg attributes a `switch` arm's execution to the body line, not the bare +`case X:` label line. The fuzzer exercises every one of these arms (verified +directly: the body line immediately after each label is covered, and the +lexbor differential + self-check confirm the corresponding behavior). These +are not real gaps: + +- `class-wp-css-attribute-selector.php` + - 287, 291, 295, 299, 303 — the `~= |= ^= $= *=` matcher operators. + - 330, 331, 336, 337 — the `i`/`I`/`s`/`S` case modifiers. +- `class-wp-css-compound-selector.php` + - 120, 122, 124 — the `.` / `#` / `[` subclass-selector dispatch. + +## Defensive guards unreachable from the public API (13 lines) + +These are internal precondition checks that the calling code already +guarantees, or branches for grammar the parser never emits: + +- `class-wp-css-attribute-selector.php:257` — `return null` when the first + byte is not `[`. `parse()` is only ever called by + `parse_subclass_selector()` *after* it has matched `[`, so the guard never + fires. +- `class-wp-css-complex-selector.php:170–179` — the `_doing_it_wrong` + "unsupported combinator" arm in the match walker. The parser only ever + stores `' '` (descendant) or `'>'` (child) combinators, so the match-time + default arm is dead defensively. +- `class-wp-css-compound-selector-list.php:87` — `return false` when the + processor is not on a `#tag` token. `select()` only invokes matching while + positioned on a tag; reachable only by calling `matches()` directly off a + non-tag token. +- `class-wp-css-selector-parser-matcher.php:130` — `parse_string()` EOF + guard; every caller checks bounds and the opening quote before calling. +- `class-wp-css-selector-parser-matcher.php:429` — + `check_if_three_code_points_would_start_an_ident_sequence()` EOF guard; + callers bound-check first. +- `class-wp-css-type-selector.php:45` — `return false` when `get_tag()` is + null during matching; matching only runs on resolved element tokens. +- `class-wp-css-type-selector.php:75` — `parse()` EOF guard; the compound + parser checks `offset < strlen` before calling. + +## Notes on what raised coverage + +- The `edge-escape` bucket drives the U+FFFD escape-decoder branch + (`consume_escaped_codepoint` for NUL / surrogate / over-max codepoints) + and the `normalize_selector_input` NUL→U+FFFD and CR/CRLF/FF→LF paths, + which the structural generators cannot reach. +- A few `invalid`-bucket templates (`[ a`, `[a="x\`) were added to reach + attribute/string parse guards that random structural generation rarely + lands on. diff --git a/tools/css-selector-fuzz/README.md b/tools/css-selector-fuzz/README.md index 3f73c562a6857..a6bad339034e7 100644 --- a/tools/css-selector-fuzz/README.md +++ b/tools/css-selector-fuzz/README.md @@ -41,6 +41,10 @@ produces the same document, the same selector, and the same verdict. - `chaos` — arbitrary bytes; no parse expectation. - `mutated` — a supported selector with random byte mutations; no parse expectation. + - `edge-escape` — selectors that exercise otherwise-unreachable parser + branches: hex escapes for NUL / surrogate / over-max codepoints (must + decode to U+FFFD) and raw NUL / CR / CRLF / FF bytes in the input (must + normalize per `normalize_selector_input`); carries the intended AST. 4. Check invariants: - No PHP error/warning/exception from parsing or matching, ever. - Parse result (instance vs `null`) matches the bucket's expectation. @@ -123,6 +127,11 @@ Run a batch in-process (no isolation, faster): php tools/css-selector-fuzz/worker.php --start-seed 1 --count 500 +Measure line coverage of the `css/` classes (see `COVERAGE.md` for the +current report and a justified list of unreached lines): + + phpdbg -qrr tools/css-selector-fuzz/coverage.php --seeds 3000 --list-uncovered + Options of note: - `runner.php --stop-on-failure` stops at the first failing chunk. diff --git a/tools/css-selector-fuzz/coverage.php b/tools/css-selector-fuzz/coverage.php new file mode 100644 index 0000000000000..64c60a7d5e42c --- /dev/null +++ b/tools/css-selector-fuzz/coverage.php @@ -0,0 +1,92 @@ +#!/usr/bin/env php + $lines ) { + foreach ( $lines as $line => $hits ) { + $oplog[ $file ][ $line ] = true; + } + } +} + +$executable = phpdbg_get_executable( array( 'files' => $targets ) ); + +$total_exec = 0; +$total_covered = 0; + +foreach ( $targets as $file ) { + $exec_lines = array_keys( $executable[ $file ] ?? array() ); + $covered_lines = array_keys( $oplog[ $file ] ?? array() ); + $covered_lines = array_intersect( $covered_lines, $exec_lines ); + $uncovered = array_diff( $exec_lines, $covered_lines ); + + $total_exec += count( $exec_lines ); + $total_covered += count( $covered_lines ); + + printf( + "%-55s %4d/%4d lines %5.1f%%\n", + basename( $file ), + count( $covered_lines ), + count( $exec_lines ), + count( $exec_lines ) > 0 ? 100 * count( $covered_lines ) / count( $exec_lines ) : 100 + ); + + if ( $list_uncovered && array() !== $uncovered ) { + $source = file( $file ); + sort( $uncovered ); + foreach ( $uncovered as $line ) { + printf( " !%4d %s\n", $line, rtrim( $source[ $line - 1 ] ?? '' ) ); + } + } +} + +printf( + "%-55s %4d/%4d lines %5.1f%%\n", + 'TOTAL', + $total_covered, + $total_exec, + $total_exec > 0 ? 100 * $total_covered / $total_exec : 100 +); diff --git a/tools/css-selector-fuzz/lib/SelectorGenerator.php b/tools/css-selector-fuzz/lib/SelectorGenerator.php index 131c3e970cefb..7bf1851f192e6 100644 --- a/tools/css-selector-fuzz/lib/SelectorGenerator.php +++ b/tools/css-selector-fuzz/lib/SelectorGenerator.php @@ -31,6 +31,7 @@ class SelectorGenerator { 'invalid', 'chaos', 'mutated', + 'edge-escape', ); /** @var Prng */ @@ -177,21 +178,23 @@ public static function generate( Prng $prng, array $pools, ?array $rows = null, $bucket = $prng->weighted( null === $rows || array() === $rows ? array( - 'supported-compound' => 30, - 'supported-complex' => 25, - 'unsupported' => 15, - 'invalid' => 12, + 'supported-compound' => 28, + 'supported-complex' => 24, + 'unsupported' => 14, + 'invalid' => 11, 'chaos' => 8, 'mutated' => 10, + 'edge-escape' => 5, ) : array( - 'supported-compound' => 24, - 'supported-complex' => 20, - 'path-directed' => 22, - 'unsupported' => 12, - 'invalid' => 10, + 'supported-compound' => 23, + 'supported-complex' => 19, + 'path-directed' => 21, + 'unsupported' => 11, + 'invalid' => 9, 'chaos' => 6, 'mutated' => 6, + 'edge-escape' => 5, ) ); } @@ -224,6 +227,9 @@ public static function generate( Prng $prng, array $pools, ?array $rows = null, case 'path-directed': return $generator->gen_path_directed( $rows ); + case 'edge-escape': + return $generator->gen_edge_escape(); + case 'unsupported': return array( 'bucket' => $bucket, @@ -521,6 +527,120 @@ private function pick_name( string $pool_key ): string { ); } + /* + * --------------------------- + * Edge-case escapes and input + * --------------------------- + * + * Targets parser branches the structural generators can't reach: + * - hex escapes whose codepoint is NUL / a surrogate / over-max, which + * `consume_escaped_codepoint` must decode to U+FFFD; + * - raw NUL / CR / CRLF / FF bytes in the selector input, which + * `normalize_selector_input` rewrites ( NUL→U+FFFD, the rest→LF ). + * + * These carry a known intended AST: the decoded ident is the U+FFFD + * replacement character ( or, for input normalization, the same selector + * with whitespace normalized ), so the AST round-trip still applies. + */ + private function gen_edge_escape(): array { + $kind = $this->prng->weighted( + array( + 'fffd-ident' => 50, + 'nul-input' => 25, + 'ws-input' => 25, + ) + ); + + if ( 'fffd-ident' === $kind ) { + // A class selector whose name is a single U+FFFD, produced by a + // hex escape for an out-of-range codepoint. + $hex = $this->prng->choice( + array( + '0', + '00', + '000000', + dechex( $this->prng->int( 0xD800, 0xDFFF ) ), // surrogate + dechex( $this->prng->int( 0x110000, 0xFFFFFF ) ), // over-max + ) + ); + if ( $this->prng->chance( 40 ) ) { + $hex = strtoupper( $hex ); + } + $selector = '.\\' . $hex . ' '; + $ast = array( + array( + 'context' => array(), + 'self' => array( + 'type' => null, + 'subs' => array( array( 'kind' => 'class', 'name' => "\u{FFFD}" ) ), + ), + ), + ); + return array( + 'bucket' => 'edge-escape', + 'selector' => $selector, + 'expectCompound' => true, + 'expectComplex' => true, + 'ast' => $ast, + ); + } + + /* + * Raw control bytes in the selector input. A small fixed compound + * keeps the case focused on normalize_selector_input and avoids + * entangling with unrelated attribute-selector edge cases. + */ + $compound = array( + 'type' => $this->prng->chance( 50 ) ? 'span' : null, + 'subs' => array( + array( 'kind' => 'class', 'name' => 'foo' ), + array( 'kind' => 'id', 'name' => 'bar' ), + ), + ); + if ( null === $compound['type'] && $this->prng->chance( 50 ) ) { + array_pop( $compound['subs'] ); + } + $rendered = $this->render_compound( $compound ); + + if ( 'nul-input' === $kind ) { + // A NUL between a class dot's selectors becomes part of an ident + // only in limited spots; simplest reliable case: a class whose + // name contains a NUL ( → U+FFFD ). + $ast = array( + array( + 'context' => array(), + 'self' => array( + 'type' => null, + 'subs' => array( array( 'kind' => 'class', 'name' => "a\u{FFFD}b" ) ), + ), + ), + ); + return array( + 'bucket' => 'edge-escape', + 'selector' => ".a\0b", + 'expectCompound' => true, + 'expectComplex' => true, + 'ast' => $ast, + ); + } + + // ws-input: wrap/insert CR, CRLF, FF as insignificant whitespace. + $lead = $this->prng->choice( array( "\r", "\f", "\r\n", "\r\r", "\f\f" ) ); + $trail = $this->prng->choice( array( "\r", "\f", "\r\n", '' ) ); + return array( + 'bucket' => 'edge-escape', + 'selector' => $lead . $rendered . $trail, + 'expectCompound' => true, + 'expectComplex' => true, + 'ast' => array( + array( + 'context' => array(), + 'self' => $compound, + ), + ), + ); + } + /* * ------------------------ * Path-directed generation @@ -1164,8 +1284,10 @@ private function gen_invalid(): string { '..a', '.#a', '[a', + '[ a', '[a=', '[a=]', + '[a="x\\', '[=b]', '[a==b]', '[a~b]', From 69f3fefad3e3d04b41dfebd991ca6f03bd1058c9 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 13:53:58 +0200 Subject: [PATCH 162/634] CSS selector fuzz: automatic delta-debugging minimizer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add minimize.php and Worker::run_pair. run_pair runs only the self-contained invariants — those computable from a (selector, html) pair without the generator's intended AST or parse expectation: WP select() vs the reference matcher over WP's own parsed AST and the captured tree, the metamorphic relations, the lexbor differential, and parse/shape/cross-grammar/rejection checks. All three known bugs reduce to a self-contained signature (Bug 1 -> metamorphic-ast, Bug 2 -> match-mismatch-html, Bug 3 -> metamorphic-parse). minimize.php ddmin-shrinks the HTML then the selector (HTML first so a selector-only signature collapses the document cheaply), preserving a chosen target signature. The metamorphic stage runs only when the target is itself metamorphic, stops at the first reproducing draw, and uses a fixed draw seed so shrinking stays monotonic. Verified on unpatched core: Bug 2 -> [type*=""] on
(8 bytes); Bug 3 -> a[aa="a"] (empty html); Bug 1 -> a 19-byte selector, empty html. --- tools/css-selector-fuzz/README.md | 11 ++ tools/css-selector-fuzz/lib/Worker.php | 164 +++++++++++++++++++++ tools/css-selector-fuzz/minimize.php | 189 +++++++++++++++++++++++++ 3 files changed, 364 insertions(+) create mode 100644 tools/css-selector-fuzz/minimize.php diff --git a/tools/css-selector-fuzz/README.md b/tools/css-selector-fuzz/README.md index a6bad339034e7..ffa12efda964d 100644 --- a/tools/css-selector-fuzz/README.md +++ b/tools/css-selector-fuzz/README.md @@ -123,6 +123,17 @@ Probe a specific selector: php tools/css-selector-fuzz/replay.php --selector 'section > div.cls' --html '
' +Minimize a failing case to a small reproducer (delta-debugging; shrinks +both the selector and the HTML while preserving a failure signature): + + php tools/css-selector-fuzz/minimize.php --seed 1234 + php tools/css-selector-fuzz/minimize.php --selector 'sel' --html '<…>' --signature match-mismatch + +The minimizer drives `Worker::run_pair`, which checks only self-contained +invariants — those computable from the (selector, html) pair without the +generator's intended AST. All three known bugs reduce to one: Bug 1 → +`metamorphic-ast`, Bug 2 → `match-mismatch-html`, Bug 3 → `metamorphic-parse`. + Run a batch in-process (no isolation, faster): php tools/css-selector-fuzz/worker.php --start-seed 1 --count 500 diff --git a/tools/css-selector-fuzz/lib/Worker.php b/tools/css-selector-fuzz/lib/Worker.php index 49b79fd39241a..e81f1ba677de9 100644 --- a/tools/css-selector-fuzz/lib/Worker.php +++ b/tools/css-selector-fuzz/lib/Worker.php @@ -43,6 +43,9 @@ class Worker { const SELECT_ITERATION_LIMIT = 10000; + /** Metamorphic PRNG draws tried per pair in run_pair (minimizer). */ + const PAIR_METAMORPH_DRAWS = 12; + /** * Runs a single fuzz case. * @@ -331,6 +334,167 @@ static function ( $failure ) { ); } + /** + * Runs the SELF-CONTAINED invariants on an explicit ( selector, html ) + * pair — no generated model, intended AST, or parse expectation. This is + * what the minimizer drives: every checked property is computable from + * the pair alone ( WP select() vs the reference matcher over WP's own + * parsed AST and the captured tree; metamorphic relations; the lexbor + * differential; parse/shape/cross-grammar invariants; rejection + * bookkeeping for unparseable selectors ). + * + * Bug 1 surfaces here as metamorphic-ast, Bug 2 as match-mismatch-*, + * Bug 3 as metamorphic-parse — so all three known bugs are minimizable + * without the generator. + * + * @return array{ + * failures: array, + * signatures: string[], + * } + */ + public static function run_pair( string $selector_string, string $html, ?string $target = null ): array { + Bootstrap::load(); + + $failures = array(); + $record = static function ( string $invariant, array $detail ) use ( &$failures ) { + $failures[] = array( + 'invariant' => $invariant, + 'detail' => $detail, + ); + }; + + // When the minimizer fixes a target signature, the metamorphic loop + // ( the only expensive, multi-draw stage ) is only worth running if + // the target is itself a metamorphic signature. + $target_invariant = null === $target ? null : substr( strrchr( $target, ':' ), 1 ); + $target_is_metamorph = null !== $target_invariant && 0 === strpos( $target_invariant, 'metamorphic' ); + $has_target_signature = static function () use ( &$failures, $target ) { + if ( null === $target ) { + return false; + } + foreach ( $failures as $failure ) { + if ( self::signature( $failure ) === $target ) { + return true; + } + } + return false; + }; + + list( $capture, $capture_error ) = self::guard( + static function () use ( $html ) { + return TreeCapture::capture( $html ); + } + ); + + $rows = null; + $tag_rows = null; + $quirks = false; + if ( null === $capture_error && null === $capture['error'] ) { + $rows = $capture['htmlRows']; + $tag_rows = $capture['tagRows']; + $quirks = $capture['quirks']; + } + + $document = array( 'html' => $html ); + + list( $compound_list, $compound_error ) = self::guard( + static function () use ( $selector_string ) { + return \WP_CSS_Compound_Selector_List::from_selectors( $selector_string ); + } + ); + list( $complex_list, $complex_error ) = self::guard( + static function () use ( $selector_string ) { + return \WP_CSS_Complex_Selector_List::from_selectors( $selector_string ); + } + ); + + if ( null !== $compound_error ) { + $record( 'parse-error', array( 'grammar' => 'compound', 'error' => self::describe_throwable( $compound_error ) ) ); + } + if ( null !== $complex_error ) { + $record( 'parse-error', array( 'grammar' => 'complex', 'error' => self::describe_throwable( $complex_error ) ) ); + } + if ( null !== $compound_list && null === $complex_list && null === $complex_error ) { + $record( 'compound-implies-complex', array() ); + } + + $compound_ast = null; + $complex_ast = null; + if ( null !== $compound_list ) { + list( $compound_ast, $shape_error ) = self::guard( + static function () use ( $compound_list ) { + return AstExtractor::from_compound_list( $compound_list ); + } + ); + if ( null !== $shape_error ) { + $record( 'ast-shape', array( 'grammar' => 'compound', 'error' => self::describe_throwable( $shape_error ) ) ); + } + } + if ( null !== $complex_list ) { + list( $complex_ast, $shape_error ) = self::guard( + static function () use ( $complex_list ) { + return AstExtractor::from_complex_list( $complex_list ); + } + ); + if ( null !== $shape_error ) { + $record( 'ast-shape', array( 'grammar' => 'complex', 'error' => self::describe_throwable( $shape_error ) ) ); + } + } + if ( null !== $compound_ast && null !== $complex_ast && $compound_ast !== $complex_ast ) { + $record( 'ast-cross-grammar', array( 'compoundAst' => $compound_ast, 'complexAst' => $complex_ast ) ); + } + + $html_matches = null; + if ( null !== $complex_ast && null !== $rows ) { + $expected = ReferenceMatcher::expected_html_matches_rows( $complex_ast, $rows, $quirks ); + $html_matches = self::check_select_matches( 'html', $selector_string, $document, $expected, $record ); + self::check_lexbor_differential( $complex_ast, $selector_string, $document, $rows, $quirks, $expected, $record ); + } elseif ( null === $complex_list && null === $complex_error && null !== $rows ) { + self::check_select_rejection( 'html', $selector_string, $document, $record ); + } + + if ( null !== $compound_ast && null !== $tag_rows ) { + $expected = ReferenceMatcher::expected_tag_matches_rows( $compound_ast, $tag_rows ); + self::check_select_matches( 'tag', $selector_string, $document, $expected, $record ); + } elseif ( null === $compound_list && null === $compound_error && null !== $tag_rows ) { + self::check_select_rejection( 'tag', $selector_string, $document, $record ); + } + + $run_metamorph = ( null === $target || $target_is_metamorph ) + && null !== $complex_ast && null !== $html_matches && array() === $failures; + if ( $run_metamorph ) { + /* + * Metamorphic transforms randomize escapes / case / order, so a + * transform-sensitive bug ( e.g. Bug 1 and Bug 3 ) only fires for + * some PRNG draws. run_case sees one draw; here several fixed + * draws are tried so minimization can reliably preserve such a + * signature regardless of which draw first exposed it. With a + * target fixed, stop at the first draw that reproduces it. + */ + for ( $i = 0; $i < self::PAIR_METAMORPH_DRAWS && array() === $failures; $i++ ) { + // A FIXED draw seed ( not derived from the pair ) keeps the + // test monotonic under shrinking: the same coin-flips apply to + // whatever AST survives, so a smaller selector that still has + // the bug reproduces the same transform signature. + $metamorph_prng = new Prng( 'css-selector-fuzz-minimize', "metamorph:{$i}" ); + self::check_metamorphic( $complex_ast, $html_matches, $document, $metamorph_prng, $record ); + if ( $has_target_signature() ) { + break; + } + } + } + + $signatures = array(); + foreach ( $failures as $failure ) { + $signatures[] = self::signature( $failure ); + } + + return array( + 'failures' => $failures, + 'signatures' => array_values( array_unique( $signatures ) ), + ); + } + /** * Verifies that the processor's captured view of a safe (model-built) * document agrees with the generated model — this guards the oracle diff --git a/tools/css-selector-fuzz/minimize.php b/tools/css-selector-fuzz/minimize.php new file mode 100644 index 0000000000000..3f3870b97b247 --- /dev/null +++ b/tools/css-selector-fuzz/minimize.php @@ -0,0 +1,189 @@ +#!/usr/bin/env php + metamorphic-ast, Bug 2 -> match-mismatch-html, Bug 3 -> + * metamorphic-parse. + * + * Usage: + * php tools/css-selector-fuzz/minimize.php --seed 1234 [--signature SUBSTR] + * php tools/css-selector-fuzz/minimize.php --selector 'sel' --html '<…>' [--signature SUBSTR] + * + * Options: + * --signature SUBSTR Target a signature whose id or invariant contains + * SUBSTR (default: the first signature of the seed's + * failure set). + * --max-attempts N Cap test evaluations (default 4000). + * --json Emit the reproducer as JSON. + */ + +require_once __DIR__ . '/lib/autoload.php'; + +use CssSelectorFuzz\Worker; +use function CssSelectorFuzz\json_encode_safe; +use function CssSelectorFuzz\option_bool; +use function CssSelectorFuzz\option_int; +use function CssSelectorFuzz\option_string; +use function CssSelectorFuzz\parse_cli_options; +use function CssSelectorFuzz\printable_bytes; + +$options = parse_cli_options( $argv ); +$max_attempts = option_int( $options, 'max-attempts', 20000 ); +$sig_filter = option_string( $options, 'signature', null ); + +$seed = option_int( $options, 'seed', -1 ); +if ( $seed >= 0 ) { + $case = Worker::run_case( $seed ); + $selector = $case['selector']; + $html = $case['html']; +} else { + $selector = option_string( $options, 'selector', null ); + $html = option_string( $options, 'html', null ); + if ( null === $selector || null === $html ) { + fwrite( STDERR, "Provide --seed N, or both --selector and --html.\n" ); + exit( 1 ); + } +} + +/** Signatures produced by a pair ( $target lets run_pair short-circuit ). */ +$signatures_of = static function ( string $selector, string $html, ?string $target = null ): array { + return Worker::run_pair( $selector, $html, $target )['signatures']; +}; + +$baseline = $signatures_of( $selector, $html ); +if ( array() === $baseline ) { + fwrite( STDERR, "The starting pair does not reproduce any self-contained failure.\n" ); + fwrite( STDERR, 'selector: ' . printable_bytes( $selector ) . "\n" ); + exit( 1 ); +} + +// Pick the target signature. +$target = $baseline[0]; +if ( null !== $sig_filter ) { + foreach ( $baseline as $candidate ) { + if ( false !== strpos( $candidate, $sig_filter ) ) { + $target = $candidate; + break; + } + } +} + +$attempts = 0; +$reproduces = static function ( string $selector, string $html ) use ( $signatures_of, $target, &$attempts, $max_attempts ): bool { + if ( $attempts >= $max_attempts ) { + return false; + } + ++$attempts; + return in_array( $target, $signatures_of( $selector, $html, $target ), true ); +}; + +/** + * Delta-debugging shrink of one byte string: ddmin chunk removal followed + * by per-position single-byte simplification. $test( candidate ) decides + * whether a candidate still reproduces. + */ +$shrink = static function ( string $current, callable $test ) use ( &$attempts, $max_attempts ): string { + $chunks = 2; + while ( strlen( $current ) > 0 && $attempts < $max_attempts ) { + $length = strlen( $current ); + $chunk_size = (int) ceil( $length / $chunks ); + $changed = false; + + for ( $offset = 0; $offset < $length && $attempts < $max_attempts; $offset += $chunk_size ) { + $candidate = substr( $current, 0, $offset ) . substr( $current, min( $length, $offset + $chunk_size ) ); + if ( $candidate === $current ) { + continue; + } + if ( $test( $candidate ) ) { + $current = $candidate; + $chunks = max( 2, $chunks - 1 ); + $changed = true; + break; + } + } + + if ( ! $changed ) { + if ( $chunks >= $length ) { + break; + } + $chunks = min( $length, $chunks * 2 ); + } + } + + // Per-byte canonicalization: replace each byte with a simpler stand-in. + $replacements = array( 'a', ' ', '' ); + for ( $i = 0; $i < strlen( $current ) && $attempts < $max_attempts; $i++ ) { + foreach ( $replacements as $replacement ) { + $candidate = substr( $current, 0, $i ) . $replacement . substr( $current, $i + 1 ); + if ( $candidate === $current ) { + continue; + } + if ( $test( $candidate ) ) { + $current = $candidate; + $i = max( -1, $i - 2 ); + break; + } + } + } + + return $current; +}; + +// Alternate shrinking the HTML and the selector until neither moves. +// HTML first: when the signature is selector-only (e.g. metamorphic-parse) +// the document collapses cheaply before the costlier selector pass. +$prev = null; +while ( $attempts < $max_attempts && ( $selector . "\0" . $html ) !== $prev ) { + $prev = $selector . "\0" . $html; + + $html = $shrink( + $html, + static function ( string $candidate ) use ( $reproduces, &$selector ): bool { + return $reproduces( $selector, $candidate ); + } + ); + $selector = $shrink( + $selector, + static function ( string $candidate ) use ( $reproduces, &$html ): bool { + return $reproduces( $candidate, $html ); + } + ); +} + +$final = $signatures_of( $selector, $html ); +$ok = in_array( $target, $final, true ); + +if ( option_bool( $options, 'json', false ) ) { + echo json_encode_safe( + array( + 'target' => $target, + 'reproduced' => $ok, + 'attempts' => $attempts, + 'selector' => printable_bytes( $selector ), + 'selectorBytes' => strlen( $selector ), + 'html' => printable_bytes( $html ), + 'htmlBytes' => strlen( $html ), + 'selectorBase64' => base64_encode( $selector ), + 'htmlBase64' => base64_encode( $html ), + ) + ) . "\n"; + exit( $ok ? 0 : 2 ); +} + +echo "target: {$target}\n"; +echo 'reproduced: ' . ( $ok ? 'yes' : 'NO' ) . "\n"; +echo "attempts: {$attempts}\n"; +echo 'selector: ' . printable_bytes( $selector ) . ' (' . strlen( $selector ) . " bytes)\n"; +echo 'html: ' . printable_bytes( $html ) . ' (' . strlen( $html ) . " bytes)\n"; +echo "\nreplay:\n"; +echo ' php tools/css-selector-fuzz/replay.php --selector ' . escapeshellarg( $selector ) + . ' --html ' . escapeshellarg( $html ) . "\n"; +exit( $ok ? 0 : 2 ); From 5da3afedd0db58dfcb028dbe5cf13b5cae2da1c3 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 14:00:25 +0200 Subject: [PATCH 163/634] CSS selector fuzz: fragment parsing + quirks-trigger coverage Add a -context fragment mode (~20% of safe-document cases): DocumentGenerator::generate_fragment renders body-level content without the document wrapper, TreeCapture parses it via create_fragment and captures the tree (with the implicit HTML/BODY ancestors the fragment parser reports in breadcrumbs), and the match / metamorphic invariants run against it. collect_matches and the rejection check route through create_fragment when the case is a fragment; the tag processor (no fragment mode) and lexbor (full-document only) are skipped for fragments. is the only context create_fragment accepts publicly. Quirks-mode triggers were already broadened by the wild generator's five doctype variants (none / html / legacy-compat SYSTEM / quirky PUBLIC / limited-quirks): ~111 quirks vs ~213 no-quirks per 400 wild docs, and is_quirks_mode() is captured per case and honored by the reference matcher. 294 fragment cases over 2000 seeds run clean with capture == model; full 2000-seed batch clean against core with the three known fixes. --- tools/css-selector-fuzz/README.md | 8 +- .../lib/DocumentGenerator.php | 97 ++++++++++++++++ tools/css-selector-fuzz/lib/TreeCapture.php | 23 +++- tools/css-selector-fuzz/lib/Worker.php | 105 ++++++++++++++---- 4 files changed, 208 insertions(+), 25 deletions(-) diff --git a/tools/css-selector-fuzz/README.md b/tools/css-selector-fuzz/README.md index ffa12efda964d..3042338f18917 100644 --- a/tools/css-selector-fuzz/README.md +++ b/tools/css-selector-fuzz/README.md @@ -10,8 +10,12 @@ produces the same document, the same selector, and the same verdict. ## What a case does 1. Generate a random HTML document — 70% from a structurally "safe" element - set with a known model tree, 30% "wild" (misnested, implied-end-tag, - foreign-content, varied-doctype token soup with no model). + set with a known model tree (of these, ~20% are parsed as a `` + fragment via `create_fragment` instead of a full document, exercising the + fragment `select()` path), 30% "wild" (misnested, implied-end-tag, + foreign-content, token soup with one of five doctypes spanning no-quirks, + quirks, and limited-quirks). `create_fragment` only accepts the `` + context publicly, so that is the fragment context fuzzed. 2. Capture the processor's own view of the document as the matching oracle's ground truth (`TreeCapture`): a flat list of rows in visit order, each carrying the element's tag, attributes, and ancestor tag list (context diff --git a/tools/css-selector-fuzz/lib/DocumentGenerator.php b/tools/css-selector-fuzz/lib/DocumentGenerator.php index e435edce409c9..20e6e99607421 100644 --- a/tools/css-selector-fuzz/lib/DocumentGenerator.php +++ b/tools/css-selector-fuzz/lib/DocumentGenerator.php @@ -106,6 +106,103 @@ public static function generate( Prng $prng ): array { return $generator->build(); } + /** + * Generates a ``-context fragment: body-level content rendered + * without the document wrapper, parsed via create_fragment. The model's + * top-level elements carry the implicit BODY/HTML ancestors the fragment + * parser reports in breadcrumbs. + * + * @return array{ + * model: null, + * children: array, + * html: string, + * context: string, + * fragment: true, + * quirks: bool, + * pools: array, + * } + */ + public static function generate_fragment( Prng $prng ): array { + $generator = new self( $prng, $prng->int( 6, 30 ) ); + return $generator->build_fragment(); + } + + private function build_fragment(): array { + $children = array(); + $child_budget = $this->prng->int( 1, 6 ); + for ( $i = 0; $i < $child_budget && $this->element_count < $this->max_elements; $i++ ) { + $children[] = $this->random_subtree( 0 ); + } + + $bits = array(); + foreach ( $children as $child ) { + $bits[] = $this->render_element( $child ); + } + $filler = array( '', 'text', ' more ', "\n ", '& x', 'café ✓', '' ); + $html = ''; + foreach ( $bits as $bit ) { + if ( $this->prng->chance( 35 ) ) { + $html .= $this->prng->choice( $filler ); + } + $html .= $bit; + } + + foreach ( $this->pools as $key => $values ) { + $this->pools[ $key ] = array_values( array_unique( $values ) ); + } + + return array( + 'model' => null, + 'children' => $children, + 'html' => $html, + 'context' => '', + 'fragment' => true, + 'quirks' => false, + 'pools' => $this->pools, + ); + } + + /** + * Rows ( TreeCapture shape ) for a ``-context fragment: the + * top-level children flattened with the implicit HTML/BODY ancestors the + * fragment parser reports. + */ + public static function rows_from_fragment( array $children ): array { + $html_root = array( 'tag' => 'html', 'fid' => '(html)', 'attrs' => array(), 'children' => array() ); + $body_root = array( 'tag' => 'body', 'fid' => '(body)', 'attrs' => array(), 'children' => $children ); + + $rows = array(); + foreach ( $children as $child ) { + foreach ( self::flatten_with_ancestors( $child, array( $body_root, $html_root ) ) as $pair ) { + list( $element, $ancestors ) = $pair; + + $attrs = array(); + $seen = array(); + foreach ( $element['attrs'] as $attr ) { + $lower = ascii_strtolower( $attr[0] ); + if ( isset( $seen[ $lower ] ) ) { + continue; + } + $seen[ $lower ] = true; + $attrs[] = array( $lower, $attr[1] ); + } + + $ancestor_tags = array(); + foreach ( $ancestors as $ancestor ) { + $ancestor_tags[] = strtoupper( ascii_strtolower( $ancestor['tag'] ) ); + } + + $rows[] = array( + 'tag' => strtoupper( ascii_strtolower( $element['tag'] ) ), + 'fid' => $element['fid'], + 'attrs' => $attrs, + 'ancestorTags' => $ancestor_tags, + ); + } + } + return $rows; + } + private function build(): array { $has_doctype = $this->prng->chance( 85 ); diff --git a/tools/css-selector-fuzz/lib/TreeCapture.php b/tools/css-selector-fuzz/lib/TreeCapture.php index 9edc3b0541757..bd64dc30eb6de 100644 --- a/tools/css-selector-fuzz/lib/TreeCapture.php +++ b/tools/css-selector-fuzz/lib/TreeCapture.php @@ -24,6 +24,13 @@ class TreeCapture { const CAPTURE_ITERATION_LIMIT = 20000; /** + * Captures the processor's view of a document or a fragment. + * + * @param string $html The markup ( full document or fragment ). + * @param string|null $context When set, parse as a fragment in this + * context ( e.g. '' ); the tag + * processor has no fragment mode, so tagRows + * is null in that case. * @return array{ * htmlRows: array|null, * tagRows: array|null, @@ -31,7 +38,7 @@ class TreeCapture { * error: string|null, * } */ - public static function capture( string $html ): array { + public static function capture( string $html, ?string $context = null ): array { $out = array( 'htmlRows' => null, 'tagRows' => null, @@ -39,7 +46,13 @@ public static function capture( string $html ): array { 'error' => null, ); - $processor = \WP_HTML_Processor::create_full_parser( $html ); + $processor = null === $context + ? \WP_HTML_Processor::create_full_parser( $html ) + : \WP_HTML_Processor::create_fragment( $html, $context ); + if ( null === $processor ) { + $out['error'] = 'fragment-context-unsupported'; + return $out; + } $rows = array(); $iterations = 0; while ( $processor->next_tag() ) { @@ -69,6 +82,12 @@ public static function capture( string $html ): array { $out['htmlRows'] = $rows; $out['quirks'] = $processor->is_quirks_mode(); + // The tag processor has no fragment mode; a fragment case exercises + // the html processor's select() only. + if ( null !== $context ) { + return $out; + } + $tag_processor = new \WP_HTML_Tag_Processor( $html ); $tag_rows = array(); $iterations = 0; diff --git a/tools/css-selector-fuzz/lib/Worker.php b/tools/css-selector-fuzz/lib/Worker.php index e81f1ba677de9..46ad6f7fb3bd8 100644 --- a/tools/css-selector-fuzz/lib/Worker.php +++ b/tools/css-selector-fuzz/lib/Worker.php @@ -61,8 +61,9 @@ class Worker { public static function run_case( int $seed ): array { Bootstrap::load(); - $prng = new Prng( (string) $seed, 'css-selector-fuzz-case' ); - $is_wild = $prng->chance( 30 ); + $prng = new Prng( (string) $seed, 'css-selector-fuzz-case' ); + $is_wild = $prng->chance( 30 ); + $is_fragment = ! $is_wild && $prng->chance( 20 ); $failures = array(); $record = static function ( string $invariant, array $detail ) use ( &$failures ) { @@ -88,13 +89,18 @@ public static function run_case( int $seed ): array { $capture_error = null; $attempts = $is_wild ? 8 : 1; for ( $attempt = 0; $attempt < $attempts; $attempt++ ) { - $document = $is_wild - ? WildDocumentGenerator::generate( $prng->fork( "wild-document:{$attempt}" ) ) - : DocumentGenerator::generate( $prng->fork( 'document' ) ); + if ( $is_wild ) { + $document = WildDocumentGenerator::generate( $prng->fork( "wild-document:{$attempt}" ) ); + } elseif ( $is_fragment ) { + $document = DocumentGenerator::generate_fragment( $prng->fork( 'fragment' ) ); + } else { + $document = DocumentGenerator::generate( $prng->fork( 'document' ) ); + } + $context = ( $document['fragment'] ?? false ) ? $document['context'] : null; list( $capture, $capture_error ) = self::guard( - static function () use ( $document ) { - return TreeCapture::capture( $document['html'] ); + static function () use ( $document, $context ) { + return TreeCapture::capture( $document['html'], $context ); } ); @@ -120,7 +126,9 @@ static function () use ( $document ) { $tag_rows = $capture['tagRows']; $quirks = $capture['quirks']; - if ( ! $is_wild ) { + if ( $is_fragment ) { + self::check_fragment_capture_against_model( $document, $capture, $record ); + } elseif ( ! $is_wild ) { self::check_capture_against_model( $document, $capture, $record ); } } @@ -283,7 +291,10 @@ static function () use ( $complex_list ) { $html_matches = self::check_select_matches( 'html', $selector_string, $document, $expected, $record ); - $lexbor_state = self::check_lexbor_differential( $complex_ast, $selector_string, $document, $rows, $quirks, $expected, $record ); + // lexbor parses full documents only; fragments skip it. + if ( ! ( $document['fragment'] ?? false ) ) { + $lexbor_state = self::check_lexbor_differential( $complex_ast, $selector_string, $document, $rows, $quirks, $expected, $record ); + } } elseif ( null === $complex_list && null === $complex_error ) { self::check_select_rejection( 'html', $selector_string, $document, $record ); } @@ -495,6 +506,46 @@ static function () use ( $complex_list ) { ); } + /** + * Fragment analogue of check_capture_against_model: the ``-context + * fragment capture must equal the model rows built from the body-level + * children ( with the implicit HTML/BODY ancestors ). + */ + private static function check_fragment_capture_against_model( array $document, array $capture, callable $record ): void { + $model_rows = DocumentGenerator::rows_from_fragment( $document['children'] ); + + $normalize = static function ( array $rows ): array { + $out = array(); + foreach ( $rows as $row ) { + $attrs = array(); + foreach ( $row['attrs'] as $attr ) { + $attrs[ $attr[0] ] = $attr[1]; + } + ksort( $attrs ); + $out[] = array( + 'tag' => $row['tag'], + 'fid' => $row['fid'], + 'attrs' => $attrs, + 'ancestorTags' => $row['ancestorTags'], + ); + } + return $out; + }; + + $expected = $normalize( $model_rows ); + $actual = $normalize( $capture['htmlRows'] ); + if ( $expected !== $actual ) { + $record( + 'model-desync', + array( + 'processor' => 'fragment', + 'expected' => $expected, + 'actual' => $actual, + ) + ); + } + } + /** * Verifies that the processor's captured view of a safe (model-built) * document agrees with the generated model — this guards the oracle @@ -566,15 +617,22 @@ private static function check_capture_against_model( array $document, array $cap /** * Runs a select() loop over the document, collecting matched data-fids. * - * @param string $target 'html' or 'tag'. + * @param string $target 'html' or 'tag'. + * @param array $document The case document ( may request fragment mode ). * @return array{0: string[]|null, 1: \Throwable|null} */ - private static function collect_matches( string $target, string $selector_string, string $html ): array { + private static function collect_matches( string $target, string $selector_string, array $document ): array { + $html = $document['html']; + $context = ( $document['fragment'] ?? false ) ? $document['context'] : null; return self::guard( - static function () use ( $target, $selector_string, $html ) { - $processor = 'html' === $target - ? \WP_HTML_Processor::create_full_parser( $html ) - : new \WP_HTML_Tag_Processor( $html ); + static function () use ( $target, $selector_string, $html, $context ) { + if ( 'tag' === $target ) { + $processor = new \WP_HTML_Tag_Processor( $html ); + } elseif ( null !== $context ) { + $processor = \WP_HTML_Processor::create_fragment( $html, $context ); + } else { + $processor = \WP_HTML_Processor::create_full_parser( $html ); + } $matches = array(); $iterations = 0; @@ -610,7 +668,7 @@ static function () use ( $target, $selector_string, $html ) { private static function check_select_matches( string $target, string $selector_string, array $document, array $expected, callable $record ): ?array { Bootstrap::reset_doing_it_wrong(); - list( $actual, $error ) = self::collect_matches( $target, $selector_string, $document['html'] ); + list( $actual, $error ) = self::collect_matches( $target, $selector_string, $document ); if ( null !== $error ) { $record( @@ -831,7 +889,7 @@ static function () use ( $variant_list ) { } Bootstrap::reset_doing_it_wrong(); - list( $variant_matches, $match_error ) = self::collect_matches( 'html', $variant_selector, $document['html'] ); + list( $variant_matches, $match_error ) = self::collect_matches( 'html', $variant_selector, $document ); if ( null !== $match_error ) { $record( @@ -866,11 +924,16 @@ static function () use ( $variant_list ) { private static function check_select_rejection( string $target, string $selector_string, array $document, callable $record ): void { Bootstrap::reset_doing_it_wrong(); + $context = ( $document['fragment'] ?? false ) ? $document['context'] : null; list( $results, $error ) = self::guard( - static function () use ( $target, $selector_string, $document ) { - $processor = 'html' === $target - ? \WP_HTML_Processor::create_full_parser( $document['html'] ) - : new \WP_HTML_Tag_Processor( $document['html'] ); + static function () use ( $target, $selector_string, $document, $context ) { + if ( 'tag' === $target ) { + $processor = new \WP_HTML_Tag_Processor( $document['html'] ); + } elseif ( null !== $context ) { + $processor = \WP_HTML_Processor::create_fragment( $document['html'], $context ); + } else { + $processor = \WP_HTML_Processor::create_full_parser( $document['html'] ); + } // Two calls: the second exercises the parse cache. return array( $processor->select( $selector_string ), $processor->select( $selector_string ) ); From 44058b4c015da49ce70dcb8497f82819e79b5225 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 14:04:47 +0200 Subject: [PATCH 164/634] CSS selector fuzz: triage 5000-seed run, update findings and roadmap 5000-seed isolated run on core @ 46334f170b: 427 failures, 0 crashes, every failure triaged to one of the three known bugs (Bug 1 -> metamorphic-ast / ast-mismatch / path-expectation; Bug 2 -> match-mismatch-html/tag; Bug 3 -> metamorphic-parse / parse-expectation). Zero lexbor-divergence (the third oracle agreed with the reference matcher on every compared no-quirks case) and zero model-desync. With all three fixes applied the same 5000 seeds run completely clean, confirming the fuzzer reports exactly these three bugs and no spurious oracle/generator defect. FINDINGS.md: add the signature->bug triage table and refresh the fuzzer status. NEXT-STEPS.md: mark the roadmap complete against the acceptance bar. All three known bugs verified still reproducing. --- tools/css-selector-fuzz/FINDINGS.md | 54 ++++++++++++++++++++++++--- tools/css-selector-fuzz/NEXT-STEPS.md | 13 ++++--- 2 files changed, 56 insertions(+), 11 deletions(-) diff --git a/tools/css-selector-fuzz/FINDINGS.md b/tools/css-selector-fuzz/FINDINGS.md index 981b33ef41d80..ad9f47c3458b7 100644 --- a/tools/css-selector-fuzz/FINDINGS.md +++ b/tools/css-selector-fuzz/FINDINGS.md @@ -1,11 +1,17 @@ # CSS Selector Fuzzer — Findings -Run: branch `html-css-fuzz` @ `6ebbcc2fe4`, PHP 8.4.21. ~3600 deterministic +Run: branch `html-css-fuzz` @ `46334f170b`, PHP 8.4.21. 5000 deterministic seeds, 0 crashes/timeouts. Three distinct, reproduced WordPress-core correctness bugs in the new HTML-API CSS selector support. Every selector below is valid, supported CSS that the API mis-handles **without** reporting lack of support. +No new bugs surfaced beyond these three, and no fuzzer-side (oracle or +generator) defect surfaced: with all three fixes applied a 5000-seed run is +completely clean, and the lexbor differential (third independent oracle) agreed +with the reference matcher on every compared no-quirks case (0 `lexbor-divergence`). + Reproduce any case: `php tools/css-selector-fuzz/replay.php --selector '' [--html '']`. +Auto-minimize a failing seed: `php tools/css-selector-fuzz/minimize.php --seed `. --- @@ -105,10 +111,46 @@ character of the selector string. --- +## Triage of the 5000-seed run (unpatched core) + +427 failures, every one attributable to one of the three bugs above. The +signature → bug mapping (and why each is a WP finding, not a fuzzer defect): + +| signature | hits | bug | how it manifests | +|---|---|---|---| +| `metamorphic-ast` (5 variants) | 328 | Bug 1 | a re-rendered / escaped variant of a selector parses to a different AST because an identity escape after multibyte content mis-decodes | +| `ast-mismatch` | 71 | Bug 1 | generated AST ≠ parsed AST, same root cause | +| `path-expectation` | 1 | Bug 1 | a path-directed selector with a multibyte-then-identity-escape value (`Über90\ x`) mis-parses, so the element it was built from no longer matches | +| `metamorphic-parse` (4 variants) | 9 | Bug 3 | a re-rendered variant ending in a single-char unquoted value at EOF is wrongly rejected | +| `parse-expectation` (2 variants) | 7 | Bug 3 | the generated selector itself ends in `=x]` and is wrongly rejected (e.g. `[dir =a]`) | +| `match-mismatch-html` | 7 | Bug 2 | empty-operand `^= *= $=` match elements the spec says they must not | +| `match-mismatch-tag` | 4 | Bug 2 | same, via the tag processor | + +Zero `lexbor-divergence`, zero `model-desync`, zero crashes/timeouts. With all +three fixes applied, the same 5000 seeds run with **0 failures** — confirming +the fuzzer reports exactly these three bugs and nothing spurious. + ## Fuzzer status -Implemented and validated: deterministic seeds, seed-based replay, generative -6-bucket selector generation, independent reference matcher, ~18 invariants, -process-isolated runner, self-check suite. `php tools/css-selector-fuzz/tests/self-check.php` -passes; see `README.md` for usage. No fuzzer-side (oracle/generator) defects -surfaced in 3600 seeds — all failures are the three target bugs above. +Implemented and validated: + +- Deterministic seeds, seed-based replay, self-check suite + (`php tools/css-selector-fuzz/tests/self-check.php` passes). +- Seven-bucket selector generation including **path-directed** synthesis + (combinator positive-match rate ~68% vs ~14% before) and **edge-escape** + (U+FFFD escape decoder, input normalization). +- Three independent match oracles: the spec-faithful `ReferenceMatcher`, the + AST round-trip, and a **lexbor differential** (liblexbor v3.0.0, no-quirks + documents, tree-equality gated). The three agree on every compared case. +- **Metamorphic invariants** (oracle-free): meaning-preserving transforms keep + the match set; AST-preserving transforms keep the AST. +- **Parser-derived oracle tree** (`TreeCapture`): the processor's own parse is + ground truth, so **wild / restructured HTML** and **`` fragments** are + fuzzed, not only clean trees. +- **Line coverage** measured (93.8%, see `COVERAGE.md`; 96.8% of reachable + code, remainder justified). +- **Automatic minimizer** (`minimize.php`): delta-debugs selector and HTML to a + minimal reproducer preserving a chosen signature. + +See `README.md` for usage and `NEXT-STEPS.md` for the roadmap this work +completed. diff --git a/tools/css-selector-fuzz/NEXT-STEPS.md b/tools/css-selector-fuzz/NEXT-STEPS.md index 0b509450a177e..86fa37c61eb93 100644 --- a/tools/css-selector-fuzz/NEXT-STEPS.md +++ b/tools/css-selector-fuzz/NEXT-STEPS.md @@ -1,10 +1,13 @@ # CSS Selector Fuzzer — Next Steps / Improvement Roadmap -Status: first-generation fuzzer is implemented, validated, and has found three -real WordPress-core bugs (see `FINDINGS.md`). Design and current coverage are in -`README.md`. This document is the prioritized plan to take it from "found three -bugs" to "exhaustive and trustworthy." Do NOT re-explain the existing tool here; -read `README.md` and `FINDINGS.md` first. +> **Status: all seven work items below are implemented and validated** (see +> `README.md`, `COVERAGE.md`, `FINDINGS.md`). The acceptance bar is met: +> coverage measured (93.8%; 96.8% of reachable code, remainder justified); +> three oracles agree on no-quirks supported cases with every divergence +> triaged; metamorphic invariants passing; combinator positive-match rate +> raised from 14.5% to ~68% (path-directed bucket); minimizer working; a clean +> 5000-seed run with all signatures triaged to the three known bugs, all of +> which still reproduce. The notes below are retained as the design rationale. Repo: `/Users/jonsurrell/a8c/wordpress-develop/html-css-fuzz`, branch `html-css-fuzz` @ `6ebbcc2fe4` (trunk + merged `html-api/add-css-selector-parser`). From 7336efad279a0790488817a42a580f0bb20d794a Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 14:37:15 +0200 Subject: [PATCH 165/634] CSS selector fuzz: stop the minimizer silently retargeting a different bug Reviewer found minimize.php --seed could print 'reproduced: yes' for a signature the seed never produced: run_pair only checks self-contained invariants, so a seed whose recorded failure is generator-side (ast-mismatch, parse-expectation, path-expectation, model-desync) would fall through to minimizing an unrelated incidental self-contained signature and report success. run_case now returns its per-case signatures. minimize.php --seed restricts targets to signatures sharing an INVARIANT with the seed's own failures (invariant-level, not exact-hash, so the same metamorphic invariant exposed by a different transform draw still counts as faithful). When the seed's failures are entirely generator-side it refuses by default and lists the nearby self-contained signatures; --signature opts into a retarget, which is then explicitly labelled 'retargeted' / NOTE in the output. Docs updated to scope --seed accordingly. --- tools/css-selector-fuzz/FINDINGS.md | 5 +- tools/css-selector-fuzz/README.md | 18 +++++- tools/css-selector-fuzz/lib/Worker.php | 20 ++++-- tools/css-selector-fuzz/minimize.php | 88 ++++++++++++++++++++++++-- 4 files changed, 113 insertions(+), 18 deletions(-) diff --git a/tools/css-selector-fuzz/FINDINGS.md b/tools/css-selector-fuzz/FINDINGS.md index ad9f47c3458b7..302d6218a6f0a 100644 --- a/tools/css-selector-fuzz/FINDINGS.md +++ b/tools/css-selector-fuzz/FINDINGS.md @@ -11,7 +11,10 @@ completely clean, and the lexbor differential (third independent oracle) agreed with the reference matcher on every compared no-quirks case (0 `lexbor-divergence`). Reproduce any case: `php tools/css-selector-fuzz/replay.php --selector '' [--html '']`. -Auto-minimize a failing seed: `php tools/css-selector-fuzz/minimize.php --seed `. +Auto-minimize a failing seed: `php tools/css-selector-fuzz/minimize.php --seed ` +(faithful for seeds with a self-contained failure; seeds whose only recorded +failure is generator-side — `ast-mismatch`, `parse-expectation` — are refused +unless a related self-contained signature is opted into with `--signature`). --- diff --git a/tools/css-selector-fuzz/README.md b/tools/css-selector-fuzz/README.md index 3042338f18917..2c60bf5c73a51 100644 --- a/tools/css-selector-fuzz/README.md +++ b/tools/css-selector-fuzz/README.md @@ -133,10 +133,22 @@ both the selector and the HTML while preserving a failure signature): php tools/css-selector-fuzz/minimize.php --seed 1234 php tools/css-selector-fuzz/minimize.php --selector 'sel' --html '<…>' --signature match-mismatch -The minimizer drives `Worker::run_pair`, which checks only self-contained +The minimizer drives `Worker::run_pair`, which checks only **self-contained** invariants — those computable from the (selector, html) pair without the -generator's intended AST. All three known bugs reduce to one: Bug 1 → -`metamorphic-ast`, Bug 2 → `match-mismatch-html`, Bug 3 → `metamorphic-parse`. +generator's intended AST: `match-mismatch-*`, `metamorphic-*`, +`lexbor-divergence`, `parse-error`, `ast-shape`, `ast-cross-grammar`, and the +rejection checks. The generator-side invariants `ast-mismatch`, +`parse-expectation`, `path-expectation`, and `model-desync` are **not** +self-contained and cannot be reproduced from the pair alone. + +So `--seed` faithfully minimizes only seeds whose failure is self-contained. +The three known bugs each *also* surface a self-contained signature (Bug 1 → +`metamorphic-ast`, Bug 2 → `match-mismatch-html`, Bug 3 → `metamorphic-parse`), +but a seed whose recorded failure is *only* the generator-side form (e.g. a +Bug-1 seed that recorded `ast-mismatch` before the metamorphic phase ran) is +**refused by default** rather than silently retargeted — pass `--signature` +to opt into minimizing a related self-contained signature, which is then +clearly labelled as a retarget in the output. Run a batch in-process (no isolation, faster): diff --git a/tools/css-selector-fuzz/lib/Worker.php b/tools/css-selector-fuzz/lib/Worker.php index 46ad6f7fb3bd8..6371b617cc028 100644 --- a/tools/css-selector-fuzz/lib/Worker.php +++ b/tools/css-selector-fuzz/lib/Worker.php @@ -334,14 +334,20 @@ static function ( $failure ) { ) ); + $signatures = array(); + foreach ( $failures as $failure ) { + $signatures[] = self::signature( $failure ); + } + return array( - 'seed' => $seed, - 'bucket' => $selector['bucket'], - 'digest' => $digest, - 'failures' => $failures, - 'selector' => $selector_string, - 'html' => $document['html'], - 'lexbor' => $lexbor_state, + 'seed' => $seed, + 'bucket' => $selector['bucket'], + 'digest' => $digest, + 'failures' => $failures, + 'signatures' => array_values( array_unique( $signatures ) ), + 'selector' => $selector_string, + 'html' => $document['html'], + 'lexbor' => $lexbor_state, ); } diff --git a/tools/css-selector-fuzz/minimize.php b/tools/css-selector-fuzz/minimize.php index 3f3870b97b247..edfc892689fa7 100644 --- a/tools/css-selector-fuzz/minimize.php +++ b/tools/css-selector-fuzz/minimize.php @@ -39,11 +39,27 @@ $max_attempts = option_int( $options, 'max-attempts', 20000 ); $sig_filter = option_string( $options, 'signature', null ); -$seed = option_int( $options, 'seed', -1 ); +/* + * In --seed mode, the seed's OWN failures ( from run_case ) are the source + * of truth. The minimizer can only preserve "self-contained" signatures + * ( those run_pair re-checks without the generator's intended AST ); the + * generator-side ones ( ast-mismatch, parse-expectation, path-expectation, + * model-desync ) are invisible to run_pair. Targeting must therefore be + * restricted to the intersection of the seed's failures and run_pair's + * view — otherwise the minimizer could silently retarget to an unrelated + * incidental signature and report a false "reproduced". + */ +$seed = option_int( $options, 'seed', -1 ); +$seed_signatures = null; if ( $seed >= 0 ) { - $case = Worker::run_case( $seed ); - $selector = $case['selector']; - $html = $case['html']; + $case = Worker::run_case( $seed ); + $selector = $case['selector']; + $html = $case['html']; + $seed_signatures = $case['signatures']; + if ( array() === $seed_signatures ) { + fwrite( STDERR, "Seed {$seed} produced no failure; nothing to minimize.\n" ); + exit( 1 ); + } } else { $selector = option_string( $options, 'selector', null ); $html = option_string( $options, 'html', null ); @@ -61,14 +77,66 @@ $baseline = $signatures_of( $selector, $html ); if ( array() === $baseline ) { fwrite( STDERR, "The starting pair does not reproduce any self-contained failure.\n" ); + if ( null !== $seed_signatures ) { + fwrite( STDERR, 'Seed failure(s): ' . implode( ', ', $seed_signatures ) . "\n" ); + fwrite( STDERR, "These are generator-side signatures the minimizer cannot reproduce from the\n" ); + fwrite( STDERR, "pair alone. Minimize a seed whose failure is self-contained, or pass\n" ); + fwrite( STDERR, "--selector/--html directly.\n" ); + } fwrite( STDERR, 'selector: ' . printable_bytes( $selector ) . "\n" ); exit( 1 ); } -// Pick the target signature. -$target = $baseline[0]; +/* + * Candidate targets are matched at the INVARIANT level, not the exact + * signature hash: a signature embeds transform-specific detail ( e.g. + * metamorphic-parse via `rerender` vs via `dup-branch` ), and run_pair's + * fixed metamorphic draws may expose the same invariant through a + * different transform than run_case did. Same invariant == same bug class, + * so that is faithful. A DIFFERENT invariant ( e.g. the seed's generator- + * side ast-mismatch vs an incidental self-contained metamorphic-ast ) is a + * genuine retarget and must be opted into. + */ +$invariant_of = static function ( string $signature ): string { + $pos = strrpos( $signature, ':' ); + return false === $pos ? $signature : substr( $signature, $pos + 1 ); +}; + +$retargeted = false; +if ( null === $seed_signatures ) { + $candidates = $baseline; +} else { + $seed_invariants = array_map( $invariant_of, $seed_signatures ); + $candidates = array(); + foreach ( $baseline as $signature ) { + if ( in_array( $invariant_of( $signature ), $seed_invariants, true ) ) { + $candidates[] = $signature; + } + } +} + +if ( array() === $candidates ) { + // The seed's failures are all generator-side ( no self-contained + // invariant in common ); refuse to silently minimize an unrelated + // incidental signature. + fwrite( STDERR, "Seed {$seed}'s failures are not self-contained, so the minimizer cannot\n" ); + fwrite( STDERR, "faithfully reproduce them.\n" ); + fwrite( STDERR, 'Seed failure(s): ' . implode( ', ', $seed_signatures ) . "\n" ); + fwrite( STDERR, 'Self-contained nearby: ' . implode( ', ', $baseline ) . "\n" ); + fwrite( STDERR, "Re-run with --signature to minimize one of the nearby signatures\n" ); + fwrite( STDERR, "explicitly ( understanding it is a related, not identical, failure ).\n" ); + if ( null === $sig_filter ) { + exit( 1 ); + } + // User explicitly opted into a nearby signature. + $candidates = $baseline; + $retargeted = true; +} + +// Pick the target signature from the eligible candidates. +$target = $candidates[0]; if ( null !== $sig_filter ) { - foreach ( $baseline as $candidate ) { + foreach ( $candidates as $candidate ) { if ( false !== strpos( $candidate, $sig_filter ) ) { $target = $candidate; break; @@ -165,6 +233,8 @@ static function ( string $candidate ) use ( $reproduces, &$html ): bool { echo json_encode_safe( array( 'target' => $target, + 'retargeted' => $retargeted, + 'seedSignatures' => $seed_signatures, 'reproduced' => $ok, 'attempts' => $attempts, 'selector' => printable_bytes( $selector ), @@ -179,6 +249,10 @@ static function ( string $candidate ) use ( $reproduces, &$html ): bool { } echo "target: {$target}\n"; +if ( $retargeted ) { + echo 'NOTE: seed failure(s) ' . implode( ', ', $seed_signatures ) . " are generator-side;\n"; + echo " minimized the related self-contained signature above instead.\n"; +} echo 'reproduced: ' . ( $ok ? 'yes' : 'NO' ) . "\n"; echo "attempts: {$attempts}\n"; echo 'selector: ' . printable_bytes( $selector ) . ' (' . strlen( $selector ) . " bytes)\n"; From 5f0ad7ce06efc812dbccaa63da7f8c8471edd2b8 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 14:39:06 +0200 Subject: [PATCH 166/634] CSS selector fuzz: make lexbor oracle death observable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewers noted the lexbor tally was computed then discarded and the 'off' state conflated 'oracle not applicable' with 'oracle dead', so a third oracle that died mid-run (PHP latches available()=false and every later case silently returns 'off') would leave no trace in artifacts. Split the state into 'n/a' (unparseable selector / fragment / no tree — differential genuinely does not apply) vs 'unavailable' (harness missing or died) and 'error'. Aggregate the per-case tally into the batch summary (already present) and now into runner state.json under 'lexbor'. The runner prints a loud WARNING if unavailable/error appear after the harness had been live, or a NOTE if it never ran at all. Verified both paths. --- tools/css-selector-fuzz/README.md | 11 ++++++++++- tools/css-selector-fuzz/lib/Worker.php | 12 +++++++++--- tools/css-selector-fuzz/runner.php | 19 +++++++++++++++++++ 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/tools/css-selector-fuzz/README.md b/tools/css-selector-fuzz/README.md index 2c60bf5c73a51..c48c790e3fdc9 100644 --- a/tools/css-selector-fuzz/README.md +++ b/tools/css-selector-fuzz/README.md @@ -88,7 +88,16 @@ produces the same document, the same selector, and the same verdict. Build with `sh tools/css-selector-fuzz/lexbor/build.sh` (clones and builds liblexbor, pinned to v3.0.0 = `2ae88a1c6b52`). The worker auto-detects the binary at `tools/css-selector-fuzz/lexbor/harness` and reports per-batch -tallies (`compared` / `tree-gated` / `skipped-quirks` / `off`). +tallies, persisted to `state.json` under `lexbor`: + +- `compared` — the differential ran and matched fid-multisets. +- `tree-gated` — WP and lexbor built different trees; differential skipped. +- `skipped-quirks` / `skipped-utf8` — quirks document / non-UTF-8 AST. +- `n/a` — the differential does not apply (unparseable selector, fragment, no + captured tree). +- `unavailable` / `error` — the harness was missing or died. The runner prints + a loud warning if these appear after the harness had run, so a third oracle + that dies mid-run cannot hide behind a green run. Known lexbor issues compensated for at this pin: diff --git a/tools/css-selector-fuzz/lib/Worker.php b/tools/css-selector-fuzz/lib/Worker.php index 6371b617cc028..b2ad002ed8ac0 100644 --- a/tools/css-selector-fuzz/lib/Worker.php +++ b/tools/css-selector-fuzz/lib/Worker.php @@ -256,7 +256,12 @@ static function () use ( $complex_list ) { // --- Match phase --------------------------------------------------- $html_matches = null; - $lexbor_state = 'off'; + // 'n/a' = the lexbor differential does not apply to this case + // ( unparseable selector, fragment, no captured tree ). Distinct from + // 'unavailable', which check_lexbor_differential reports only when the + // harness itself is missing or died — so a silently-dropped third + // oracle shows up in the per-batch tally instead of hiding in 'off'. + $lexbor_state = 'n/a'; if ( null !== $complex_ast && null !== $rows ) { $expected = ReferenceMatcher::expected_html_matches_rows( $complex_ast, $rows, $quirks ); @@ -729,11 +734,12 @@ private static function check_select_matches( string $target, string $selector_s * means reference == lexbor != WP: a * high-confidence WP finding. * - * @return string Tally state: off|skipped-quirks|error|tree-gated|compared. + * @return string Tally state: + * unavailable|skipped-quirks|skipped-utf8|error|tree-gated|compared. */ private static function check_lexbor_differential( array $complex_ast, string $selector_string, array $document, array $rows, bool $quirks, array $expected, callable $record ): string { if ( ! LexborOracle::available() ) { - return 'off'; + return 'unavailable'; } if ( $quirks ) { return 'skipped-quirks'; diff --git a/tools/css-selector-fuzz/runner.php b/tools/css-selector-fuzz/runner.php index 3dbdf0ee66cbe..fc3db262b282a 100644 --- a/tools/css-selector-fuzz/runner.php +++ b/tools/css-selector-fuzz/runner.php @@ -158,6 +158,7 @@ function css_selector_fuzz_worker_summary( string $stdout ): ?array { 'crashes' => 0, 'buckets' => array(), 'signatures' => array(), + 'lexbor' => array(), 'nextSeed' => $start_seed, 'stopReason' => null, ); @@ -244,6 +245,9 @@ function css_selector_fuzz_worker_summary( string $stdout ): ?array { foreach ( $summary['signatures'] as $signature => $signature_count ) { $state['signatures'][ $signature ] = ( $state['signatures'][ $signature ] ?? 0 ) + $signature_count; } + foreach ( $summary['lexbor'] ?? array() as $lexbor_state => $lexbor_count ) { + $state['lexbor'][ $lexbor_state ] = ( $state['lexbor'][ $lexbor_state ] ?? 0 ) + $lexbor_count; + } } $seed += $count; @@ -263,5 +267,20 @@ function css_selector_fuzz_worker_summary( string $stdout ): ?array { $state['updatedAt'] = gmdate( 'c' ); write_json_file( $state_path, $state ); +/* + * The lexbor differential is the third oracle. If it ever ran ( 'compared' ) + * it was built and live; any 'unavailable' or 'error' tally then means it + * was missing for some cases or died mid-run, so part of the run had only + * two oracles. Surface that loudly rather than letting a green run hide it. + */ +$lexbor = $state['lexbor']; +$lexbor_ran = ( $lexbor['compared'] ?? 0 ) > 0; +$lexbor_lost = ( $lexbor['unavailable'] ?? 0 ) + ( $lexbor['error'] ?? 0 ); +if ( $lexbor_ran && $lexbor_lost > 0 ) { + fwrite( STDERR, "WARNING: lexbor third oracle was unavailable/errored for {$lexbor_lost} case(s); those ran with two oracles.\n" ); +} elseif ( ! $lexbor_ran ) { + fwrite( STDERR, "NOTE: lexbor third oracle never ran (harness not built?); run `sh tools/css-selector-fuzz/lexbor/build.sh` for the differential.\n" ); +} + echo json_encode_safe( $state ) . "\n"; exit( 0 === $state['failures'] ? 0 : 2 ); From 031d5c38a08c5b02180d0b74f548ac8514a99543 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 14:40:39 +0200 Subject: [PATCH 167/634] CSS selector fuzz: harden lexbor harness (base64 + fid framing) Two latent issues from the C review (neither reachable from the current generators, both defensive): - b64_decode had dead code (two empty if-bodies) and a comment claiming invalid bytes are skipped when they were actually folded into the output stream as zero, corrupting everything after a stray byte. Now genuinely skip any non-alphabet byte (testing the byte, not its table value, since 'A' legitimately maps to 0). The index is unsigned, so table[c] was never out of bounds. - put_fid wrote the raw data-fid into the tab-and-newline framed protocol; a fid containing TAB/LF/CR would desync row/match parsing on the PHP side. Generated fids are always w/e, but harden anyway: the harness replaces those three bytes with '?', and TreeCapture::sanitize_fid applies the identical replacement to WP's own fids, so a sanitized fid still compares equal (worst case a benign tree-gated skip, never a false divergence). Verified a tab-fid produces one row/match/D with no desync. --- tools/css-selector-fuzz/lexbor/harness.c | 33 +++++++++++++++++---- tools/css-selector-fuzz/lib/TreeCapture.php | 13 +++++++- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/tools/css-selector-fuzz/lexbor/harness.c b/tools/css-selector-fuzz/lexbor/harness.c index a33a198090ddf..ebd3aa32f4b4a 100644 --- a/tools/css-selector-fuzz/lexbor/harness.c +++ b/tools/css-selector-fuzz/lexbor/harness.c @@ -65,13 +65,18 @@ b64_decode(const char *in, size_t in_len, size_t *out_len) for (size_t i = 0; i < in_len; i++) { unsigned char c = (unsigned char) in[i]; + /* + * The PHP adapter always feeds well-formed base64_encode() output, + * but guard anyway: skip padding/whitespace, and actually skip any + * byte not in the alphabet ('A' legitimately maps to 0, so test the + * byte itself, not its table value). c is unsigned, so table[c] is + * always in bounds. + */ if (c == '=' || c == '\n' || c == '\r') { continue; } - if (c != 'A' && table[c] == 0 && c != 'A') { - if (c != 'A') { - /* invalid chars are skipped; base64 here is machine-made */ - } + if (c != 'A' && table[c] == 0) { + continue; } acc = (acc << 6) | (unsigned int) table[c]; bits += 6; @@ -97,6 +102,24 @@ put_upper(const lxb_char_t *name, size_t len) } } +/* + * Emit a data-fid value, replacing the framing bytes TAB / LF / CR with '?'. + * Generated documents only ever use fids like "w12" / "e3", so this never + * fires in practice; it guards the line-and-tab protocol against a fid that + * contains a control char (which would otherwise desync row/match parsing on + * the PHP side). LexborOracle applies the identical replacement when reading + * WP's own fids, so a sanitized fid still compares equal — the worst case is + * a benign tree-gated skip, never a false divergence. + */ +static void +put_fid_value(const lxb_char_t *value, size_t value_len) +{ + for (size_t i = 0; i < value_len; i++) { + unsigned char c = value[i]; + putchar((c == '\t' || c == '\n' || c == '\r') ? '?' : c); + } +} + static void put_fid(lxb_dom_node_t *node) { @@ -106,7 +129,7 @@ put_fid(lxb_dom_node_t *node) element, (const lxb_char_t *) "data-fid", 8, &value_len); if (value != NULL) { - fwrite(value, 1, value_len, stdout); + put_fid_value(value, value_len); return; } diff --git a/tools/css-selector-fuzz/lib/TreeCapture.php b/tools/css-selector-fuzz/lib/TreeCapture.php index bd64dc30eb6de..616a3ff65ba76 100644 --- a/tools/css-selector-fuzz/lib/TreeCapture.php +++ b/tools/css-selector-fuzz/lib/TreeCapture.php @@ -110,7 +110,18 @@ public static function capture( string $html, ?string $context = null ): array { /** The element's data-fid, or the same placeholder collect_matches() uses. */ private static function fid_of( $processor ): string { $fid = $processor->get_attribute( 'data-fid' ); - return is_string( $fid ) ? $fid : '(missing-fid:' . $processor->get_tag() . ')'; + return is_string( $fid ) ? self::sanitize_fid( $fid ) : '(missing-fid:' . $processor->get_tag() . ')'; + } + + /** + * Replaces the lexbor protocol framing bytes ( TAB / LF / CR ) in a fid + * with '?'. Generated fids never contain these, but the lexbor harness + * applies the same replacement, so matching this here keeps the two trees + * comparable even for a hypothetical control-char fid ( the worst case is + * a benign tree-gated skip, never a false divergence ). + */ + public static function sanitize_fid( string $fid ): string { + return strtr( $fid, "\t\n\r", '???' ); } /** From a5f832e938b5354540ec3823fc4c2a0f14b31d63 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 14:42:31 +0200 Subject: [PATCH 168/634] CSS selector fuzz: make class-selector coverage deterministic Reviewer found COVERAGE.md's documented command gave 375/401, not the reported 376/401: class-wp-css-class-selector.php:58 (the bare/trailing '.' guard) is reachable but was only sampled intermittently (it landed at seeds 4001-4050, outside the 3000-seed window), so the report's 'all 25 unreached lines accounted for' was off by one. Add the 'a.' invalid template so that guard is hit deterministically within the documented window. class-selector is now a reproducible 10/10 and the 376/401 (93.8%) total matches the documented command exactly; the 25 unreached lines are the 12 case-label artifacts + 13 defensive guards already itemized. --- tools/css-selector-fuzz/COVERAGE.md | 9 ++++++--- tools/css-selector-fuzz/lib/SelectorGenerator.php | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/css-selector-fuzz/COVERAGE.md b/tools/css-selector-fuzz/COVERAGE.md index e69e34cf38a17..5c772ce27793c 100644 --- a/tools/css-selector-fuzz/COVERAGE.md +++ b/tools/css-selector-fuzz/COVERAGE.md @@ -70,6 +70,9 @@ guarantees, or branches for grammar the parser never emits: (`consume_escaped_codepoint` for NUL / surrogate / over-max codepoints) and the `normalize_selector_input` NUL→U+FFFD and CR/CRLF/FF→LF paths, which the structural generators cannot reach. -- A few `invalid`-bucket templates (`[ a`, `[a="x\`) were added to reach - attribute/string parse guards that random structural generation rarely - lands on. +- A few `invalid`-bucket templates (`[ a`, `[a="x\`, `a.`) were added to reach + attribute / string / class parse guards that random structural generation + rarely lands on. With them the per-file numbers above are **deterministic** + at the documented 3000-seed window (e.g. `class-wp-css-class-selector.php` + reaches 10/10 reliably rather than depending on whether a bare `.` happened + to be sampled). diff --git a/tools/css-selector-fuzz/lib/SelectorGenerator.php b/tools/css-selector-fuzz/lib/SelectorGenerator.php index 7bf1851f192e6..88a2cbaefd9a9 100644 --- a/tools/css-selector-fuzz/lib/SelectorGenerator.php +++ b/tools/css-selector-fuzz/lib/SelectorGenerator.php @@ -1273,6 +1273,7 @@ private function gen_invalid(): string { ' ', "\t\n\f ", '.', + 'a.', '#', '[', ']', From acd1762d1861fdcd27ce9b80834a4b3c29745fa0 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 14:44:12 +0200 Subject: [PATCH 169/634] CSS selector fuzz: honest framing of oracle strength Reviewers flagged overclaims in the prose. Corrected with measured numbers, no behavior change: - 'most match assertions non-vacuous' -> true only within the path-directed bucket (~67% non-vacuous); aggregate across all buckets is ~62% vacuous [] == [] by design (negative-oriented and parse-focused buckets are intentionally empty-set). README, FINDINGS, NEXT-STEPS now state both numbers and the actual point (the combinator walker is exercised with real depth). - 'three oracles agree on every compared case' -> kept, but disclose ~half of compared cases are themselves vacuous. - Quirks-mode class/ID matching has NO independent third oracle (lexbor #368 excludes quirks docs), and ReferenceMatcher shares WP's ASCII-fold reading by construction -> documented as the weakest-covered behavior rather than implied-covered. - The determinism digest covers the WP-under-test surface but not the lexbor oracle's own output -> noted. --- tools/css-selector-fuzz/FINDINGS.md | 5 +++++ tools/css-selector-fuzz/NEXT-STEPS.md | 5 ++++- tools/css-selector-fuzz/README.md | 29 ++++++++++++++++++++++----- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/tools/css-selector-fuzz/FINDINGS.md b/tools/css-selector-fuzz/FINDINGS.md index 302d6218a6f0a..4d5331df629a6 100644 --- a/tools/css-selector-fuzz/FINDINGS.md +++ b/tools/css-selector-fuzz/FINDINGS.md @@ -9,6 +9,11 @@ No new bugs surfaced beyond these three, and no fuzzer-side (oracle or generator) defect surfaced: with all three fixes applied a 5000-seed run is completely clean, and the lexbor differential (third independent oracle) agreed with the reference matcher on every compared no-quirks case (0 `lexbor-divergence`). +Caveats on the strength of that agreement: roughly half of the `compared` +cases (and ~62% of all match assertions across buckets) are vacuous `[] == []`; +quirks-mode class/ID matching is excluded from the differential (lexbor #368) +and so rests on `ReferenceMatcher` alone. See `README.md` for the full +disclosure. Reproduce any case: `php tools/css-selector-fuzz/replay.php --selector '' [--html '']`. Auto-minimize a failing seed: `php tools/css-selector-fuzz/minimize.php --seed ` diff --git a/tools/css-selector-fuzz/NEXT-STEPS.md b/tools/css-selector-fuzz/NEXT-STEPS.md index 86fa37c61eb93..5d7a76e51dc8c 100644 --- a/tools/css-selector-fuzz/NEXT-STEPS.md +++ b/tools/css-selector-fuzz/NEXT-STEPS.md @@ -167,7 +167,10 @@ keep-failing) to a minimal reproducer. Wire into `replay.php` or a new a fuzzer-oracle fix — never left ambiguous. - Metamorphic invariants in place and passing. - Positive-match rate for combinator selectors materially raised (path-directed - generation); match assertions are mostly non-vacuous. + generation): ~68% in that bucket vs ~14% before, so the combinator/breadcrumb + walker is genuinely exercised. (Aggregate across all buckets remains ~62% + vacuous `[] == []`, by design — the negative-oriented and parse-focused + buckets are intentionally mostly empty-set; see `README.md`.) - Minimizer produces minimal repros automatically. - A clean multi-thousand-seed run with all signatures triaged; `FINDINGS.md` updated with any new bugs (each with a minimal repro and a one-line fix diff --git a/tools/css-selector-fuzz/README.md b/tools/css-selector-fuzz/README.md index c48c790e3fdc9..92c0ce3f10579 100644 --- a/tools/css-selector-fuzz/README.md +++ b/tools/css-selector-fuzz/README.md @@ -35,9 +35,16 @@ produces the same document, the same selector, and the same verdict. match that element — or flipped into a near-miss (wrong type/class/attr guarantees a non-match; loosening `>` to descendant must keep matching). The guarantee is asserted against the reference matcher - (`path-expectation`), making most match assertions non-vacuous: - measured positive-match rate for combinator selectors is ~68% in this - bucket vs ~14% in `supported-complex`. + (`path-expectation`). Within this bucket ~67% of match assertions are + non-vacuous (positive-match rate ~68% for combinator selectors, vs ~14% + in `supported-complex`). Across *all* buckets ~38% of match assertions + are non-vacuous: the negative-oriented buckets (`unsupported`, + `invalid`, much of `supported-*`) and `edge-escape` (which targets the + parse/escape-decode path, not matching) are intentionally mostly + empty-set, so the aggregate `[] == []` rate is ~62%. The point of + path-directed generation is that the *combinator/breadcrumb* walker — + the part most likely to harbor a matching bug — is now exercised with + real depth, not that every assertion is non-vacuous. - `unsupported` — valid CSS the API intentionally rejects (pseudo-classes and -elements, `+`/`~`/`||` combinators, namespaces, non-type context selectors); must not parse. @@ -80,8 +87,13 @@ produces the same document, the same selector, and the same verdict. the selector layer, not tree construction. Verdicts: `lexbor-divergence` (lexbor ≠ reference) is a fuzzer-oracle problem; `match-mismatch-html` with no accompanying divergence means reference == lexbor ≠ WP — a - high-confidence WP finding. + high-confidence WP finding. (Roughly half of `compared` cases are + themselves non-vacuous; the rest assert `[] == []` on both engines.) - Repeating a case yields a byte-identical result digest (determinism). + Note the digest covers the WP-under-test surface (selector, html, + parse-nullness, ASTs, failure invariants) but **not** the lexbor + oracle's own output, so it would not flag a flaky lexbor result that + never escalates to a `lexbor-divergence` failure. ## lexbor harness @@ -107,7 +119,14 @@ Known lexbor issues compensated for at this pin: case-sensitive). Detected by a startup probe; when present, lexbor is compared against the reference matcher run with quirks-style class/ID folding, and quirks-mode documents are excluded from the differential - entirely (the reference matcher is the sole quirks authority). + entirely. **Consequence — a real coverage hole:** quirks-mode class/ID + matching has no independent third oracle. `ReferenceMatcher` is the sole + authority there, and it encodes the same "ASCII-only case fold in quirks" + reading WP does (both fold via ASCII-only lowercasing), so if that reading + is wrong they would be wrong identically and lexbor — the one engine that + could disagree — is excluded. This is inherent to lexbor #368 being open; + it is the weakest-covered behavior in the suite and is called out here + rather than papered over. - lexbor rejects uppercase `I`/`S` attribute-selector modifiers, and its non-ASCII ident-codepoint table omits U+00B7 and U+00C0–U+00F6 (it starts at U+00F8), rejecting e.g. `.Über` while accepting `.über`. From 86744400159a9bd5e5ba8f2e32f11d46bb5dc0e4 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 15:00:36 +0200 Subject: [PATCH 170/634] CSS selector fuzz: model class_list NUL-fold; close review nitpicks Reviewer-1 #10 (class-value decode boundary): ReferenceMatcher::class_matches now folds NUL -> U+FFFD per class token, matching WP_HTML_Tag_Processor:: class_list(). Previously the reference left raw NUL, so it would have diverged from select() on a class value containing NUL (a reference gap, not a WP bug). Pinned by five deterministic decode-boundary cases in self-check.php (NUL->FFFD, trailing NUL, FF separator) that put the two independent class tokenizers against each other and against select(). Randomized document-side NUL injection is deliberately NOT added: a hot-path PRNG draw perturbs self-check.php's fixed seed space enough to surface the known Bug 3, which would first require decoupling self-check from the unfixed core bugs. Documented as a scoped future improvement in README 'Known oracle limitations', which also distinguishes the independent class-value path from the shared get_attribute() attribute path per the reviewer's sharpening. Reviewer-2 nitpick (fid sanitization asymmetric on match path): collect_matches now routes select() fids through TreeCapture::sanitize_fid, identical to the tree-row and lexbor sides, so a control-char fid can never produce a false lexbor-divergence (unreachable today; fids are integers). Reviewer-3 nitpick: minimize.php header docstring no longer implies --seed works universally. Validated: self-check OK (incl. new cases), unpatched detects the 3 bugs, patched 2000-seed run clean (927 lexbor comparisons), all 3 bugs still reproduce. --- tools/css-selector-fuzz/README.md | 23 ++++++++++++ .../lib/ReferenceMatcher.php | 8 +++++ tools/css-selector-fuzz/lib/Worker.php | 5 ++- tools/css-selector-fuzz/minimize.php | 15 +++++--- tools/css-selector-fuzz/tests/self-check.php | 36 +++++++++++++++++++ 5 files changed, 81 insertions(+), 6 deletions(-) diff --git a/tools/css-selector-fuzz/README.md b/tools/css-selector-fuzz/README.md index 92c0ce3f10579..661e6dd575cba 100644 --- a/tools/css-selector-fuzz/README.md +++ b/tools/css-selector-fuzz/README.md @@ -136,6 +136,29 @@ Known lexbor issues compensated for at this pin: - `lxb_selectors_find` reports a node once per matching selector-list branch; `LXB_SELECTORS_OPT_MATCH_FIRST` dedupes. +## Known oracle limitations (document-side decoding) + +The match oracle's independence differs between class and attribute selectors: + +- **Class values are matched by two genuinely independent tokenizers.** WP's + `select('.x')` goes through `WP_HTML_Tag_Processor::class_list()`, which + splits on ASCII whitespace and folds NUL → U+FFFD per token; + `ReferenceMatcher::class_matches()` reimplements that independently (and is + pinned against `class_list()` on NUL/FF boundary inputs by `self-check.php`). + The random document generators do **not** emit control bytes inside class + values, so the *randomized* fuzzing never exercises this boundary — it is + covered only by the deterministic self-check cases. Randomized document-side + injection is deliberately deferred: adding it to the hot path perturbs the + deterministic self-check seed space enough to surface the known Bug 3, which + would first require decoupling `self-check.php` from the unfixed core bugs. + A worthwhile, scoped future improvement. +- **Attribute values are matched through a single shared read.** Both WP's + attribute matcher and `ReferenceMatcher::attr_matches()` read the same + `get_attribute()` output, so a value-decoding bug there would be shared and + invisible regardless of input — a genuine shared-oracle limitation that no + generator change can close (it needs an independent attribute-value decoder, + which lexbor partly provides on no-quirks documents). + ## Usage Bounded fuzz run (process-isolated chunks, crash/hang attribution): diff --git a/tools/css-selector-fuzz/lib/ReferenceMatcher.php b/tools/css-selector-fuzz/lib/ReferenceMatcher.php index 6af3301cd080b..5acbf9f5d4927 100644 --- a/tools/css-selector-fuzz/lib/ReferenceMatcher.php +++ b/tools/css-selector-fuzz/lib/ReferenceMatcher.php @@ -172,6 +172,14 @@ private static function class_matches( string $wanted, array $row, bool $quirks $word = substr( $class_value, $at, $word_length ); $at += $word_length; + /* + * WP_HTML_Tag_Processor::class_list() replaces NUL with U+FFFD in + * each class token before comparison; model that so a class value + * containing a raw NUL matches a `\0`-escaped ( U+FFFD ) selector + * the same way select() does. + */ + $word = str_replace( "\0", "\u{FFFD}", $word ); + if ( $quirks ? ascii_strtolower( $word ) === ascii_strtolower( $wanted ) diff --git a/tools/css-selector-fuzz/lib/Worker.php b/tools/css-selector-fuzz/lib/Worker.php index b2ad002ed8ac0..5bb607a032c58 100644 --- a/tools/css-selector-fuzz/lib/Worker.php +++ b/tools/css-selector-fuzz/lib/Worker.php @@ -649,7 +649,10 @@ static function () use ( $target, $selector_string, $html, $context ) { $iterations = 0; while ( $processor->select( $selector_string ) ) { $fid = $processor->get_attribute( 'data-fid' ); - $matches[] = is_string( $fid ) ? $fid : '(missing-fid:' . $processor->get_tag() . ')'; + // Sanitize identically to TreeCapture/lexbor so a fid with + // a control char can never produce a false divergence on + // the match path ( unreachable today: fids are integers ). + $matches[] = is_string( $fid ) ? TreeCapture::sanitize_fid( $fid ) : '(missing-fid:' . $processor->get_tag() . ')'; if ( ++$iterations > self::SELECT_ITERATION_LIMIT ) { throw new \RuntimeException( 'select() did not terminate within the iteration limit.' ); } diff --git a/tools/css-selector-fuzz/minimize.php b/tools/css-selector-fuzz/minimize.php index edfc892689fa7..c7fe1f1cb3dda 100644 --- a/tools/css-selector-fuzz/minimize.php +++ b/tools/css-selector-fuzz/minimize.php @@ -9,9 +9,13 @@ * * The minimizer drives Worker::run_pair, which checks only self-contained * invariants (computable from the pair alone), so it needs no generator - * intent. The three known bugs reduce to self-contained signatures: - * Bug 1 -> metamorphic-ast, Bug 2 -> match-mismatch-html, Bug 3 -> - * metamorphic-parse. + * intent. --seed faithfully minimizes only seeds whose failure is + * self-contained; the generator-side invariants (ast-mismatch, + * parse-expectation, path-expectation, model-desync) are invisible to + * run_pair, so a seed whose failure is only those is refused by default + * (each of the three known bugs DOES also surface a self-contained + * signature — Bug 1 -> metamorphic-ast, Bug 2 -> match-mismatch-html, + * Bug 3 -> metamorphic-parse — reachable via --signature). * * Usage: * php tools/css-selector-fuzz/minimize.php --seed 1234 [--signature SUBSTR] @@ -19,8 +23,9 @@ * * Options: * --signature SUBSTR Target a signature whose id or invariant contains - * SUBSTR (default: the first signature of the seed's - * failure set). + * SUBSTR. For --seed, also the way to opt into a + * related self-contained signature when the seed's own + * failure is generator-side (printed as a retarget). * --max-attempts N Cap test evaluations (default 4000). * --json Emit the reproducer as JSON. */ diff --git a/tools/css-selector-fuzz/tests/self-check.php b/tools/css-selector-fuzz/tests/self-check.php index e92cc3ecd3f7c..10196f2d62291 100644 --- a/tools/css-selector-fuzz/tests/self-check.php +++ b/tools/css-selector-fuzz/tests/self-check.php @@ -115,6 +115,42 @@ function select_fids( string $html, string $selector ): array { check( array( 'e4' ) === select_fids( $known_html, '[data-v|="hello"]' ), 'Known: [data-v|=hello].' ); check( array( 'e7' ) === select_fids( $known_html, '[lang^="en"]' ), 'Known: [lang^=en].' ); +// --- Class-value decode boundary (ReferenceMatcher vs WP class_list) -------- +// WP's class_list() folds NUL -> U+FFFD and treats FF as a separator; the +// reference matcher reimplements tokenization independently. Pin both engines +// against each other on these boundary inputs ( exercised deterministically +// here since the random document generator does not emit control bytes in +// class values — see README #10 ). Each case also checks the reference matcher +// agrees with select() over a TreeCapture of the same markup. + +function ref_fids( string $html, string $selector ): array { + $capture = \CssSelectorFuzz\TreeCapture::capture( $html ); + $list = WP_CSS_Complex_Selector_List::from_selectors( $selector ); + if ( null !== $capture['error'] || null === $list ) { + return array( '(error)' ); + } + $ast = \CssSelectorFuzz\AstExtractor::from_complex_list( $list ); + return \CssSelectorFuzz\ReferenceMatcher::expected_html_matches_rows( $ast, $capture['htmlRows'], $capture['quirks'] ); +} + +$nul_html = ""; +$ff_html = ""; + +$nul_cases = array( + array( "class NUL -> FFFD", $nul_html, ".foo\u{FFFD}bar", array( 'n0' ) ), + array( "class trailing NUL", $nul_html, ".x\u{FFFD}", array( 'n1' ) ), + array( "class raw NUL no-match", $nul_html, '.foobar', array() ), + array( "class FF separator (first)", $ff_html, '.alpha', array( 'f0' ) ), + array( "class FF separator (second)", $ff_html, '.beta', array( 'f0' ) ), +); +foreach ( $nul_cases as $case ) { + list( $label, $html, $selector, $expected ) = $case; + $wp = select_fids( $html, $selector ); + $ref = ref_fids( $html, $selector ); + check( $expected === $wp, "Decode boundary ({$label}): select() == expected." ); + check( $ref === $wp, "Decode boundary ({$label}): ReferenceMatcher == select()." ); +} + // --- Worker end-to-end on a few seeds --------------------------------------- for ( $seed = 1; $seed <= 5; $seed++ ) { From acbc6a1a4e52edbdfb0d99b74326fae73fe473ae Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 15:04:10 +0200 Subject: [PATCH 171/634] CSS selector fuzz: track self-check/known-bug decoupling as follow-up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewer-1 forward-looking note (not a blocker): self-check.php's parse-expectation loop runs over a fixed seed window that dodges the three known core bugs only by seed luck, so any future generator change can collide with them (as the deferred class-NUL injection already does). Record decoupling self-check from the unfixed core bugs as a standalone hardening item in NEXT-STEPS — worth doing independently and the prerequisite for randomized class-NUL injection. --- tools/css-selector-fuzz/NEXT-STEPS.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tools/css-selector-fuzz/NEXT-STEPS.md b/tools/css-selector-fuzz/NEXT-STEPS.md index 5d7a76e51dc8c..0081ce4d3a63a 100644 --- a/tools/css-selector-fuzz/NEXT-STEPS.md +++ b/tools/css-selector-fuzz/NEXT-STEPS.md @@ -8,6 +8,17 @@ > raised from 14.5% to ~68% (path-directed bucket); minimizer working; a clean > 5000-seed run with all signatures triaged to the three known bugs, all of > which still reproduce. The notes below are retained as the design rationale. +> +> **Open follow-up hardening (post-review):** `tests/self-check.php` runs its +> parse-expectation assertions over a fixed seed window (1–400) that currently +> dodges the three known core bugs only by seed luck. Any generator change that +> shifts the PRNG stream can collide with Bug 1/3 there (it already does for the +> deferred document-side class-NUL injection — see README "Known oracle +> limitations"). Decouple self-check from the unfixed core bugs — e.g. apply the +> three FINDINGS.md fixes inside the self-check harness, or allowlist their +> signatures in the parse-expectation loop — as a standalone hardening. This is +> worth doing on its own (it makes self-check robust to *any* future generator +> change) and is the prerequisite for randomized class-NUL document injection. Repo: `/Users/jonsurrell/a8c/wordpress-develop/html-css-fuzz`, branch `html-css-fuzz` @ `6ebbcc2fe4` (trunk + merged `html-api/add-css-selector-parser`). From 0a5ef71b4443e422dcd1bb29a356a7aad25ff70a Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 17:28:57 +0200 Subject: [PATCH 172/634] CSS selector fuzz: record fix status; correct findings inaccuracies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All three FINDINGS.md bugs are now fixed on this branch by the 'CSS selector:' commits, each with PHPUnit regression tests, and a post-fix 5000-seed run is clean. Update FINDINGS.md and the NEXT-STEPS regression anchors accordingly: the minimal repros must now NOT trigger. Corrections and additions surfaced by the fix-review panels: - Bug 2's claimed substr_compare negative-length edge does not exist (-strlen('') is 0, and PHP clamps out-of-range negative offsets); the landed fix also excludes ~= from the guard since a whitespace-delimited list never yields an empty item. - README: note lexbor's [x~=""] whitespace-value divergence (matches where Selectors-4/Chrome/WP say no match) as a latent noise source and candidate upstream report. - NEXT-STEPS: candidate finding 4 — \ at EOF is a valid escape per CSS Syntax §4.3.8 and should decode to U+FFFD in ident context, but WP rejects it ('.foo\' parses to null). Unverified, low severity. - NEXT-STEPS: self-check/known-bug decoupling reframed now that this branch's core is fixed; hazard remains for unfixed-core runs. --- tools/css-selector-fuzz/FINDINGS.md | 22 +++++++++++------ tools/css-selector-fuzz/NEXT-STEPS.md | 34 +++++++++++++++++++-------- tools/css-selector-fuzz/README.md | 6 +++++ 3 files changed, 45 insertions(+), 17 deletions(-) diff --git a/tools/css-selector-fuzz/FINDINGS.md b/tools/css-selector-fuzz/FINDINGS.md index 4d5331df629a6..5e650aac73549 100644 --- a/tools/css-selector-fuzz/FINDINGS.md +++ b/tools/css-selector-fuzz/FINDINGS.md @@ -5,6 +5,12 @@ seeds, 0 crashes/timeouts. Three distinct, reproduced WordPress-core correctness bugs in the new HTML-API CSS selector support. Every selector below is valid, supported CSS that the API mis-handles **without** reporting lack of support. +**Status: all three bugs are fixed on this branch** (commit prefix +`CSS selector:` — Bug 1 `7419a9fef6`, Bug 2 `0cefeb2fc8`, Bug 3 `16d03e2c5f`), +each with PHPUnit regression tests that fail pre-fix. A post-fix 5000-seed run +is clean (0 failures, 0 crashes). The repros below no longer trigger; they +remain as regression anchors and Trac-ready minimal test cases. + No new bugs surfaced beyond these three, and no fuzzer-side (oracle or generator) defect surfaced: with all three fixes applied a 5000-seed run is completely clean, and the lexbor differential (third independent oracle) agreed @@ -54,9 +60,8 @@ non-hex identity-escape branch is wrong. Depending on what wrong codepoint is produced this also causes spurious parse failures (a valid selector returns `null`). -**Fix direction:** read the next codepoint by byte offset, e.g. -`mb_substr( substr( $input, $offset ), 0, 1, 'UTF-8' )`, or decode the UTF-8 -lead byte length from `$input[$offset]` directly. +**Fix (landed in `7419a9fef6`):** read the next codepoint from the byte +offset: `mb_substr( substr( $input, $offset ), 0, 1, 'UTF-8' )`. --- @@ -82,9 +87,11 @@ Reproduction against `………`: | `[x$=""]` | `I` | none | | `[x~=""]` | none ✅ | none | -**Fix direction:** in `matches()`, return `false` for `^= $= *=` (and `~=`) when -`'' === $this->value`, before the `substr_compare`/`strpos` calls. (This also -removes a `substr_compare` negative-length edge with very short attribute values.) +**Fix (landed in `0cefeb2fc8`):** in `matches()`, return `false` for `^= $= *=` +when `'' === $this->value`, before the `substr_compare`/`strpos` calls. `~=` +needs no guard — a whitespace-delimited list never yields an empty item — and +a test pins that. (No `substr_compare` length edge exists here: `-strlen('')` +is `0`, and PHP clamps out-of-range negative offsets rather than erroring.) --- @@ -115,7 +122,8 @@ character of the selector string. | `[a^=b]` | parsed ✅ (2-char operator) | | `[a=b].c` | parsed ✅ (trailing content) | -**Fix direction:** change `>=` to `>` (need `strlen - $updated_offset >= 3`). +**Fix (landed in `16d03e2c5f`):** change `>=` to `>` (need +`strlen - $updated_offset >= 3`). --- diff --git a/tools/css-selector-fuzz/NEXT-STEPS.md b/tools/css-selector-fuzz/NEXT-STEPS.md index 0081ce4d3a63a..51a68dc06a5cf 100644 --- a/tools/css-selector-fuzz/NEXT-STEPS.md +++ b/tools/css-selector-fuzz/NEXT-STEPS.md @@ -9,16 +9,29 @@ > 5000-seed run with all signatures triaged to the three known bugs, all of > which still reproduce. The notes below are retained as the design rationale. > +> **Core fixes landed:** the three FINDINGS.md bugs are fixed on this branch +> (`CSS selector:` commits `7419a9fef6` / `0cefeb2fc8` / `16d03e2c5f`), each +> with PHPUnit regression tests. A post-fix 5000-seed run is clean. +> > **Open follow-up hardening (post-review):** `tests/self-check.php` runs its -> parse-expectation assertions over a fixed seed window (1–400) that currently -> dodges the three known core bugs only by seed luck. Any generator change that -> shifts the PRNG stream can collide with Bug 1/3 there (it already does for the -> deferred document-side class-NUL injection — see README "Known oracle -> limitations"). Decouple self-check from the unfixed core bugs — e.g. apply the -> three FINDINGS.md fixes inside the self-check harness, or allowlist their +> parse-expectation assertions over a fixed seed window (1–400) that, against +> an *unfixed* core, dodges the known core bugs only by seed luck. On this +> branch the bugs are fixed so the collision risk is gone, but the hazard +> returns whenever the tooling runs against a core without the fixes (e.g. +> cherry-picked onto trunk before the fixes land) or when a future unfixed bug +> is found. Decouple self-check from unfixed core bugs — e.g. allowlist known > signatures in the parse-expectation loop — as a standalone hardening. This is > worth doing on its own (it makes self-check robust to *any* future generator > change) and is the prerequisite for randomized class-NUL document injection. +> +> **Candidate finding 4 (unverified, found in fix review):** per CSS Syntax 3 +> §4.3.8, `\` followed by EOF is a valid escape (EOF is not a newline), and +> §4.3.7 says consuming it returns U+FFFD — so `.foo\` should parse as class +> `foo\u{FFFD}`. WP's `next_two_are_valid_escape()` requires a code point after +> the backslash, so `.foo\` is rejected (`from_selectors()` → null). The +> string-context behavior (`'foo\` → `foo`, "do nothing" at EOF) is already +> spec-correct; only ident context diverges. Low severity (fail-safe null, not +> a mis-match); verify against browsers, then fix or document as intentional. Repo: `/Users/jonsurrell/a8c/wordpress-develop/html-css-fuzz`, branch `html-css-fuzz` @ `6ebbcc2fe4` (trunk + merged `html-api/add-css-selector-parser`). @@ -189,7 +202,8 @@ keep-failing) to a minimal reproducer. Wire into `replay.php` or a new ## Existing bugs to keep verifying (regression anchors) -From `FINDINGS.md` — minimal repros, all must still trigger until core is fixed: -1. Identity escape after multibyte mis-decodes: `#Ü,\sup #x` → type `uup` (want `sup`). -2. Empty-value matchers match everything: `[x^=""]`, `[x*=""]`, `[x$=""]`. -3. Off-by-one length guard: `[a=b]` (single-char unquoted value, exact `=`, at EOF) → `null`. +From `FINDINGS.md` — all three are fixed on this branch and pinned by PHPUnit +tests; the minimal repros must now NOT trigger (a clean 5000-seed run confirms): +1. Identity escape after multibyte mis-decodes: `#Ü,\sup #x` → type must be `sup`. +2. Empty-value substring matchers: `[x^=""]`, `[x*=""]`, `[x$=""]` must match nothing. +3. Off-by-one length guard: `[a=b]` (single-char unquoted value, exact `=`, at EOF) must parse. diff --git a/tools/css-selector-fuzz/README.md b/tools/css-selector-fuzz/README.md index 661e6dd575cba..3af425719c807 100644 --- a/tools/css-selector-fuzz/README.md +++ b/tools/css-selector-fuzz/README.md @@ -135,6 +135,12 @@ Known lexbor issues compensated for at this pin: findings. - `lxb_selectors_find` reports a node once per matching selector-list branch; `LXB_SELECTORS_OPT_MATCH_FIRST` dedupes. +- lexbor matches `[x~=""]` against whitespace-only attribute values + (e.g. `x=" "`); Selectors-4 and Chrome say an empty operand never + matches a list item, and WP agrees with them. Latent + `lexbor-divergence` noise source if the generator ever pairs `~=""` + with whitespace-valued attributes; candidate upstream report, not a + WP finding. ## Known oracle limitations (document-side decoding) From 68ef171dea1d9fae4b558345db6648cba7713259 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 18:46:50 +0200 Subject: [PATCH 173/634] CSS selector fuzz: draft upstream lexbor bug reports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three spec-conformance bugs in liblexbor v3.0.0, found via the differential oracle and re-verified directly against the harness: 1. [x~=""] matches whitespace-only attribute values (empty operand must never match, Selectors-4 §6.1). 2. Uppercase I/S attribute-selector modifiers are parse errors (Selectors-4 §6.3 defines them case-insensitively). 3. Non-ASCII ident code points below U+00F8 (U+00B7, U+00C0-U+00F6) are rejected; the table appears to start at U+00F8 (CSS Syntax 3 §4.2). Each comes with verified repro tables, control cases bracketing the boundary, spec citations, a self-contained C repro skeleton, and instructions for an agent to re-verify at lexbor master, dedupe against existing issues, and file upstream. lexbor #368 is already filed and excluded. --- .../lexbor/UPSTREAM-ISSUES.md | 141 ++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 tools/css-selector-fuzz/lexbor/UPSTREAM-ISSUES.md diff --git a/tools/css-selector-fuzz/lexbor/UPSTREAM-ISSUES.md b/tools/css-selector-fuzz/lexbor/UPSTREAM-ISSUES.md new file mode 100644 index 0000000000000..8ebf17484b095 --- /dev/null +++ b/tools/css-selector-fuzz/lexbor/UPSTREAM-ISSUES.md @@ -0,0 +1,141 @@ +# lexbor — draft upstream bug reports + +Three spec-conformance bugs in liblexbor's CSS selectors support, found while +using lexbor as a differential oracle for the WordPress HTML-API CSS selector +fuzzer (`tools/css-selector-fuzz/`). All three were re-verified directly +against the harness on 2026-06-10. + +- **Pinned version:** lexbor v3.0.0 (`2ae88a1c6b52`), built by + `tools/css-selector-fuzz/lexbor/build.sh`. +- **Upstream repo:** https://github.com/lexbor/lexbor +- **Already filed upstream — do NOT refile:** + [#368](https://github.com/lexbor/lexbor/issues/368) (class/`#id` selectors + match ASCII case-insensitively in no-quirks documents). + +## Instructions for the filing agent + +1. **Re-verify at lexbor master first.** The pin is v3.0.0; any of these may + already be fixed. Edit `build.sh` to build master (or clone/build manually) + and re-run the repros below. Only file what still reproduces, and say in + the report which commit you tested. +2. **Search for duplicates** before filing (suggested queries: `~=`, + `attr-modifier`, `case insensitive modifier`, `ident code point`, + `U+00B7`, `non-ascii`). #368 shows the maintainer's preferred repro style. +3. **One issue per bug.** Reduce each to a self-contained C repro (sketch + below); maintainers should not need this repo's harness. +4. Reproduction via this repo (fast path): build the harness + (`sh tools/css-selector-fuzz/lexbor/build.sh`), then feed it + `base64(html) TAB base64(selector)` lines on stdin. Response lines per + case: `Rtagfidancestors` (tree rows), `Mfid` (match), + `Xreason` (selector parse error), terminated by `D`. See + `lib/LexborOracle.php` for a reference client and `harness.c` for the + exact lexbor API usage (`lxb_html_document_parse`, + `lxb_css_selectors_parse`, `lxb_selectors_find`). + +Minimal C repro skeleton (adapt per issue; `harness.c` is the full reference): + +```c +/* cc repro.c -llexbor */ +#include +#include +#include + +static lxb_status_t cb(lxb_dom_node_t *n, lxb_css_selector_specificity_t s, void *ctx) { + (*(int *)ctx)++; + return LXB_STATUS_OK; +} + +int main(void) { + const lxb_char_t html[] = ""; + const lxb_char_t sel[] = "[x~=\"\"]"; + int hits = 0; + + lxb_html_document_t *doc = lxb_html_document_create(); + lxb_html_document_parse(doc, html, sizeof(html) - 1); + + lxb_css_parser_t *parser = lxb_css_parser_create(); + lxb_css_parser_init(parser, NULL); + lxb_selectors_t *selectors = lxb_selectors_create(); + lxb_selectors_init(selectors); + + lxb_css_selector_list_t *list = + lxb_css_selectors_parse(parser, sel, sizeof(sel) - 1); + if (list == NULL) { printf("selector parse error\n"); return 1; } + + lxb_selectors_find(selectors, lxb_dom_interface_node(doc), + list, cb, &hits); + printf("matches: %d\n", hits); /* spec: 0 */ + return 0; +} +``` + +--- + +## Issue 1 — `[x~=""]` matches whitespace-only attribute values + +Per Selectors Level 4, `[att~=val]` with an empty `val` never matches: + +> If "val" is the empty string, it will never represent anything. +> — https://www.w3.org/TR/selectors-4/#attribute-representation (§6.1) + +lexbor instead matches elements whose attribute value consists only of +whitespace, suggesting its list-splitting yields an empty token for +whitespace-only values. Verified at v3.0.0 (`data-fid="a"` on the element): + +| document | selector | lexbor | spec / Chrome 149 | +|---------------------------|-----------|-----------|-------------------| +| `` (space) | `[x~=""]` | matches ❌ | no match | +| `` (tab) | `[x~=""]` | matches ❌ | no match | +| `` | `[x~=""]` | no match ✅ | no match | +| `` | `[x~=""]` | no match ✅ | no match | +| `` (control) | `[x~=a]` | matches ✅ | matches | + +Chrome 149 (`document.querySelectorAll`) returns no match for all `[x~=""]` +rows (verified 2026-06-10 via Playwright during the WordPress fix review). + +## Issue 2 — uppercase `I`/`S` attribute-selector modifiers rejected + +Selectors Level 4 §6.3 defines the modifiers explicitly as case-insensitive: + +> ...adding the identifier `i` (or `I`) ... adding the identifier `s` (or `S`) ... +> — https://www.w3.org/TR/selectors-4/#attribute-case + +lexbor parses the lowercase forms but reports a selector parse error for the +uppercase forms. Verified at v3.0.0: + +| selector | lexbor | spec | +|--------------|---------------|---------| +| `[x=abc i]` | parses ✅ | parses | +| `[x=abc I]` | parse error ❌ | parses | +| `[x=abc s]` | parses ✅ | parses | +| `[x=abc S]` | parse error ❌ | parses | + +Note for browser comparison: Chrome 149 had not shipped the `s` modifier at +all (throws SyntaxError), so compare `I` against Chrome and `S` against the +spec text / Firefox. + +## Issue 3 — non-ASCII ident code points below U+00F8 rejected + +CSS Syntax Level 3 defines the non-ASCII ident code points to include +U+00B7 and U+00C0–U+00D6 / U+00D8–U+00F6: + +> non-ASCII ident code point: U+00B7, U+00C0 to U+00D6, U+00D8 to U+00F6, +> U+00F8 to U+037D, ... +> — https://www.w3.org/TR/css-syntax-3/#non-ascii-ident-code-point + +lexbor's table appears to start at U+00F8: code points in the earlier ranges +are rejected both in ident-start and non-start positions. Verified at v3.0.0 +(raw UTF-8 selectors; class attribute contains the same characters): + +| selector | codepoint(s) | lexbor | spec | +|-----------|---------------------|---------------|---------| +| `.über` | U+00FC (≥ U+00F8) | parses ✅ | parses | +| `.øx` | U+00F8 (boundary) | parses ✅ | parses | +| `.Über` | U+00DC (U+00D8–F6) | parse error ❌ | parses | +| `.a·b` | U+00B7 (non-start) | parse error ❌ | parses | +| `.÷x` | U+00F7 (excluded) | parse error ✅ | error | + +The U+00F7 row is a control: the division sign is correctly NOT an ident code +point, so lexbor's boundary is off by exactly the U+00B7 / U+00C0–U+00F6 +ranges. Workaround used by this fuzzer: hex-escape all non-ASCII (`\dc ber` +parses fine), which is why this surfaces only with raw multibyte selectors. From 28df783d2107ad6f70ab303485f65d4d96d1e771 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 22:38:50 +0200 Subject: [PATCH 174/634] CSS selector fuzz: cover backslash-at-EOF escapes; record decisions Track the core EOF-escape fix (candidate finding 4, now confirmed against lexbor and fixed): - The invalid bucket's lone '\' entry is now a valid selector (type U+FFFD); replace it with "\\n" (backslash before a newline is not a valid escape and stays invalid). - New 'eof-escape' kind in the edge-escape bucket generates '.name\', '#name\', and 'name\' (including empty-name variants) with expected ASTs ending in U+FFFD, exercising both the EOF escape decode and the normalize-input trailing-whitespace handling. NEXT-STEPS.md: mark candidate finding 4 fixed (including the trailing-trim wrong-match-set bug its review surfaced) and record the session decisions: EOF-truncated attribute selectors will be made spec-conformant (auto-close), the HTML case-insensitive attribute value list will be implemented, grammar-level truncations stay invalid, no Trac tickets. Self-check OK; 5000-seed runs clean at seeds 1-5000 and 7000000+ (reviewer-chosen fresh range) with lexbor comparisons active. --- tools/css-selector-fuzz/NEXT-STEPS.md | 31 +++++++--- .../lib/SelectorGenerator.php | 59 +++++++++++++++++-- 2 files changed, 78 insertions(+), 12 deletions(-) diff --git a/tools/css-selector-fuzz/NEXT-STEPS.md b/tools/css-selector-fuzz/NEXT-STEPS.md index 51a68dc06a5cf..af2ba87eca8cd 100644 --- a/tools/css-selector-fuzz/NEXT-STEPS.md +++ b/tools/css-selector-fuzz/NEXT-STEPS.md @@ -24,14 +24,29 @@ > worth doing on its own (it makes self-check robust to *any* future generator > change) and is the prerequisite for randomized class-NUL document injection. > -> **Candidate finding 4 (unverified, found in fix review):** per CSS Syntax 3 -> §4.3.8, `\` followed by EOF is a valid escape (EOF is not a newline), and -> §4.3.7 says consuming it returns U+FFFD — so `.foo\` should parse as class -> `foo\u{FFFD}`. WP's `next_two_are_valid_escape()` requires a code point after -> the backslash, so `.foo\` is rejected (`from_selectors()` → null). The -> string-context behavior (`'foo\` → `foo`, "do nothing" at EOF) is already -> spec-correct; only ident context diverges. Low severity (fail-safe null, not -> a mis-match); verify against browsers, then fix or document as intentional. +> **Candidate finding 4 — FIXED:** per CSS Syntax 3 §4.3.8, `\` followed by +> EOF is a valid escape (EOF is not a newline), and §4.3.7 says consuming it +> returns U+FFFD — so `.foo\` parses as class `foo\u{FFFD}`. Verified against +> lexbor (agrees: `.foo\` matches class `foo\u{FFFD}`; `\` parses as type +> `\u{FFFD}`). Fixed on this branch (`CSS selector:` commit): EOF guard in +> `consume_escaped_codepoint()` returns U+FFFD, `next_two_are_valid_escape()` +> accepts a backslash as the final byte. Review of the fix surfaced a second +> bug in the same family: `normalize_selector_input()` trimmed *trailing* +> whitespace before tokenizing, so `.foo\ ` (escaped space — valid class +> `foo `, matches nothing) and `.foo\` (invalid escape — must be +> rejected) both collapsed to `.foo\` and matched class `foo\u{FFFD}` — a +> wrong-match-set bug. Fixed by switching to `ltrim()`; the grammar consumes +> insignificant trailing whitespace. Fuzzer updated to match: the lone `\` +> invalid-bucket entry became `\` (still invalid), and `edge-escape` +> gained an `eof-escape` kind covering `.name\` / `#name\` / `name\`. +> +> **Session decisions (2026-06-10):** EOF-truncated selectors (`div[a=b`) +> will be made spec-conformant — CSS Syntax auto-closes open blocks at EOF — +> rather than documented as an intentional rejection. HTML's default +> case-insensitive attribute value list will be implemented (no-modifier + +> html-namespace + listed attribute; explicit `s` keeps forcing +> case-sensitivity). Grammar-level truncations (`[`, `[a=`, `div >`, `div,`) +> stay invalid — browsers reject those too. No Trac tickets for any of this. Repo: `/Users/jonsurrell/a8c/wordpress-develop/html-css-fuzz`, branch `html-css-fuzz` @ `6ebbcc2fe4` (trunk + merged `html-api/add-css-selector-parser`). diff --git a/tools/css-selector-fuzz/lib/SelectorGenerator.php b/tools/css-selector-fuzz/lib/SelectorGenerator.php index 88a2cbaefd9a9..54aa761781c5b 100644 --- a/tools/css-selector-fuzz/lib/SelectorGenerator.php +++ b/tools/css-selector-fuzz/lib/SelectorGenerator.php @@ -545,12 +545,61 @@ private function pick_name( string $pool_key ): string { private function gen_edge_escape(): array { $kind = $this->prng->weighted( array( - 'fffd-ident' => 50, - 'nul-input' => 25, - 'ws-input' => 25, + 'fffd-ident' => 40, + 'eof-escape' => 20, + 'nul-input' => 20, + 'ws-input' => 20, ) ); + if ( 'eof-escape' === $kind ) { + /* + * A backslash at the end of input is a valid escape ( EOF is not + * a newline ) and decodes to U+FFFD, in ident context only: + * `.foo\` is the class `foo\u{FFFD}`. + * + * https://www.w3.org/TR/css-syntax-3/#consume-escaped-code-point + */ + $name = $this->prng->chance( 30 ) ? '' : 'a' . $this->prng->int( 0, 99 ); + list( $selector, $self ) = $this->prng->choice( + array( + array( + '.' . $name . '\\', + array( + 'type' => null, + 'subs' => array( array( 'kind' => 'class', 'name' => $name . "\u{FFFD}" ) ), + ), + ), + array( + '#' . $name . '\\', + array( + 'type' => null, + 'subs' => array( array( 'kind' => 'id', 'name' => $name . "\u{FFFD}" ) ), + ), + ), + array( + $name . '\\', + array( + 'type' => $name . "\u{FFFD}", + 'subs' => null, + ), + ), + ) + ); + return array( + 'bucket' => 'edge-escape', + 'selector' => $selector, + 'expectCompound' => true, + 'expectComplex' => true, + 'ast' => array( + array( + 'context' => array(), + 'self' => $self, + ), + ), + ); + } + if ( 'fffd-ident' === $kind ) { // A class selector whose name is a single U+FFFD, produced by a // hex escape for an out-of-range codepoint. @@ -1307,7 +1356,9 @@ private function gen_invalid(): string { 'a >> b', '>', '-', - '\\', + // A lone '\' is a valid escape at EOF ( type selector U+FFFD ); + // '\' before a newline is not a valid escape. + "\\\n", "a\\\nb", 'a/**/b', '/* comment */ a', From c6916ce008756ab273c5738912d1dda6c094dad4 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 23:02:33 +0200 Subject: [PATCH 175/634] CSS selector fuzz: cover EOF-truncated attribute selectors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Track the core EOF auto-close change: - New 'eof-truncated' kind in the edge-escape bucket: render an attribute compound, strip the trailing ']', sometimes also drop a closing string quote (EOF terminates the string, then the block) and sometimes append a trailing backslash to the unterminated string (the 'do nothing' escape arm, keeping that branch exercised after the '[a="x\' invalid template became valid). - Invalid bucket reshuffled along the new validity boundary: entries that EOF auto-close makes valid ('[a', '[ a', '[a=b', '[a="x\', '[a="b]', "[a='b]", '[a=b i') are replaced with still-invalid grammar-level truncations ('[a=', '[a= ', '[a~', '[a^', '[a=b x', '[a=b ix', '[a=b i x', '[5=b', '[a="bc'). COVERAGE.md regenerated: 384/408 lines (94.1%), effective 396/408 (97.1%). The parse_string() and ident-start EOF guards flipped from 'defensive, unreachable' to genuinely covered ('[a=' now reaches the value parsers at EOF); next_two_are_valid_escape()'s EOF guard is the remaining defensive line. NEXT-STEPS.md: record candidate finding 5 (escaped attribute-selector modifier idents like '[a=b \69]' are rejected by the byte-wise modifier switch; Chromium itself is inconsistent — accepts \69/i, rejects \73/s; fail-safe refusal, not fixed). Review panel: two approvals; 20k-case generator oracle loop and a fresh 9M-seed-range fuzz run by reviewers found no oracle mismatches. Gates: self-check OK, full suite 1631 green, 5000-seed run clean. --- tools/css-selector-fuzz/COVERAGE.md | 46 ++++++---- tools/css-selector-fuzz/NEXT-STEPS.md | 9 ++ .../lib/SelectorGenerator.php | 84 ++++++++++++++++--- 3 files changed, 111 insertions(+), 28 deletions(-) diff --git a/tools/css-selector-fuzz/COVERAGE.md b/tools/css-selector-fuzz/COVERAGE.md index 5c772ce27793c..5279d0363201e 100644 --- a/tools/css-selector-fuzz/COVERAGE.md +++ b/tools/css-selector-fuzz/COVERAGE.md @@ -7,21 +7,25 @@ with phpdbg's opcode log over 3000 deterministic seeds: | file | covered / executable | % | |---|---|---| -| class-wp-css-attribute-selector.php | 102 / 112 | 91.1% | +| class-wp-css-attribute-selector.php | 106 / 116 | 91.4% | | class-wp-css-class-selector.php | 10 / 10 | 100% | | class-wp-css-complex-selector-list.php | 16 / 16 | 100% | | class-wp-css-complex-selector.php | 59 / 66 | 89.4% | | class-wp-css-compound-selector-list.php | 27 / 28 | 96.4% | | class-wp-css-compound-selector.php | 29 / 32 | 90.6% | | class-wp-css-id-selector.php | 12 / 12 | 100% | -| class-wp-css-selector-parser-matcher.php | 106 / 108 | 98.1% | +| class-wp-css-selector-parser-matcher.php | 110 / 111 | 99.1% | | class-wp-css-type-selector.php | 15 / 17 | 88.2% | -| **TOTAL** | **376 / 401** | **93.8%** | +| **TOTAL** | **384 / 408** | **94.1%** | -The 25 unreached lines are all accounted for below. Twelve are a phpdbg -measurement artifact (the code executes); the other thirteen are defensive +The 24 unreached lines are all accounted for below. Twelve are a phpdbg +measurement artifact (the code executes); the other twelve are defensive guards that the public entry points cannot reach. Effective coverage of -reachable code is **388 / 401 = 96.8%**. +reachable code is **396 / 408 = 97.1%**. + +(Executable-line totals grew from 401 to 408 with the EOF-escape and +EOF-auto-close changes; two parser-matcher EOF guards that used to be +unreachable defensive lines are now genuinely exercised — see below.) ## phpdbg `case`-label artifact (12 lines — code executes) @@ -32,17 +36,17 @@ lexbor differential + self-check confirm the corresponding behavior). These are not real gaps: - `class-wp-css-attribute-selector.php` - - 287, 291, 295, 299, 303 — the `~= |= ^= $= *=` matcher operators. - - 330, 331, 336, 337 — the `i`/`I`/`s`/`S` case modifiers. + - 309, 313, 317, 321, 325 — the `~= |= ^= $= *=` matcher operators. + - 350, 351, 356, 357 — the `i`/`I`/`s`/`S` case modifiers. - `class-wp-css-compound-selector.php` - 120, 122, 124 — the `.` / `#` / `[` subclass-selector dispatch. -## Defensive guards unreachable from the public API (13 lines) +## Defensive guards unreachable from the public API (12 lines) These are internal precondition checks that the calling code already guarantees, or branches for grammar the parser never emits: -- `class-wp-css-attribute-selector.php:257` — `return null` when the first +- `class-wp-css-attribute-selector.php:282` — `return null` when the first byte is not `[`. `parse()` is only ever called by `parse_subclass_selector()` *after* it has matched `[`, so the guard never fires. @@ -54,23 +58,31 @@ guarantees, or branches for grammar the parser never emits: processor is not on a `#tag` token. `select()` only invokes matching while positioned on a tag; reachable only by calling `matches()` directly off a non-tag token. -- `class-wp-css-selector-parser-matcher.php:130` — `parse_string()` EOF - guard; every caller checks bounds and the opening quote before calling. -- `class-wp-css-selector-parser-matcher.php:429` — - `check_if_three_code_points_would_start_an_ident_sequence()` EOF guard; - callers bound-check first. +- `class-wp-css-selector-parser-matcher.php:351` — + `next_two_are_valid_escape()` EOF guard; every caller either bound-checks + first or only calls it on a known backslash byte. - `class-wp-css-type-selector.php:45` — `return false` when `get_tag()` is null during matching; matching only runs on resolved element tokens. - `class-wp-css-type-selector.php:75` — `parse()` EOF guard; the compound parser checks `offset < strlen` before calling. +Two guards documented here in earlier revisions are now genuinely covered: +the `parse_string()` EOF guard and the +`check_if_three_code_points_would_start_an_ident_sequence()` EOF guard are +both reached since EOF auto-close lets `[a=` call the value parsers at the +end of input. + ## Notes on what raised coverage - The `edge-escape` bucket drives the U+FFFD escape-decoder branch (`consume_escaped_codepoint` for NUL / surrogate / over-max codepoints) and the `normalize_selector_input` NUL→U+FFFD and CR/CRLF/FF→LF paths, - which the structural generators cannot reach. -- A few `invalid`-bucket templates (`[ a`, `[a="x\`, `a.`) were added to reach + which the structural generators cannot reach. Its `eof-escape` kind covers + the backslash-at-end-of-input → U+FFFD decode, and its `eof-truncated` + kind covers the EOF auto-close paths in the attribute parser, including + unterminated strings (with and without a trailing "do nothing" backslash, + which keeps the `parse_string` backslash-at-EOF arm exercised). +- A few `invalid`-bucket templates (`[a=`, `[a~`, `[a="bc`, `a.`) reach attribute / string / class parse guards that random structural generation rarely lands on. With them the per-file numbers above are **deterministic** at the documented 3000-seed window (e.g. `class-wp-css-class-selector.php` diff --git a/tools/css-selector-fuzz/NEXT-STEPS.md b/tools/css-selector-fuzz/NEXT-STEPS.md index af2ba87eca8cd..4bcf41dc07c78 100644 --- a/tools/css-selector-fuzz/NEXT-STEPS.md +++ b/tools/css-selector-fuzz/NEXT-STEPS.md @@ -40,6 +40,15 @@ > invalid-bucket entry became `\` (still invalid), and `edge-escape` > gained an `eof-escape` kind covering `.name\` / `#name\` / `name\`. > +> **Candidate finding 5 (recorded 2026-06-10, low severity, not fixed):** +> the attribute-selector case modifier is matched byte-wise (`i`/`I`/`s`/`S` +> literals), so an *escaped* modifier ident like `[a=b \69]` (tokenizes to +> the ident `i`) is rejected. Per the Selectors-4 grammar ` = +> i | s` these are ident tokens, so escapes should arguably be accepted — +> but browsers are themselves inconsistent (Chromium accepts `[a=b \69]` +> and rejects `[a=b \73]`). Fail-safe refusal, not a mis-match; revisit only +> if the matcher ever moves to token-level parsing. +> > **Session decisions (2026-06-10):** EOF-truncated selectors (`div[a=b`) > will be made spec-conformant — CSS Syntax auto-closes open blocks at EOF — > rather than documented as an intentional rejection. HTML's default diff --git a/tools/css-selector-fuzz/lib/SelectorGenerator.php b/tools/css-selector-fuzz/lib/SelectorGenerator.php index 54aa761781c5b..82fe2b5745b0b 100644 --- a/tools/css-selector-fuzz/lib/SelectorGenerator.php +++ b/tools/css-selector-fuzz/lib/SelectorGenerator.php @@ -545,13 +545,69 @@ private function pick_name( string $pool_key ): string { private function gen_edge_escape(): array { $kind = $this->prng->weighted( array( - 'fffd-ident' => 40, - 'eof-escape' => 20, - 'nul-input' => 20, - 'ws-input' => 20, + 'fffd-ident' => 35, + 'eof-escape' => 20, + 'eof-truncated' => 15, + 'nul-input' => 15, + 'ws-input' => 15, ) ); + if ( 'eof-truncated' === $kind ) { + /* + * The end of input auto-closes an unterminated attribute selector + * block ( and an unterminated string inside it ): `[a=b` is the + * same selector as `[a=b]`. + * + * https://www.w3.org/TR/css-syntax-3/#consume-simple-block + */ + $matcher = $this->prng->choice( array( null, 'exact', 'one-of', 'exact-or-hyphen-suffixed', 'prefixed', 'suffixed', 'contains' ) ); + $value = null === $matcher ? null : $this->prng->choice( array( 'v' . $this->prng->int( 0, 99 ), 'a b', '', 'x,y', "caf\u{E9}" ) ); + $modifier = null !== $matcher && $this->prng->chance( 30 ) + ? $this->prng->choice( array( 'case-insensitive', 'case-sensitive' ) ) + : null; + $compound = array( + 'type' => $this->prng->chance( 50 ) ? 'div' : null, + 'subs' => array( + array( + 'kind' => 'attr', + 'name' => 'a' . $this->prng->int( 0, 99 ), + 'matcher' => $matcher, + 'value' => $value, + 'modifier' => $modifier, + ), + ), + ); + + // The attribute selector is the final rendered unit, so the render always ends with ']'. + $rendered = $this->render_compound( $compound ); + $truncated = substr( $rendered, 0, -1 ); + + // Sometimes also drop a closing string quote: EOF terminates the string, then closes the block. + $last_byte = substr( $truncated, -1 ); + if ( ( '"' === $last_byte || "'" === $last_byte ) && $this->prng->chance( 50 ) ) { + $truncated = substr( $truncated, 0, -1 ); + + // A backslash at the end of an unterminated string "does nothing": the value is unchanged. + if ( $this->prng->chance( 40 ) ) { + $truncated .= '\\'; + } + } + + return array( + 'bucket' => 'edge-escape', + 'selector' => $truncated, + 'expectCompound' => true, + 'expectComplex' => true, + 'ast' => array( + array( + 'context' => array(), + 'self' => $compound, + ), + ), + ); + } + if ( 'eof-escape' === $kind ) { /* * A backslash at the end of input is a valid escape ( EOF is not @@ -1333,23 +1389,29 @@ private function gen_invalid(): string { '. x', '..a', '.#a', - '[a', - '[ a', + /* + * EOF auto-closes an open attribute selector block + * ( '[a', '[a=b', '[a="b]', '[a=b i' are valid ), but + * grammar-level truncation is still invalid. + */ '[a=', + '[a= ', + '[a~', + '[a^', '[a=]', - '[a="x\\', '[=b]', '[a==b]', '[a~b]', '[a!=b]', - '[a=b', - '[a="b]', - "[a='b]", "[a=\"b\nc\"]", + "[a=\"b\nc", '[a=b x]', + '[a=b x', '[a=b ix]', - '[a=b i', + '[a=b ix', + '[a=b i x', '[5=b]', + '[5=b', 'a >', '> a', 'a > > b', From a2c21ae9cc746778672afca89ff8aee3aec7a6d7 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 10 Jun 2026 23:54:44 +0200 Subject: [PATCH 176/634] CSS selector fuzz: mirror the HTML case-insensitive attribute list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Track the core change in the oracle stack: - ReferenceMatcher: independent copy of the 46-name list (the oracle must not share a possible misreading with the implementation under test); attr matching folds when no modifier + html-namespace row + listed name. A new $html_attr_ci flag threads through the matching entry points so the lexbor comparison can model an engine without the rule. - TreeCapture: html-processor rows now carry the element's namespace (svg/math subtrees and foreignObject integration points get correct per-element folding; rows without the field default to html, which matches both the model generator's html-only output and the namespace-blind standalone Tag Processor). - Worker: lexbor does not implement the rule ([rel=NOFOLLOW] fails to match rel="nofollow"); its expectation is now always recomputed with the list disabled, composed with the existing issue-368 quirks fold. Candidate upstream report recorded in NEXT-STEPS.md. - SelectorGenerator: case-flip twists in gen_attr_selector and, more importantly, path_attr_feature — the path-directed bucket pairs attribute name and value from the same real element, so a flipped operand makes the folding rule load-bearing for the mustMatchFid invariant. Mutation-tested: with the core folding branch disabled, a 3000-seed run fires 11 match-mismatch failures (review found the earlier pool-based flip alone was load-bearing in ~1/14k cases). - util: ascii_strtoupper and str_shuffle_case (ASCII-only, multibyte bytes pass through untouched). Review panel: two approvals (spec reviewer machine-diffed both list constants against the live spec; oracle reviewer verified row namespaces against match-time get_namespace() including integration points, the lexbor compensation composition, and util determinism). Gates: self-check OK, suite 1640 green, 5000-seed run clean, fresh 11M-seed-range reviewer run clean. --- tools/css-selector-fuzz/NEXT-STEPS.md | 18 ++++ .../lib/ReferenceMatcher.php | 97 ++++++++++++++++--- .../lib/SelectorGenerator.php | 38 +++++++- tools/css-selector-fuzz/lib/TreeCapture.php | 1 + tools/css-selector-fuzz/lib/Worker.php | 25 +++-- tools/css-selector-fuzz/lib/util.php | 17 ++++ 6 files changed, 170 insertions(+), 26 deletions(-) diff --git a/tools/css-selector-fuzz/NEXT-STEPS.md b/tools/css-selector-fuzz/NEXT-STEPS.md index 4bcf41dc07c78..7cd82c01cce89 100644 --- a/tools/css-selector-fuzz/NEXT-STEPS.md +++ b/tools/css-selector-fuzz/NEXT-STEPS.md @@ -49,6 +49,24 @@ > and rejects `[a=b \73]`). Fail-safe refusal, not a mis-match; revisit only > if the matcher ever moves to token-level parsing. > +> **HTML case-insensitive attribute value list — IMPLEMENTED (2026-06-10):** +> per https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors +> the values of ~46 listed attributes (`type`, `rel`, `lang`, `dir`, +> `media`, ...) match ASCII case-insensitively on HTML elements when the +> selector has no modifier; an explicit `s` still forces sensitivity, and +> elements outside the html namespace are unaffected. Oracle notes from +> verification: +> - **lexbor does not implement the rule at all** (`[rel=nofollow]` does +> not match `rel="NOFOLLOW"`) — compensated in the differential the same +> way as lexbor #368 (lexbor is compared against the reference run with +> the list disabled); candidate upstream report. +> - **Chromium applies the list to foreign elements too** (`[type=TEXT]` +> matches ``), diverging from the HTML spec's "on an +> HTML element" scoping. WP follows the spec (html namespace only, via +> `get_namespace()`). The standalone Tag Processor has no namespace +> tracking and applies the list to every element — an inherent +> tag-processor approximation, same as its ancestor-blind matching. +> > **Session decisions (2026-06-10):** EOF-truncated selectors (`div[a=b`) > will be made spec-conformant — CSS Syntax auto-closes open blocks at EOF — > rather than documented as an intentional rejection. HTML's default diff --git a/tools/css-selector-fuzz/lib/ReferenceMatcher.php b/tools/css-selector-fuzz/lib/ReferenceMatcher.php index 5acbf9f5d4927..e86aa4e2e990b 100644 --- a/tools/css-selector-fuzz/lib/ReferenceMatcher.php +++ b/tools/css-selector-fuzz/lib/ReferenceMatcher.php @@ -18,7 +18,9 @@ * - Class and ID matching is exact, except in quirks mode where it is * ASCII case-insensitive. * - Attribute value matching is exact (byte-wise) unless the `i` modifier - * requests ASCII case-insensitivity. + * requests ASCII case-insensitivity, or the attribute is in HTML's + * case-insensitive list, the selector has no modifier, and the element + * is in the html namespace (rows without a namespace field are html). * - For `^=`, `$=`, `*=` and `~=`, an empty (or for `~=`, whitespace- * containing) value matches nothing. * @@ -28,18 +30,78 @@ class ReferenceMatcher { const WHITESPACE = " \t\r\n\f"; + /** + * HTML's case-insensitive attribute value list: with no `i`/`s` + * modifier, these attributes' values match ASCII case-insensitively on + * HTML elements. Independent copy — the matcher must not share a + * possible misreading with the implementation under test. + * + * https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors + */ + const HTML_CASE_INSENSITIVE_ATTRIBUTES = array( + 'accept' => true, + 'accept-charset' => true, + 'align' => true, + 'alink' => true, + 'axis' => true, + 'bgcolor' => true, + 'charset' => true, + 'checked' => true, + 'clear' => true, + 'codetype' => true, + 'color' => true, + 'compact' => true, + 'declare' => true, + 'defer' => true, + 'dir' => true, + 'direction' => true, + 'disabled' => true, + 'enctype' => true, + 'face' => true, + 'frame' => true, + 'hreflang' => true, + 'http-equiv' => true, + 'lang' => true, + 'language' => true, + 'link' => true, + 'media' => true, + 'method' => true, + 'multiple' => true, + 'nohref' => true, + 'noresize' => true, + 'noshade' => true, + 'nowrap' => true, + 'readonly' => true, + 'rel' => true, + 'rev' => true, + 'rules' => true, + 'scope' => true, + 'scrolling' => true, + 'selected' => true, + 'shape' => true, + 'target' => true, + 'text' => true, + 'type' => true, + 'valign' => true, + 'valuetype' => true, + 'vlink' => true, + ); + /** * Expected match list for WP_HTML_Processor::select(). * - * @param array $list_ast Canonical complex selector list AST. - * @param array $rows Element rows in visit order, with ancestorTags. - * @param bool $quirks Whether the document parses in quirks mode. + * @param array $list_ast Canonical complex selector list AST. + * @param array $rows Element rows in visit order, with ancestorTags. + * @param bool $quirks Whether the document parses in quirks mode. + * @param bool $html_attr_ci Whether HTML's case-insensitive attribute value + * list applies. True models WP/browsers; false + * models an engine without the rule ( lexbor ). * @return string[] data-fid values in visit order. */ - public static function expected_html_matches_rows( array $list_ast, array $rows, bool $quirks ): array { + public static function expected_html_matches_rows( array $list_ast, array $rows, bool $quirks, bool $html_attr_ci = true ): array { $out = array(); foreach ( $rows as $row ) { - if ( self::list_matches_row( $list_ast, $row, $quirks ) ) { + if ( self::list_matches_row( $list_ast, $row, $quirks, $html_attr_ci ) ) { $out[] = $row['fid']; } } @@ -60,7 +122,7 @@ public static function expected_tag_matches_rows( array $list_ast, array $rows ) foreach ( $rows as $row ) { $matched = false; foreach ( $list_ast as $complex ) { - if ( self::compound_matches( $complex['self'], $row, false ) ) { + if ( self::compound_matches( $complex['self'], $row, false, true ) ) { $matched = true; break; } @@ -82,10 +144,10 @@ public static function expected_tag_processor_matches( array $list_ast, array $m return self::expected_tag_matches_rows( $list_ast, DocumentGenerator::rows_from_model( $model ) ); } - public static function list_matches_row( array $list_ast, array $row, bool $quirks ): bool { + public static function list_matches_row( array $list_ast, array $row, bool $quirks, bool $html_attr_ci = true ): bool { foreach ( $list_ast as $complex ) { if ( - self::compound_matches( $complex['self'], $row, $quirks ) && + self::compound_matches( $complex['self'], $row, $quirks, $html_attr_ci ) && self::explore_context( $complex['context'], $row['ancestorTags'] ) ) { return true; @@ -127,12 +189,12 @@ private static function explore_context( array $context, array $ancestor_tags ): return false; } - public static function compound_matches( array $compound, array $row, bool $quirks ): bool { + public static function compound_matches( array $compound, array $row, bool $quirks, bool $html_attr_ci = true ): bool { if ( null !== $compound['type'] && ! self::type_matches( $compound['type'], $row['tag'] ) ) { return false; } foreach ( (array) $compound['subs'] as $sub ) { - if ( ! self::sub_matches( $sub, $row, $quirks ) ) { + if ( ! self::sub_matches( $sub, $row, $quirks, $html_attr_ci ) ) { return false; } } @@ -143,14 +205,14 @@ private static function type_matches( string $type, string $tag ): bool { return '*' === $type || ascii_strtolower( $type ) === ascii_strtolower( $tag ); } - private static function sub_matches( array $sub, array $row, bool $quirks ): bool { + private static function sub_matches( array $sub, array $row, bool $quirks, bool $html_attr_ci ): bool { switch ( $sub['kind'] ) { case 'class': return self::class_matches( $sub['name'], $row, $quirks ); case 'id': return self::id_matches( $sub['name'], $row, $quirks ); case 'attr': - return self::attr_matches( $sub, $row ); + return self::attr_matches( $sub, $row, $html_attr_ci ); } return false; } @@ -201,7 +263,7 @@ private static function id_matches( string $wanted, array $row, bool $quirks ): : $id === $wanted; } - private static function attr_matches( array $sub, array $row ): bool { + private static function attr_matches( array $sub, array $row, bool $html_attr_ci ): bool { $attr_value = DocumentGenerator::get_attribute_value( $row, $sub['name'] ); if ( null === $attr_value ) { return false; @@ -214,7 +276,12 @@ private static function attr_matches( array $sub, array $row ): bool { } $wanted = (string) $sub['value']; - $case_insensitive = 'case-insensitive' === $sub['modifier']; + $case_insensitive = 'case-insensitive' === $sub['modifier'] || ( + $html_attr_ci && + null === $sub['modifier'] && + 'html' === ( $row['namespace'] ?? 'html' ) && + isset( self::HTML_CASE_INSENSITIVE_ATTRIBUTES[ ascii_strtolower( $sub['name'] ) ] ) + ); if ( $case_insensitive ) { $attr_value = ascii_strtolower( $attr_value ); $wanted = ascii_strtolower( $wanted ); diff --git a/tools/css-selector-fuzz/lib/SelectorGenerator.php b/tools/css-selector-fuzz/lib/SelectorGenerator.php index 82fe2b5745b0b..1f3a8fa2e89c2 100644 --- a/tools/css-selector-fuzz/lib/SelectorGenerator.php +++ b/tools/css-selector-fuzz/lib/SelectorGenerator.php @@ -423,11 +423,29 @@ private function gen_attr_selector(): array { ) ); + $value = $this->gen_attr_value(); + + /* + * HTML's case-insensitive attribute value list: with no modifier, + * the values of listed attributes ( type, rel, lang, dir, ... ) + * match ASCII case-insensitively on HTML elements. Sometimes flip + * the case of the selector value for a listed attribute so the + * differential exercises that rule rather than relying on sampled + * values happening to differ in case. + */ + if ( + '' === $modifier && + isset( ReferenceMatcher::HTML_CASE_INSENSITIVE_ATTRIBUTES[ ascii_strtolower( $name ) ] ) && + $this->prng->chance( 40 ) + ) { + $value = $this->prng->chance( 50 ) ? ascii_strtoupper( $value ) : str_shuffle_case( $value, $this->prng ); + } + return array( 'kind' => 'attr', 'name' => $name, 'matcher' => $matcher, - 'value' => $this->gen_attr_value(), + 'value' => $value, 'modifier' => '' === $modifier ? null : $modifier, ); } @@ -838,7 +856,7 @@ private function path_compound_for( array $element ): array { continue; } $seen_attrs[ $lower ] = true; - $features[] = $this->path_attr_feature( $lower, $attr[1] ); + $features[] = $this->path_attr_feature( $lower, $attr[1], 'html' === ( $element['namespace'] ?? 'html' ) ); } $subs = array(); @@ -864,7 +882,7 @@ private function path_compound_for( array $element ): array { } /** An attribute selector that the (name, value) pair satisfies. */ - private function path_attr_feature( string $name, $value ): array { + private function path_attr_feature( string $name, $value, bool $is_html_namespace = true ): array { $presence = array( 'kind' => 'attr', 'name' => $this->prng->chance( 15 ) ? $this->random_case( $name ) : $name, @@ -933,6 +951,20 @@ private function path_attr_feature( string $name, $value ): array { } else { $modifier = 'case-sensitive'; } + } elseif ( + $is_html_namespace && + isset( ReferenceMatcher::HTML_CASE_INSENSITIVE_ATTRIBUTES[ $name ] ) && + $this->prng->chance( 50 ) + ) { + /* + * HTML's case-insensitive attribute value list: with no modifier + * the flipped operand still satisfies the (name, value) pair on + * an html-namespace element, which makes the folding rule + * load-bearing for the mustMatchFid invariant — name and value + * here come from the same real element, unlike the independent + * pools in gen_attr_selector. + */ + $operand = $this->random_case( $operand ); } return array( diff --git a/tools/css-selector-fuzz/lib/TreeCapture.php b/tools/css-selector-fuzz/lib/TreeCapture.php index 616a3ff65ba76..2350db024c8ad 100644 --- a/tools/css-selector-fuzz/lib/TreeCapture.php +++ b/tools/css-selector-fuzz/lib/TreeCapture.php @@ -67,6 +67,7 @@ public static function capture( string $html, ?string $context = null ): array { 'fid' => self::fid_of( $processor ), 'attrs' => self::attrs_of( $processor ), 'ancestorTags' => array_reverse( $breadcrumbs ), + 'namespace' => $processor->get_namespace(), ); } diff --git a/tools/css-selector-fuzz/lib/Worker.php b/tools/css-selector-fuzz/lib/Worker.php index 5bb607a032c58..ed3a9c7fa24d2 100644 --- a/tools/css-selector-fuzz/lib/Worker.php +++ b/tools/css-selector-fuzz/lib/Worker.php @@ -785,15 +785,24 @@ private static function check_lexbor_differential( array $complex_ast, string $s } /* - * lexbor #368: class/#id match ASCII case-insensitively even in - * no-quirks documents. Compare lexbor against the reference run - * with quirks-style class/ID folding ( the only thing the flag - * affects ) so the rest of the semantics still get differential - * coverage; WP itself is still held to the strict expectation. + * Two known lexbor deviations are compensated for so the rest of the + * semantics still get differential coverage; WP itself is still held + * to the strict expectation: + * + * - lexbor #368: class/#id match ASCII case-insensitively even in + * no-quirks documents. Compare lexbor against the reference run + * with quirks-style class/ID folding. + * - lexbor does not implement HTML's case-insensitive attribute + * value list ( [rel=NOFOLLOW] does not match rel="nofollow" ), + * where browsers and WP do. Compare lexbor against the reference + * run with that list disabled. */ - $expected_for_lexbor = LexborOracle::has_issue_368() - ? ReferenceMatcher::expected_html_matches_rows( $complex_ast, $rows, true ) - : $expected; + $expected_for_lexbor = ReferenceMatcher::expected_html_matches_rows( + $complex_ast, + $rows, + LexborOracle::has_issue_368() ? true : $quirks, + false + ); // lexbor reports in document order, WP/reference in visit order — // compare as multisets. diff --git a/tools/css-selector-fuzz/lib/util.php b/tools/css-selector-fuzz/lib/util.php index 6fe6662a6a3b8..d70d5cff9bae1 100644 --- a/tools/css-selector-fuzz/lib/util.php +++ b/tools/css-selector-fuzz/lib/util.php @@ -137,6 +137,23 @@ function ascii_strtolower( string $input ): string { return strtr( $input, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz' ); } +function ascii_strtoupper( string $input ): string { + return strtr( $input, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' ); +} + +/** Flips the case of each ASCII letter independently with 50% probability. */ +function str_shuffle_case( string $input, Prng $prng ): string { + $out = ''; + for ( $i = 0; $i < strlen( $input ); $i++ ) { + $byte = $input[ $i ]; + if ( $prng->chance( 50 ) ) { + $byte = ctype_lower( $byte ) ? ascii_strtoupper( $byte ) : ascii_strtolower( $byte ); + } + $out .= $byte; + } + return $out; +} + /** * Splits a valid UTF-8 string into codepoints. * From 892b0e9d5ff7cda72841f7746ea55f94e47e7bc2 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 11 Jun 2026 00:08:19 +0200 Subject: [PATCH 177/634] CSS selector fuzz: draft two more upstream lexbor reports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issues 4 and 5, both surfaced while verifying the WP conformance fixes against lexbor and both re-verified directly against the harness: 4. EOF does not auto-close an open attribute selector block: '[att=val' is a parse error where CSS Syntax §5.4.8 returns the block ('[att=val]') and Chrome accepts it. Controls confirm grammar-level truncation ('[att=', '[') is correctly rejected and escape-at-EOF ('.foo\' -> foo U+FFFD) already works — the gap is specifically the simple-block auto-close. 5. HTML's case-insensitive attribute value list is not implemented: '[rel=nofollow]' does not match rel="NOFOLLOW" where the HTML spec and Chrome fold the 46 listed attributes' values. Controls confirm explicit i/s modifiers and unlisted attributes behave. Includes the namespace-scoping caveat (spec scopes to HTML elements; Chrome folds SVG too). Both are compensated for in this fuzzer's differential (issue 4 never reaches lexbor because the differential compares canonical re-renders; issue 5 is compensated like #368 by comparing lexbor against the reference run with the list disabled). Same filing-agent protocol as issues 1-3: re-verify at master, dedupe, one self-contained C repro per issue. --- .../lexbor/UPSTREAM-ISSUES.md | 86 ++++++++++++++++++- 1 file changed, 82 insertions(+), 4 deletions(-) diff --git a/tools/css-selector-fuzz/lexbor/UPSTREAM-ISSUES.md b/tools/css-selector-fuzz/lexbor/UPSTREAM-ISSUES.md index 8ebf17484b095..9ec23e414dcfa 100644 --- a/tools/css-selector-fuzz/lexbor/UPSTREAM-ISSUES.md +++ b/tools/css-selector-fuzz/lexbor/UPSTREAM-ISSUES.md @@ -1,9 +1,10 @@ # lexbor — draft upstream bug reports -Three spec-conformance bugs in liblexbor's CSS selectors support, found while +Five spec-conformance bugs in liblexbor's CSS selectors support, found while using lexbor as a differential oracle for the WordPress HTML-API CSS selector -fuzzer (`tools/css-selector-fuzz/`). All three were re-verified directly -against the harness on 2026-06-10. +fuzzer (`tools/css-selector-fuzz/`). Issues 1–3 were re-verified directly +against the harness on 2026-06-10; issues 4–5 surfaced during the WP +conformance-fix session and were re-verified on 2026-06-11. - **Pinned version:** lexbor v3.0.0 (`2ae88a1c6b52`), built by `tools/css-selector-fuzz/lexbor/build.sh`. @@ -20,7 +21,9 @@ against the harness on 2026-06-10. the report which commit you tested. 2. **Search for duplicates** before filing (suggested queries: `~=`, `attr-modifier`, `case insensitive modifier`, `ident code point`, - `U+00B7`, `non-ascii`). #368 shows the maintainer's preferred repro style. + `U+00B7`, `non-ascii`, `EOF`, `unclosed`, `simple block`, + `case-insensitive attribute`, `querySelector`). #368 shows the + maintainer's preferred repro style. 3. **One issue per bug.** Reduce each to a self-contained C repro (sketch below); maintainers should not need this repo's harness. 4. Reproduction via this repo (fast path): build the harness @@ -139,3 +142,78 @@ The U+00F7 row is a control: the division sign is correctly NOT an ident code point, so lexbor's boundary is off by exactly the U+00B7 / U+00C0–U+00F6 ranges. Workaround used by this fuzzer: hex-escape all non-ASCII (`\dc ber` parses fine), which is why this surfaces only with raw multibyte selectors. + +## Issue 4 — EOF does not auto-close an open attribute selector block + +Per CSS Syntax Level 3, tokenization auto-closes unterminated simple blocks +at the end of input (a parse error, but the block is returned), and an +unterminated string at EOF returns the string token: + +> \: This is a parse error. Return the block. +> — https://www.w3.org/TR/css-syntax-3/#consume-simple-block (§5.4.8) + +> EOF: This is a parse error. Return the \. +> — https://www.w3.org/TR/css-syntax-3/#consume-string-token (§4.3.5) + +So `[att=val` is the same selector as `[att=val]`, and `[att="a b` carries +the string value `a b`. lexbor reports a selector parse error for every +EOF-truncated attribute selector. Verified at v3.0.0 against +`
` / `
`: + +| selector | lexbor | spec / Chrome 149 | +|-----------------|---------------|-------------------| +| `[att]` | parses ✅ | parses | +| `[att=val]` | parses ✅ | parses | +| `[att` | parse error ❌ | parses, matches | +| `[att=val` | parse error ❌ | parses, matches | +| `[att="a b` | parse error ❌ | parses, matches | +| `[att=val i` | parse error ❌ | parses, matches | +| `div[att` | parse error ❌ | parses, matches | +| `[att=` | parse error ✅ | error (grammar) | +| `[att~` | parse error ✅ | error (grammar) | +| `[` | parse error ✅ | error (grammar) | +| `[att=val, div` | parse error ✅ | error (comma is inside the open block) | + +The last four rows are controls: truncation inside the selector *grammar* +(matcher without value, lone bracket) is invalid even after auto-close, and +lexbor correctly rejects those. Chrome 149 (`document.querySelectorAll`) +accepts and rejects exactly per the table (verified 2026-06-10 via +Playwright). Note lexbor's escape handling at EOF is fine — `.foo\` parses +as class `foo\u{FFFD}` per §4.3.7 — the gap is specifically the simple-block +auto-close. + +## Issue 5 — HTML's case-insensitive attribute value list not implemented + +HTML defines 46 attributes (`type`, `rel`, `lang`, `dir`, `media`, +`hreflang`, `http-equiv`, ...) whose values must match ASCII +case-insensitively in attribute selectors on an HTML element when the +selector has no `i`/`s` modifier: + +> Attribute selectors on an HTML element in an HTML document must treat the +> values of attributes with the following names as ASCII case-insensitive: … +> — https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors + +lexbor matches all attribute values case-sensitively unless the selector +carries an explicit `i`. Verified at v3.0.0 against +`` (`e1`), `` (`e2`), +`` (`e3`): + +| selector | lexbor | spec / Chrome 149 | +|--------------------|--------------|-------------------| +| `[rel=nofollow]` | `e2` only ❌ | `e1` and `e2` | +| `[rel=NOFOLLOW]` | `e1` only ❌ | `e1` and `e2` | +| `[rel=nofollow i]` | `e1`, `e2` ✅ | `e1` and `e2` | +| `[rel=nofollow s]` | `e2` only ✅ | `e2` only | +| `[data-x=abc]` | no match ✅ | no match (unlisted attribute) | + +The last three rows are controls: explicit modifiers work, and attributes +outside the list stay case-sensitive. Chrome 149 agrees with the spec column +(verified 2026-06-10 via Playwright), with one scoping caveat the report +should mention: the spec restricts the rule to elements in the HTML +namespace, but Chrome also folds on SVG-namespace elements +(`` matches `[type=TEXT]`), so an implementation true +to the spec letter would scope by element namespace. This may be framed as +a feature request rather than a bug if lexbor considers document-language +selector rules out of scope for its selectors module — but lexbor is an +HTML engine and browsers uniformly implement the folding, so matching +against HTML documents diverges from every browser without it. From 485af4b79ddd7660aab1667d96b0e02b96f16953 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 11 Jun 2026 00:11:01 +0200 Subject: [PATCH 178/634] CSS selector fuzz: bring NEXT-STEPS status up to date - Add the missing IMPLEMENTED entry for EOF auto-close (the session decision block still said 'will be made spec-conformant'). - Record the invalid-UTF-8 escape-decode wart both review panels flagged ('\' + invalid byte decodes to mb_substitute_character, '?', instead of U+FFFD) and tie it to the open handoff item 5 contract decision. - Point the lexbor gaps at their now-drafted UPSTREAM-ISSUES.md entries (issues 4 and 5) instead of 'candidate upstream report'. - Note the mutation-test result for the path-directed case-flip and the two minor review leftovers (namespace-defaulting dead helpers, s-modifier differential coverage). - Fix the stale repo-state paragraph (the tooling has been committed on this branch since 2026-06-10) and list what remains open. --- tools/css-selector-fuzz/NEXT-STEPS.md | 61 ++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 11 deletions(-) diff --git a/tools/css-selector-fuzz/NEXT-STEPS.md b/tools/css-selector-fuzz/NEXT-STEPS.md index 7cd82c01cce89..d5551395382fe 100644 --- a/tools/css-selector-fuzz/NEXT-STEPS.md +++ b/tools/css-selector-fuzz/NEXT-STEPS.md @@ -49,6 +49,28 @@ > and rejects `[a=b \73]`). Fail-safe refusal, not a mis-match; revisit only > if the matcher ever moves to token-level parsing. > +> **EOF auto-close for attribute selectors — IMPLEMENTED (2026-06-10):** +> per CSS Syntax 3 §5.4.8/§4.3.5, the end of input closes an unterminated +> simple block (and an unterminated string), so `[att=val`, `[att`, +> `[att="a b`, and `[att=val i` are valid selectors; grammar-level +> truncations (`[`, `[a=`, `[a~`, `[a=b, div`) stay invalid. Verified +> against Chromium form-by-form, including an exhaustive per-byte +> truncation table in review. lexbor rejects all EOF-truncated forms +> (drafted as `lexbor/UPSTREAM-ISSUES.md` issue 4); the differential is +> unaffected because it compares canonical re-renders. Fuzzer gained an +> `eof-truncated` edge-escape kind and the invalid corpus was reshuffled +> along the new validity boundary; COVERAGE.md regenerated. +> +> **Escape decode of invalid UTF-8 bytes (recorded 2026-06-10, not fixed):** +> `\` followed by an invalid UTF-8 byte decodes through `mb_substr()`'s +> substitution character — `?` by default — instead of U+FFFD +> (`consume_escaped_codepoint()`, identity-escape arm). Pre-existing, +> byte-identical before/after the EOF fixes; flagged independently by both +> review panels. Belongs to the open invalid-UTF-8 input policy decision +> (handoff item 5): per spec, input preprocessing operates on decoded code +> points, so byte-level decode errors should arguably become U+FFFD before +> tokenization rather than leak `mb_substitute_character`. +> > **HTML case-insensitive attribute value list — IMPLEMENTED (2026-06-10):** > per https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors > the values of ~46 listed attributes (`type`, `rel`, `lang`, `dir`, @@ -59,7 +81,16 @@ > - **lexbor does not implement the rule at all** (`[rel=nofollow]` does > not match `rel="NOFOLLOW"`) — compensated in the differential the same > way as lexbor #368 (lexbor is compared against the reference run with -> the list disabled); candidate upstream report. +> the list disabled); drafted as `lexbor/UPSTREAM-ISSUES.md` issue 5. +> - The case-flip generator twist in `path_attr_feature` makes the folding +> load-bearing for `mustMatchFid` (mutation-tested: disabling the core +> branch fires 11 failures in 3000 seeds). Minor leftovers from review: +> the unused `expected_*_processor_matches` back-compat helpers in +> `ReferenceMatcher` silently default rows to the html namespace — fine +> today (the safe model generator emits no foreign content) but a trap +> for a future caller; and `s`-forces-sensitivity only gets differential +> coverage when sampled values happen to differ in case (pinned by unit +> tests instead). > - **Chromium applies the list to foreign elements too** (`[type=TEXT]` > matches ``), diverging from the HTML spec's "on an > HTML element" scoping. WP follows the spec (html namespace only, via @@ -67,18 +98,26 @@ > tracking and applies the list to every element — an inherent > tag-processor approximation, same as its ancestor-blind matching. > -> **Session decisions (2026-06-10):** EOF-truncated selectors (`div[a=b`) -> will be made spec-conformant — CSS Syntax auto-closes open blocks at EOF — -> rather than documented as an intentional rejection. HTML's default -> case-insensitive attribute value list will be implemented (no-modifier + -> html-namespace + listed attribute; explicit `s` keeps forcing -> case-sensitivity). Grammar-level truncations (`[`, `[a=`, `div >`, `div,`) -> stay invalid — browsers reject those too. No Trac tickets for any of this. +> **Session decisions (2026-06-10, both since implemented — see the +> IMPLEMENTED entries above):** EOF-truncated selectors (`div[a=b`) are +> spec-conformant (CSS Syntax auto-closes open blocks at EOF) rather than +> documented as an intentional rejection. HTML's default case-insensitive +> attribute value list is implemented (no-modifier + html-namespace + +> listed attribute; explicit `s` keeps forcing case-sensitivity). +> Grammar-level truncations (`[`, `[a=`, `div >`, `div,`) stay invalid — +> browsers reject those too. No Trac tickets for any of this. +> +> **Still open from the original follow-up list:** the O(1) identity-escape +> decode (perf only, do only if asked) and the invalid-UTF-8 input policy +> (contract decision; see the escape-decode note above), plus the tooling +> items in this file's hardening notes (self-check decoupling, class-NUL +> injection, vacuous-assertion rate, quirks-mode single-oracle gap). Repo: `/Users/jonsurrell/a8c/wordpress-develop/html-css-fuzz`, branch -`html-css-fuzz` @ `6ebbcc2fe4` (trunk + merged `html-api/add-css-selector-parser`). -PHP 8.4.21. Everything under `tools/css-selector-fuzz/` is untracked; nothing -committed. `/artifacts` is gitignored (runner output lives there). +`html-css-fuzz` (trunk + merged `html-api/add-css-selector-parser`). +PHP 8.4.21. The fuzzer and all fixes are committed on this branch +(`CSS selector:` / `CSS selector fuzz:` prefixed commits). `/artifacts` is +gitignored (runner output lives there). ## Measured weaknesses driving this plan From 232a1240bf9f458e1fbd8f8464db3bfd3ae8cb6b Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 11 Jun 2026 10:48:31 +0200 Subject: [PATCH 179/634] CSS selector fuzz: record O(1) identity-escape decode as implemented Move the perf follow-up out of the still-open list and record the outcome: _wp_scan_utf8-based in-place sizing, byte-identical behavior (74M differential cases), linear scaling, and the deliberately-kept quadratic mb_substr fallback for escaped invalid bytes pending the invalid-UTF-8 policy decision. --- tools/css-selector-fuzz/NEXT-STEPS.md | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/tools/css-selector-fuzz/NEXT-STEPS.md b/tools/css-selector-fuzz/NEXT-STEPS.md index d5551395382fe..b4c38885ffa07 100644 --- a/tools/css-selector-fuzz/NEXT-STEPS.md +++ b/tools/css-selector-fuzz/NEXT-STEPS.md @@ -107,11 +107,28 @@ > Grammar-level truncations (`[`, `[a=`, `div >`, `div,`) stay invalid — > browsers reject those too. No Trac tickets for any of this. > -> **Still open from the original follow-up list:** the O(1) identity-escape -> decode (perf only, do only if asked) and the invalid-UTF-8 input policy -> (contract decision; see the escape-decode note above), plus the tooling -> items in this file's hardening notes (self-check decoupling, class-NUL -> injection, vacuous-assertion rate, quirks-mode single-oracle gap). +> **O(1) identity-escape decode — IMPLEMENTED (2026-06-11, perf only):** +> `consume_escaped_codepoint()`'s identity arm no longer copies the input +> tail per escape (`mb_substr( substr( … ) )`); it sizes the code point in +> place with `_wp_scan_utf8( $input, $at, $invalid_length, 4, 1 )` +> (`compat-utf8.php`, WP 6.9). 200KB all-escape selector: 180 ms → 45 ms, +> scaling now linear (47/90/180 ms at 200/400/800KB; previously ~4× per +> doubling). Behavior is byte-identical by construction: escapes of +> *invalid* UTF-8 still fall through to the literal old `mb_substr()` line +> (re-verified ~74M differential cases, 0 mismatches, including non-default +> `mb_substitute_character` settings), so the open invalid-UTF-8 policy +> decision is untouched — and that fallback path remains quadratic for +> selectors made of escaped invalid bytes (accepted; developer-supplied +> input). Caution recorded in-code: `_wp_utf8_codepoint_span()` looks like +> the natural helper but passes `max_bytes = null`, making its ASCII +> fast-path O(tail) per call — quadratic again. Escape pin coverage grew to +> 14 cases (2/3/4-byte chars incl. at-EOF, NUL, each invalid-byte class). +> +> **Still open from the original follow-up list:** the invalid-UTF-8 input +> policy (contract decision; see the escape-decode note above), plus the +> tooling items in this file's hardening notes (self-check decoupling, +> class-NUL injection, vacuous-assertion rate, quirks-mode single-oracle +> gap). Repo: `/Users/jonsurrell/a8c/wordpress-develop/html-css-fuzz`, branch `html-css-fuzz` (trunk + merged `html-api/add-css-selector-parser`). From 9c2cb64d5e338699ed30af567016927cb614b860 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 11 Jun 2026 11:46:05 +0200 Subject: [PATCH 180/634] CSS selector fuzz: note the canary red suite for the UTF-8 policy item The invalid-UTF-8 escape-decode note now points at the mb_substitute_character canary fixture and pins landed in wpCssSelectorParserMatcher.php, which serve as the ready-made red suite for the item-5 U+FFFD fix. --- tools/css-selector-fuzz/NEXT-STEPS.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/css-selector-fuzz/NEXT-STEPS.md b/tools/css-selector-fuzz/NEXT-STEPS.md index b4c38885ffa07..5b79201125cf1 100644 --- a/tools/css-selector-fuzz/NEXT-STEPS.md +++ b/tools/css-selector-fuzz/NEXT-STEPS.md @@ -69,7 +69,12 @@ > review panels. Belongs to the open invalid-UTF-8 input policy decision > (handoff item 5): per spec, input preprocessing operates on decoded code > points, so byte-level decode errors should arguably become U+FFFD before -> tokenization rather than leak `mb_substitute_character`. +> tokenization rather than leak `mb_substitute_character`. A red suite for +> the fix is in place (2026-06-11): `wpCssSelectorParserMatcher.php` pins +> `mb_substitute_character()` to a U+2603 canary in set_up()/tear_down(), +> and its seven invalid-byte escape pins (plus a dedicated offset-overrun +> test) assert the leak's damage — swallowed characters, offset past end +> of input. Decoding to U+FFFD per maximal subpart flips every one. > > **HTML case-insensitive attribute value list — IMPLEMENTED (2026-06-10):** > per https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors From ec99a9f893cd4498704675bfdcf8817794414609 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 11 Jun 2026 18:08:11 +0200 Subject: [PATCH 181/634] CSS selector fuzz: Model the scrub notice in the worker invariants MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The core scrub change makes from_selectors() report _doing_it_wrong() once per parse of an invalid-UTF-8 selector. The worker's notice invariants assumed zero notices for parseable selectors and exactly two for unparseable ones; the chaos/mutated buckets organically produce invalid-UTF-8 selectors, so a 5000-seed run failed 108 cases against the new core behavior (94 doing-it-wrong-unexpected, 12 doing-it-wrong-missing, 2 case-determinism). Worker changes: - flush_select_parse_caches(): both select() implementations memoize the most recently parsed selector string in a function static, so whether a call re-parses — and therefore whether the parse-time scrub notice fires — depended on worker history, breaking the case-determinism re-run. Parsing a sentinel (#-fuzz-cache-flush-) through both processors before each notice-assertion window makes exactly one parse happen inside it. The flush works even for unparseable sentinels (the cache assigns before the null check) and precedes reset_doing_it_wrong(), so it cannot pollute recordings. - check_select_matches() expects exactly one scrub notice — named WP_CSS_Compound_Selector_List::from_selectors for the tag target, WP_CSS_Complex_Selector_List::from_selectors for html — iff wp_is_valid_utf8() rejects the selector string, and nothing else. Review verified the predicate is exactly equivalent to "the scrub changed the input" (exhaustive 1-2-byte strings plus 2M random). - check_select_rejection() expects the two per-call select() notices (those fire on cache hits too) plus one leading scrub notice for invalid-UTF-8 selectors, order- and name-exact via notices_match(). Stale comments updated now that parsed ASTs are valid UTF-8 by construction: Metamorph's variants() guard and the lexbor differential's skipped-utf8 state are kept as defense in depth (a nonzero skipped-utf8 tally now indicates a normalization bypass), and the invariant glossary describes the expected-set semantics. NEXT-STEPS.md: the invalid-UTF-8 policy item is resolved as scrub (decision history, the linked value-getter pin obligation, the optional parse()-visibility follow-up); the O(1) decode entry notes its mb_substr() fallback was since removed; the still-open list points at the deferred coverage work (dedicated invalid-UTF-8 generator bucket, raw-byte mutation class, explicit lexbor probe — handoff drafted) and records that the chaos/mutated buckets already exercise the scrub organically, with lexbor agreeing across clean 5000- and 10000-seed runs. Gates: self-check OK, 5000 seeds 0 failures, plus independent reviewer runs (2x2000 determinism-checked, 8000 additional seeds, all clean). --- tools/css-selector-fuzz/NEXT-STEPS.md | 61 ++++++++---- tools/css-selector-fuzz/lib/Metamorph.php | 10 +- tools/css-selector-fuzz/lib/Worker.php | 108 ++++++++++++++++++++-- 3 files changed, 146 insertions(+), 33 deletions(-) diff --git a/tools/css-selector-fuzz/NEXT-STEPS.md b/tools/css-selector-fuzz/NEXT-STEPS.md index 5b79201125cf1..b84ec6130f47a 100644 --- a/tools/css-selector-fuzz/NEXT-STEPS.md +++ b/tools/css-selector-fuzz/NEXT-STEPS.md @@ -61,20 +61,36 @@ > `eof-truncated` edge-escape kind and the invalid corpus was reshuffled > along the new validity boundary; COVERAGE.md regenerated. > -> **Escape decode of invalid UTF-8 bytes (recorded 2026-06-10, not fixed):** -> `\` followed by an invalid UTF-8 byte decodes through `mb_substr()`'s -> substitution character — `?` by default — instead of U+FFFD -> (`consume_escaped_codepoint()`, identity-escape arm). Pre-existing, -> byte-identical before/after the EOF fixes; flagged independently by both -> review panels. Belongs to the open invalid-UTF-8 input policy decision -> (handoff item 5): per spec, input preprocessing operates on decoded code -> points, so byte-level decode errors should arguably become U+FFFD before -> tokenization rather than leak `mb_substitute_character`. A red suite for -> the fix is in place (2026-06-11): `wpCssSelectorParserMatcher.php` pins -> `mb_substitute_character()` to a U+2603 canary in set_up()/tear_down(), -> and its seven invalid-byte escape pins (plus a dedicated offset-overrun -> test) assert the leak's damage — swallowed characters, offset past end -> of input. Decoding to U+FFFD per maximal subpart flips every one. +> **Invalid-UTF-8 input policy — IMPLEMENTED as scrub (2026-06-11):** +> selector strings are UTF-8 text; `normalize_selector_input()` now decodes +> the byte stream first via `wp_scrub_utf8()` (WP 6.9, maximal-subpart +> U+FFFD replacement, matching the WHATWG decoder CSS Syntax §3.2 invokes), +> and reports a `_doing_it_wrong()` (named `::from_selectors`) when +> the input changed. The `mb_substitute_character()` leak in +> `consume_escaped_codepoint()` is gone structurally: the identity arm's +> `mb_substr()` fallback is replaced by "consume the maximal subpart the +> `_wp_scan_utf8()` scan already reported, return one U+FFFD" — reachable +> only via direct `parse()` calls with un-normalized input, and consistent +> with the scrub when it is. Decision history: reject (`wp_is_valid_utf8()` +> → null) and raw passthrough were rejected after a three-persona +> adversarial panel; scrub is the unique option stable under both the +> current raw value getters and their likely scrubbed future. The U+2603 +> canary in `wpCssSelectorParserMatcher.php` set_up() is retained +> permanently — its job inverted from documenting the leak to proving +> setting-independence. Worker.php learned the notice contract (scrub +> notice expected iff `!wp_is_valid_utf8(selector)`) and flushes the +> `select()` parse caches before each notice-assertion window so the +> once-per-parse notice is deterministic under case re-runs. +> **Linked obligation:** the select-level pin +> `test_select_scrubbed_selector_does_not_match_raw_invalid_document_bytes` +> documents that scrubbed selectors cannot match raw invalid document +> bytes; if the HTML API value getters (`get_attribute()`, `class_list()`, +> …) are ever changed to scrub their return values, that case flips to a +> match and the pin must be updated in the same change. +> **Optional follow-up:** tightening the `parse()` prototype from public to +> protected (the classes are `@access private`) would make un-normalized +> input structurally impossible and let the defensive escape arm be +> deleted. > > **HTML case-insensitive attribute value list — IMPLEMENTED (2026-06-10):** > per https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors @@ -128,12 +144,19 @@ > the natural helper but passes `max_bytes = null`, making its ASCII > fast-path O(tail) per call — quadratic again. Escape pin coverage grew to > 14 cases (2/3/4-byte chars incl. at-EOF, NUL, each invalid-byte class). +> (Superseded the same day for invalid bytes: the `mb_substr()` fallback and +> its quadratic tail were removed by the scrub implementation — see the +> invalid-UTF-8 policy entry above.) > -> **Still open from the original follow-up list:** the invalid-UTF-8 input -> policy (contract decision; see the escape-decode note above), plus the -> tooling items in this file's hardening notes (self-check decoupling, -> class-NUL injection, vacuous-assertion rate, quirks-mode single-oracle -> gap). +> **Still open from the original follow-up list:** the tooling items in +> this file's hardening notes (self-check decoupling, class-NUL injection, +> vacuous-assertion rate, quirks-mode single-oracle gap), plus deferred +> fuzzer coverage for the scrub surface (dedicated invalid-UTF-8 generator +> bucket with maximal-subpart AST expectations, raw-byte mutation class, +> explicit lexbor invalid-byte probe — handoff drafted 2026-06-11; note +> the chaos/mutated buckets already produce invalid-UTF-8 selectors +> organically and lexbor agreed with the scrubbed results across a clean +> 5000-seed run). Repo: `/Users/jonsurrell/a8c/wordpress-develop/html-css-fuzz`, branch `html-css-fuzz` (trunk + merged `html-api/add-css-selector-parser`). diff --git a/tools/css-selector-fuzz/lib/Metamorph.php b/tools/css-selector-fuzz/lib/Metamorph.php index 44e0e434ff4b2..159d8e8bedd52 100644 --- a/tools/css-selector-fuzz/lib/Metamorph.php +++ b/tools/css-selector-fuzz/lib/Metamorph.php @@ -35,11 +35,11 @@ class Metamorph { */ public static function variants( array $list_ast, Prng $prng ): array { /* - * The WP parser passes raw bytes through: a selector that is not - * valid UTF-8 yields AST names that are not valid UTF-8 (it does - * not substitute U+FFFD). The renderer can only round-trip valid - * UTF-8 names, so such ASTs (only reachable from chaos/mutated - * inputs) are not transformable. + * from_selectors() scrubs invalid UTF-8 to U+FFFD before parsing, so + * parsed AST names are always valid UTF-8 and this guard should be + * unreachable. It stays as defense in depth: the renderer can only + * round-trip valid UTF-8 names, and a future AST source that skips + * normalization would otherwise corrupt the variants silently. */ if ( ! ast_strings_are_utf8( $list_ast ) ) { return array(); diff --git a/tools/css-selector-fuzz/lib/Worker.php b/tools/css-selector-fuzz/lib/Worker.php index ed3a9c7fa24d2..86ad865d50e37 100644 --- a/tools/css-selector-fuzz/lib/Worker.php +++ b/tools/css-selector-fuzz/lib/Worker.php @@ -22,9 +22,15 @@ * from the reference matcher. * - match-mismatch-tag: WP_HTML_Tag_Processor::select() match set * differs from the reference matcher. - * - doing-it-wrong-unexpected: _doing_it_wrong fired for a selector that parsed. - * - doing-it-wrong-missing: _doing_it_wrong did not fire ( or fired the wrong - * number of times ) for an unparseable selector. + * - doing-it-wrong-unexpected: the _doing_it_wrong calls during matching did + * not equal the expected set ( exactly one scrub + * notice for an invalid-UTF-8 selector, none + * otherwise ). + * - doing-it-wrong-missing: the _doing_it_wrong calls for an unparseable + * selector did not equal the expected set ( one + * select() notice per call, plus one leading + * scrub notice when the selector is invalid + * UTF-8 ). * - select-on-null: select() returned true for an unparseable selector. * - processor-error: the processor entered an error/unsupported state. * - case-determinism: running the full case twice gave different digests. @@ -672,6 +678,33 @@ static function () use ( $target, $selector_string, $html, $context ) { ); } + /** + * Flushes the select() parse caches. + * + * Both select() implementations memoize the most recently parsed selector + * string in a function-static cache, so whether a select() call re-parses + * — and therefore whether parse-time notices ( the invalid-UTF-8 scrub + * notice from from_selectors() ) fire — depends on what the worker + * happened to parse before. Parsing a sentinel selector first makes the + * next select() call for the case selector deterministic: it always + * re-parses, so exactly one parse happens inside each notice-assertion + * window regardless of worker history or case re-runs. + */ + private static function flush_select_parse_caches(): void { + ( new \WP_HTML_Tag_Processor( '' ) )->select( '#-fuzz-cache-flush-' ); + \WP_HTML_Processor::create_full_parser( '' )->select( '#-fuzz-cache-flush-' ); + } + + /** + * The _doing_it_wrong() name under which from_selectors() reports that an + * invalid-UTF-8 selector string was scrubbed to U+FFFD before parsing. + * + * @param string $target 'html' or 'tag'. + */ + private static function scrub_notice_name( string $target ): string { + return ( 'tag' === $target ? 'WP_CSS_Compound_Selector_List' : 'WP_CSS_Complex_Selector_List' ) . '::from_selectors'; + } + /** * Runs a select() loop on a parseable selector and compares the match set * against the reference matcher. @@ -680,6 +713,7 @@ static function () use ( $target, $selector_string, $html, $context ) { * @return string[]|null The actual match set, or null when matching failed. */ private static function check_select_matches( string $target, string $selector_string, array $document, array $expected, callable $record ): ?array { + self::flush_select_parse_caches(); Bootstrap::reset_doing_it_wrong(); list( $actual, $error ) = self::collect_matches( $target, $selector_string, $document ); @@ -695,13 +729,28 @@ private static function check_select_matches( string $target, string $selector_s return null; } + /* + * A selector string containing invalid UTF-8 is scrubbed to U+FFFD by + * from_selectors(), which reports the replacement with exactly one + * notice on the (single, cache-flushed) parse. Anything else is + * unexpected for a selector that parses. + */ + $expected_calls = \wp_is_valid_utf8( $selector_string ) + ? array() + : array( + array( + 'function' => self::scrub_notice_name( $target ), + ), + ); + $doing_it_wrong = Bootstrap::doing_it_wrong_calls(); - if ( array() !== $doing_it_wrong ) { + if ( ! self::notices_match( $expected_calls, $doing_it_wrong ) ) { $record( 'doing-it-wrong-unexpected', array( - 'target' => $target, - 'calls' => $doing_it_wrong, + 'target' => $target, + 'expectedCalls' => $expected_calls, + 'calls' => $doing_it_wrong, ) ); } @@ -754,7 +803,10 @@ private static function check_lexbor_differential( array $complex_ast, string $s * matching semantics, while byte-level parsing (escapes, whitespace, * modifier case — lexbor e.g. rejects uppercase I/S modifiers) is * covered by the AST round-trip and metamorphic invariants. ASTs - * containing invalid UTF-8 cannot be re-rendered and are skipped. + * containing invalid UTF-8 cannot be re-rendered; since + * from_selectors() scrubs input to U+FFFD before parsing, none should + * exist and this skip is defensive ( a nonzero skipped-utf8 tally + * indicates a normalization bypass ). */ if ( ! ast_strings_are_utf8( $complex_ast ) ) { return 'skipped-utf8'; @@ -946,6 +998,7 @@ static function () use ( $variant_list ) { * processor usable, and report misuse exactly once per call. */ private static function check_select_rejection( string $target, string $selector_string, array $document, callable $record ): void { + self::flush_select_parse_caches(); Bootstrap::reset_doing_it_wrong(); $context = ( $document['fragment'] ?? false ) ? $document['context'] : null; @@ -986,19 +1039,56 @@ static function () use ( $target, $selector_string, $document, $context ) { ); } + /* + * Two select() calls report the unparseable selector once each; the + * parse cache only skips re-parsing, never the per-call notice. An + * invalid-UTF-8 selector additionally reports the U+FFFD scrub once, + * on the first call ( the only one that parses after the flush ). + */ + $select_notice_name = ( 'tag' === $target ? 'WP_HTML_Tag_Processor' : 'WP_HTML_Processor' ) . '::select'; + $expected_calls = array( + array( 'function' => $select_notice_name ), + array( 'function' => $select_notice_name ), + ); + if ( ! \wp_is_valid_utf8( $selector_string ) ) { + array_unshift( $expected_calls, array( 'function' => self::scrub_notice_name( $target ) ) ); + } + $doing_it_wrong = Bootstrap::doing_it_wrong_calls(); - if ( 2 !== count( $doing_it_wrong ) ) { + if ( ! self::notices_match( $expected_calls, $doing_it_wrong ) ) { $record( 'doing-it-wrong-missing', array( 'target' => $target, - 'expectedCalls' => 2, + 'expectedCalls' => $expected_calls, 'calls' => $doing_it_wrong, ) ); } } + /** + * Compares recorded _doing_it_wrong() calls against expectations: same + * count, in order, matching on every key the expectation specifies + * ( recorded calls also carry 'message', which expectations omit ). + * + * @param array[] $expected_calls Expected calls, each a subset of record keys. + * @param array[] $actual_calls Recorded calls. + */ + private static function notices_match( array $expected_calls, array $actual_calls ): bool { + if ( count( $expected_calls ) !== count( $actual_calls ) ) { + return false; + } + foreach ( $expected_calls as $i => $expected_call ) { + foreach ( $expected_call as $key => $value ) { + if ( ( $actual_calls[ $i ][ $key ] ?? null ) !== $value ) { + return false; + } + } + } + return true; + } + /* * ------------- * Batch running From 2adef6a891ca6df3c154aede0a3c7656c0bb2d68 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 11 Jun 2026 21:27:29 +0200 Subject: [PATCH 182/634] CSS selector fuzz: Cover the UTF-8 scrub with an invalid-utf8 bucket MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The core scrub (598ed6f363) decodes selector input before parsing: each maximal subpart of an ill-formed UTF-8 sequence becomes one U+FFFD (CSS Syntax 3 §3.2 via the WHATWG decoder). Until now only the chaos/mutated buckets exercised that path, organically and without AST expectations. The new bucket (weight 5 in both maps) injects one raw ill-formed sequence into a class/ID/attribute-name ident or quoted attribute string operand — lead/mid/trail/whole position, optionally behind a span type — and carries the post-scrub AST as its expectation. The per-class U+FFFD counts are pinned in INVALID_UTF8_CLASSES independently of wp_scrub_utf8(), so the AST round-trip is a real differential against the core scrub: lone continuation, truncated 2/3/4-byte leads, and invalid leads F5/FF decode to 1; overlong C0 80 / C1 BF to 2; surrogate half ED A0 80 to 3; beyond-max F4 90 80 80 to 4. An injected sequence is always followed by ASCII or end of input, so a continuation byte can never complete a truncated lead and shift the subpart boundaries. self-check gains a forced-bucket section (150 seeds): the selector must be invalid UTF-8, parse in both grammars, and parse to exactly the pinned AST; variety assertions require all subpart counts {1,2,3,4}, all four injection sites, and all ten byte classes. The class names and byte values are duplicated in the test deliberately — tallying from the generator's own table would shrink the assertion with a deleted entry and self-validate a drifted byte value (both demonstrated live in review). Adversarial review: three hostile reviewers. The spec reviewer verified the count table against an independently written WHATWG decoder (960 table contexts x 3 oracles; all 2880 site/position/class render combinations decode to the assumed post-scrub string; key-order-exact ASTs in both grammars; 3000-seed sweep clean). The test reviewer ran nine mutations — count drift, raw-byte expectations, suffix-guarantee removal, core scrub no-op, per-byte core scrub (killed exclusively by the two truncated classes that discriminate maximal-subpart from per-byte replacement), class deletion and de-selection, byte drift — all killed after two hardening rounds; two disclosed low-severity survivors remain (lone-continuation substring ambiguity; a class added to the table alone gets no variety pin). The integration reviewer confirmed the scrub-notice contract cannot flip (5200 constructed cases all invalid UTF-8), the lexbor differential stays live via the canonical re-render (zero skipped-utf8), digest determinism on every in-bucket seed in 1-400, and replay/minimizer behavior on raw-byte selectors. Gates: self-check OK; 5000 seeds, 0 failures (241 invalid-utf8 cases). --- tools/css-selector-fuzz/README.md | 9 +- .../lib/SelectorGenerator.php | 118 ++++++++++++++++++ tools/css-selector-fuzz/tests/self-check.php | 88 +++++++++++++ 3 files changed, 214 insertions(+), 1 deletion(-) diff --git a/tools/css-selector-fuzz/README.md b/tools/css-selector-fuzz/README.md index 3af425719c807..3767c2a1726e8 100644 --- a/tools/css-selector-fuzz/README.md +++ b/tools/css-selector-fuzz/README.md @@ -25,7 +25,7 @@ produces the same document, the same selector, and the same verdict. capture on wild documents. Wild documents that hit a construct the processor bails on (foster parenting, complex adoption-agency runs) are deterministically regenerated a bounded number of times. -3. Generate a selector in one of seven buckets: +3. Generate a selector in one of nine buckets: - `supported-compound` — must parse in both grammars; carries intended AST. - `supported-complex` — uses `>`/descendant combinators; must parse only in the complex grammar; carries intended AST. @@ -49,6 +49,13 @@ produces the same document, the same selector, and the same verdict. and -elements, `+`/`~`/`||` combinators, namespaces, non-type context selectors); must not parse. - `invalid` — not valid CSS; must not parse. + - `invalid-utf8` — a small supported selector with a raw ill-formed UTF-8 + byte sequence (lone continuation, truncated 2/3/4-byte, overlong, + surrogate half, beyond U+10FFFF) injected into a class/ID/attribute + ident or string operand; `from_selectors()` scrubs the input first, so + the case must parse and carries the post-scrub AST (one U+FFFD per + maximal subpart, with per-class subpart counts pinned independently of + `wp_scrub_utf8()`). - `chaos` — arbitrary bytes; no parse expectation. - `mutated` — a supported selector with random byte mutations; no parse expectation. diff --git a/tools/css-selector-fuzz/lib/SelectorGenerator.php b/tools/css-selector-fuzz/lib/SelectorGenerator.php index 1f3a8fa2e89c2..345228ed1a570 100644 --- a/tools/css-selector-fuzz/lib/SelectorGenerator.php +++ b/tools/css-selector-fuzz/lib/SelectorGenerator.php @@ -13,6 +13,11 @@ * (pseudo-classes/elements, sibling/column combinators, namespaces, * non-type context selectors). Must not parse in either grammar. * - invalid: not valid CSS selectors at all. Must not parse. + * - invalid-utf8: a supported compound with a raw ill-formed UTF-8 byte + * sequence injected into an ident or string operand. from_selectors() + * scrubs the input before parsing ( one U+FFFD per maximal subpart, CSS + * Syntax §3.2 via the WHATWG decoder ), so the case carries the + * post-scrub AST. * - chaos: arbitrary bytes. No parse expectation. * - mutated: a supported selector with random byte mutations. No parse * expectation. @@ -29,11 +34,35 @@ class SelectorGenerator { 'path-directed', 'unsupported', 'invalid', + 'invalid-utf8', 'chaos', 'mutated', 'edge-escape', ); + /** + * Ill-formed UTF-8 byte classes and the number of U+FFFD replacements the + * WHATWG UTF-8 decoder produces for each ( one per maximal subpart ). + * The counts are pinned here as an independent expectation — computing + * them with wp_scrub_utf8() would make the AST check a tautology. + * + * The counts assume the byte after the sequence is not a continuation + * byte ( it could complete a truncated sequence ); the generator always + * follows an injected sequence with ASCII or end of input. + */ + const INVALID_UTF8_CLASSES = array( + 'lone-continuation' => array( "\x80", 1 ), + 'truncated-2-byte' => array( "\xC3", 1 ), + 'truncated-3-byte' => array( "\xE2\x8C", 1 ), + 'truncated-4-byte' => array( "\xF0\x9F\x82", 1 ), + 'invalid-lead-f5' => array( "\xF5", 1 ), + 'invalid-lead-ff' => array( "\xFF", 1 ), + 'overlong-min' => array( "\xC0\x80", 2 ), + 'overlong-max' => array( "\xC1\xBF", 2 ), + 'surrogate-half' => array( "\xED\xA0\x80", 3 ), + 'beyond-max' => array( "\xF4\x90\x80\x80", 4 ), + ); + /** @var Prng */ private $prng; /** @var array */ @@ -182,6 +211,7 @@ public static function generate( Prng $prng, array $pools, ?array $rows = null, 'supported-complex' => 24, 'unsupported' => 14, 'invalid' => 11, + 'invalid-utf8' => 5, 'chaos' => 8, 'mutated' => 10, 'edge-escape' => 5, @@ -192,6 +222,7 @@ public static function generate( Prng $prng, array $pools, ?array $rows = null, 'path-directed' => 21, 'unsupported' => 11, 'invalid' => 9, + 'invalid-utf8' => 5, 'chaos' => 6, 'mutated' => 6, 'edge-escape' => 5, @@ -230,6 +261,9 @@ public static function generate( Prng $prng, array $pools, ?array $rows = null, case 'edge-escape': return $generator->gen_edge_escape(); + case 'invalid-utf8': + return $generator->gen_invalid_utf8(); + case 'unsupported': return array( 'bucket' => $bucket, @@ -764,6 +798,90 @@ private function gen_edge_escape(): array { ); } + /* + * ----------------------- + * Invalid-UTF-8 injection + * ----------------------- + * + * Raw ill-formed UTF-8 byte sequences in the selector input, mirroring + * the nul-input pattern: a small fixed simple selector keeps the case + * focused on the normalize_selector_input() scrub. Each maximal subpart + * of the injected sequence decodes to one U+FFFD ( per-class counts + * pinned in INVALID_UTF8_CLASSES ), and U+FFFD is a valid ident + * codepoint — including in start position — so the scrubbed selector + * must parse and the post-scrub AST is known by construction. + */ + private function gen_invalid_utf8(): array { + list( $bytes, $subparts ) = $this->prng->choice( array_values( self::INVALID_UTF8_CLASSES ) ); + + $position = $this->prng->choice( array( 'lead', 'mid', 'trail', 'whole' ) ); + $prefix = in_array( $position, array( 'lead', 'whole' ), true ) ? '' : 'a' . $this->prng->int( 0, 9 ); + $suffix = in_array( $position, array( 'trail', 'whole' ), true ) ? '' : 'z' . $this->prng->int( 0, 9 ); + $raw = $prefix . $bytes . $suffix; + $decoded = $prefix . str_repeat( "\u{FFFD}", $subparts ) . $suffix; + + switch ( $this->prng->choice( array( 'class', 'id', 'attr-name', 'attr-value' ) ) ) { + case 'class': + $rendered = '.' . $raw; + $sub = array( + 'kind' => 'class', + 'name' => $decoded, + ); + break; + + case 'id': + $rendered = '#' . $raw; + $sub = array( + 'kind' => 'id', + 'name' => $decoded, + ); + break; + + case 'attr-name': + $rendered = '[' . $raw . ']'; + $sub = array( + 'kind' => 'attr', + 'name' => $decoded, + 'matcher' => null, + 'value' => null, + 'modifier' => null, + ); + break; + + case 'attr-value': + default: + $name = 'a' . $this->prng->int( 0, 99 ); + $quote = $this->prng->chance( 50 ) ? '"' : "'"; + $rendered = '[' . $name . '=' . $quote . $raw . $quote . ']'; + $sub = array( + 'kind' => 'attr', + 'name' => $name, + 'matcher' => 'exact', + 'value' => $decoded, + 'modifier' => null, + ); + break; + } + + $type = $this->prng->chance( 40 ) ? 'span' : null; + + return array( + 'bucket' => 'invalid-utf8', + 'selector' => ( null === $type ? '' : $type ) . $rendered, + 'expectCompound' => true, + 'expectComplex' => true, + 'ast' => array( + array( + 'context' => array(), + 'self' => array( + 'type' => $type, + 'subs' => array( $sub ), + ), + ), + ), + ); + } + /* * ------------------------ * Path-directed generation diff --git a/tools/css-selector-fuzz/tests/self-check.php b/tools/css-selector-fuzz/tests/self-check.php index 10196f2d62291..d6a9a19dec2d0 100644 --- a/tools/css-selector-fuzz/tests/self-check.php +++ b/tools/css-selector-fuzz/tests/self-check.php @@ -91,6 +91,94 @@ function check( bool $condition, string $message ): void { check( count( $by_bucket ) >= 5, 'Bucket variety: saw ' . count( $by_bucket ) . ' buckets.' ); +// --- Invalid-UTF-8 bucket: post-scrub AST expectations by construction ------ +// from_selectors() replaces each maximal subpart of an ill-formed UTF-8 +// sequence with one U+FFFD before parsing ( CSS Syntax §3.2 via the WHATWG +// decoder ). The bucket injects raw ill-formed sequences and carries the +// post-scrub AST, with the per-class subpart counts hard-coded in the +// generator — independent of wp_scrub_utf8(), so this loop is a real +// differential between the generator's WHATWG expectations and the core +// scrub + parse pipeline. + +$fffd_ast_counts = array(); +$injection_sites = array(); +$byte_classes = array(); + +// The class names AND byte values are duplicated here on purpose: tallying +// from the generator's own table would silently shrink the assertion with a +// deleted entry and self-validate on a drifted byte value. +$expected_byte_classes = array( + 'lone-continuation' => "\x80", + 'truncated-2-byte' => "\xC3", + 'truncated-3-byte' => "\xE2\x8C", + 'truncated-4-byte' => "\xF0\x9F\x82", + 'invalid-lead-f5' => "\xF5", + 'invalid-lead-ff' => "\xFF", + 'overlong-min' => "\xC0\x80", + 'overlong-max' => "\xC1\xBF", + 'surrogate-half' => "\xED\xA0\x80", + 'beyond-max' => "\xF4\x90\x80\x80", +); + +$count_fffd = static function ( $node ) use ( &$count_fffd ): int { + if ( is_string( $node ) ) { + return substr_count( $node, "\u{FFFD}" ); + } + $total = 0; + if ( is_array( $node ) ) { + foreach ( $node as $child ) { + $total += $count_fffd( $child ); + } + } + return $total; +}; + +for ( $seed = 1; $seed <= 150; $seed++ ) { + $prng = new Prng( (string) $seed, 'self-check-invalid-utf8' ); + $document = DocumentGenerator::generate( $prng->fork( 'doc' ) ); + $case = SelectorGenerator::generate( $prng->fork( 'sel' ), $document['pools'], null, 'invalid-utf8' ); + $printable = \CssSelectorFuzz\printable_bytes( $case['selector'] ); + + check( 'invalid-utf8' === $case['bucket'], "Seed {$seed}: forced invalid-utf8 bucket, got {$case['bucket']}." ); + check( ! wp_is_valid_utf8( $case['selector'] ), "Seed {$seed}: selector must contain invalid UTF-8: {$printable}" ); + check( true === $case['expectCompound'] && true === $case['expectComplex'], "Seed {$seed}: invalid-utf8 cases must expect to parse in both grammars." ); + check( is_array( $case['ast'] ) && \CssSelectorFuzz\ast_strings_are_utf8( $case['ast'] ), "Seed {$seed}: expected AST must be valid UTF-8." ); + + $compound = WP_CSS_Compound_Selector_List::from_selectors( $case['selector'] ); + $complex = WP_CSS_Complex_Selector_List::from_selectors( $case['selector'] ); + check( null !== $compound, "Seed {$seed}: compound parse after scrub for: {$printable}" ); + check( null !== $complex, "Seed {$seed}: complex parse after scrub for: {$printable}" ); + if ( null === $complex || ! is_array( $case['ast'] ) ) { + continue; + } + + $parsed_ast = \CssSelectorFuzz\AstExtractor::from_complex_list( $complex ); + check( $case['ast'] === $parsed_ast, "Seed {$seed}: parsed AST equals maximal-subpart scrub expectation for: {$printable}" ); + + $fffd_ast_counts[ $count_fffd( $case['ast'] ) ] = true; + foreach ( (array) $case['ast'][0]['self']['subs'] as $sub ) { + $injection_sites[ 'attr' === $sub['kind'] && null !== $sub['matcher'] ? 'attr-value' : $sub['kind'] ] = true; + } + foreach ( $expected_byte_classes as $class_name => $class_bytes ) { + // Substring attribution is ambiguous only for lone-continuation, + // whose byte occurs inside three longer classes — good enough for + // an at-least-once variety tally. + if ( str_contains( $case['selector'], $class_bytes ) ) { + $byte_classes[ $class_name ] = true; + } + } +} + +foreach ( array( 1, 2, 3, 4 ) as $expected_count ) { + check( isset( $fffd_ast_counts[ $expected_count ] ), "Invalid-utf8 variety: a {$expected_count}-subpart byte class was generated." ); +} +foreach ( array( 'class', 'id', 'attr', 'attr-value' ) as $site ) { + check( isset( $injection_sites[ $site ] ), "Invalid-utf8 variety: injection site {$site} was generated." ); +} +foreach ( array_keys( $expected_byte_classes ) as $class_name ) { + check( isset( $byte_classes[ $class_name ] ), "Invalid-utf8 variety: byte class {$class_name} was generated." ); +} + // --- Known-answer matching cases ------------------------------------------- $known_html = '' From 5ddac66b92892031feed967191ec0fc0fa56e0d4 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 11 Jun 2026 21:37:38 +0200 Subject: [PATCH 183/634] CSS selector fuzz: Splice raw invalid UTF-8 in the mutation bucket MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mutated bucket's operations drew from a pure-ASCII alphabet, so the only ill-formed UTF-8 it produced came from delete/duplicate corrupting the pools' few multibyte characters (leads C3/CE/E2/F0 only). A new mutation kind (weight 12) splices one raw sequence from INVALID_UTF8_CLASSES at an arbitrary byte offset — possibly splitting an existing multibyte character or landing where a following continuation byte re-validates the string. These cases carry no AST expectation; they exercise crash, scrub-notice, and differential paths, and they make the worker's invalid-UTF-8 rejection branch hot (an unparseable invalid-UTF-8 selector expects scrub + two select() notices), which no bucket reached before: the invalid-utf8 bucket always parses and the chaos alphabets are valid UTF-8. self-check asserts the operation fires: at least 10 of 200 forced mutated seeds must contain a marker byte C0/C1/ED/F4/F5/FF (currently 28). The marker set is exactly the sound subset: those bytes cannot occur in any clean render (C0/C1/F5/FF never appear in valid UTF-8; ED/F4 only for U+D000-D7FF / above U+FFFFF, which no pool emits), while the four marker-free sequences (80, C3, E2 8C, F0 9F 82) reuse bytes that legitimate pool characters contain. Adversarial review: the same three hostile reviewers, all approved. Spec: splice arithmetic verified at every boundary (empty selector, at=0/length, cross-round corruption), a 20000-seed crash sweep with warnings escalated to exceptions came back clean, marker exclusivity confirmed against the pre-change generator (0 hits in 20000 seeds; the red loop reproduced exactly). Test adequacy: dead arm, dead weighted entry, and empty payload all collapse to 0/200 against the 28/200 baseline (threshold ~4 sigma below the mean under PRNG reshuffles); the one survivor (dropping only marker-free payloads) is probe diversity, not verification, and the bucket commit pins all ten classes. Integration: 5000 seeds 0 failures with byte-identical bucket distribution to the pre-change baseline, the notice contract verified self-keyed on the final byte string under 11 adversarial splice shapes including validity-restoring ones, determinism on every mutated seed in 1-400. Gates: self-check OK; 5000 seeds, 0 failures. --- tools/css-selector-fuzz/README.md | 3 ++- .../lib/SelectorGenerator.php | 22 ++++++++++++++----- tools/css-selector-fuzz/tests/self-check.php | 18 +++++++++++++++ 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/tools/css-selector-fuzz/README.md b/tools/css-selector-fuzz/README.md index 3767c2a1726e8..f0abff0934da5 100644 --- a/tools/css-selector-fuzz/README.md +++ b/tools/css-selector-fuzz/README.md @@ -57,7 +57,8 @@ produces the same document, the same selector, and the same verdict. maximal subpart, with per-class subpart counts pinned independently of `wp_scrub_utf8()`). - `chaos` — arbitrary bytes; no parse expectation. - - `mutated` — a supported selector with random byte mutations; no parse + - `mutated` — a supported selector with random byte mutations, including + raw ill-formed UTF-8 splices at arbitrary byte offsets; no parse expectation. - `edge-escape` — selectors that exercise otherwise-unreachable parser branches: hex escapes for NUL / surrogate / over-max codepoints (must diff --git a/tools/css-selector-fuzz/lib/SelectorGenerator.php b/tools/css-selector-fuzz/lib/SelectorGenerator.php index 345228ed1a570..fb93f8d66216d 100644 --- a/tools/css-selector-fuzz/lib/SelectorGenerator.php +++ b/tools/css-selector-fuzz/lib/SelectorGenerator.php @@ -1666,11 +1666,12 @@ private function mutate( string $selector ): string { $length = strlen( $selector ); $kind = $this->prng->weighted( array( - 'insert' => 30, - 'delete' => 25, - 'replace' => 25, - 'duplicate' => 10, - 'case-flip' => 10, + 'insert' => 30, + 'delete' => 25, + 'replace' => 25, + 'duplicate' => 10, + 'case-flip' => 10, + 'invalid-utf8' => 12, ) ); @@ -1714,6 +1715,17 @@ private function mutate( string $selector ): string { $selector = substr( $selector, 0, $at ) . $flip . substr( $selector, $at + 1 ); } break; + + case 'invalid-utf8': + // Splice a raw ill-formed sequence at an arbitrary byte + // offset — possibly splitting an existing multibyte + // character or landing before a continuation byte that + // completes a truncated lead. No expectations here; these + // exercise crash / scrub-notice / differential paths. + $bytes = $this->prng->choice( array_column( self::INVALID_UTF8_CLASSES, 0 ) ); + $at = $this->prng->int( 0, $length ); + $selector = substr( $selector, 0, $at ) . $bytes . substr( $selector, $at ); + break; } } diff --git a/tools/css-selector-fuzz/tests/self-check.php b/tools/css-selector-fuzz/tests/self-check.php index d6a9a19dec2d0..8d9df7e378b70 100644 --- a/tools/css-selector-fuzz/tests/self-check.php +++ b/tools/css-selector-fuzz/tests/self-check.php @@ -179,6 +179,24 @@ function check( bool $condition, string $message ): void { check( isset( $byte_classes[ $class_name ] ), "Invalid-utf8 variety: byte class {$class_name} was generated." ); } +// --- Mutated bucket: raw invalid-byte splicing ------------------------------- +// mutate() must be able to splice raw ill-formed UTF-8 into a selector at +// arbitrary byte offsets; these cases carry no AST expectation and exercise +// crash / scrub-notice / differential paths only. The marker bytes here can +// appear in NO rendered selector (the pools' multibyte characters use other +// lead bytes), so their presence proves the mutation operation fired. + +$mutated_with_invalid = 0; +for ( $seed = 1; $seed <= 200; $seed++ ) { + $prng = new Prng( (string) $seed, 'self-check-mutated-utf8' ); + $document = DocumentGenerator::generate( $prng->fork( 'doc' ) ); + $case = SelectorGenerator::generate( $prng->fork( 'sel' ), $document['pools'], null, 'mutated' ); + if ( false !== strpbrk( $case['selector'], "\xC0\xC1\xED\xF4\xF5\xFF" ) ) { + ++$mutated_with_invalid; + } +} +check( $mutated_with_invalid >= 10, "Mutated bucket splices raw invalid bytes ({$mutated_with_invalid} of 200 seeds)." ); + // --- Known-answer matching cases ------------------------------------------- $known_html = '' From 79691ca65461d3a7e6abdbcd974dd537363a1296 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 11 Jun 2026 22:02:07 +0200 Subject: [PATCH 184/634] CSS selector fuzz: Record the lexbor invalid-byte probe and refresh docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The handoff's open question — what does lexbor do with raw ill-formed UTF-8 in selectors — is resolved empirically: lexbor v3.0.0 accepts the bytes (no parse error) and replaces them with U+FFFD, but not per the WHATWG maximal-subpart rule CSS Syntax 3 §3.2 invokes. Truncated multi-byte sequences decode to one U+FFFD per byte (E2 8C to 2, spec 1; F0 9F 82 to 3, spec 1) and UTF-8-encoded surrogate halves decode permissively as a single unit (ED A0 80 to 1, spec 3); agreement on the other byte classes is coincidental overlap of the two algorithms. Drafted as UPSTREAM-ISSUES.md issue 6 with the probe table. On the document side lexbor keeps raw invalid bytes unchanged in the DOM (the same stance as the Tag Processor), so raw doc bytes match nothing in either engine. The differential needs no n/a gating for the invalid-utf8 bucket: the worker hands lexbor a canonical re-render of the post-scrub AST (pure ASCII), the same mechanism that sidesteps lexbor's other byte-level parsing bugs, so the bucket compares normally. NEXT-STEPS.md: the deferred scrub-coverage item resolves as implemented (bucket, splice, probe); the handoff's optional metamorphic relation parse(s) === parse(scrub(s)) is recorded as deliberately skipped (no public path bypasses from_selectors(), so it is near-tautological). New small open item from review: gen_chaos()'s whole-codepoint unicode branch is dead code (string-vs-key comparison), and its byte-sliced fallback is what makes chaos emit invalid UTF-8 organically (~15% of chaos cases) — making the branch live is a behavior decision now that deliberate ill-formed coverage exists. COVERAGE.md regenerated at the 3000-seed window: 396/424 = 93.4% raw, 408/424 = 96.2% effective. All 28 unreached lines accounted for: 12 phpdbg case-label artifacts, 12 defensive guards, the 2-line escape-decoder invalid-byte arm the scrub made unreachable through from_selectors() (pinned by PHPUnit), and 2 reachable lines this window misses (witnesses verified under phpdbg: '[' reaches the attribute length guard, '[a="b' reaches the string-to-EOF break). Stale 93.8%/96.8% references in NEXT-STEPS.md and FINDINGS.md updated to point at COVERAGE.md as the source of truth. Adversarial review: the same three hostile reviewers, all approved after two correction rounds. The issue-6 table was reproduced 10/10 rows against the pinned harness by two reviewers independently, the WHATWG column confirmed against an independent spec-transcribed decoder, and the ED-restricts-its-first-continuation-to-9F subpart reasoning checked against the Encoding Standard's ranges. The coverage table and uncovered-line list reproduced exactly; the case-label artifact demonstrated mechanistically (executable-but-unloggable label lines with executing bodies); the un-normalized-only claim verified in both directions (direct parse_ident hits the arm, from_selectors never does). Corrections from review: the issue-6 legend mislabeled U+FFFD counts as byte counts; stale coverage numbers contradicted the regenerated report; chaos's organic invalid UTF-8 was misattributed to pool corruption (it byte-slices its unicode alphabet); an 'all production moves' claim ignored mutated's residual organic corruption (~2% of pre-splice mutated cases). Gates: self-check OK; docs-only change — code identical to 8333b9347b, whose 5000-seed run was clean. --- tools/css-selector-fuzz/COVERAGE.md | 73 +++++++++++++------ tools/css-selector-fuzz/FINDINGS.md | 4 +- tools/css-selector-fuzz/NEXT-STEPS.md | 47 ++++++++++-- .../lexbor/UPSTREAM-ISSUES.md | 63 +++++++++++++++- 4 files changed, 153 insertions(+), 34 deletions(-) diff --git a/tools/css-selector-fuzz/COVERAGE.md b/tools/css-selector-fuzz/COVERAGE.md index 5279d0363201e..e7b715c0a8894 100644 --- a/tools/css-selector-fuzz/COVERAGE.md +++ b/tools/css-selector-fuzz/COVERAGE.md @@ -7,25 +7,27 @@ with phpdbg's opcode log over 3000 deterministic seeds: | file | covered / executable | % | |---|---|---| -| class-wp-css-attribute-selector.php | 106 / 116 | 91.4% | +| class-wp-css-attribute-selector.php | 108 / 119 | 90.8% | | class-wp-css-class-selector.php | 10 / 10 | 100% | | class-wp-css-complex-selector-list.php | 16 / 16 | 100% | | class-wp-css-complex-selector.php | 59 / 66 | 89.4% | | class-wp-css-compound-selector-list.php | 27 / 28 | 96.4% | | class-wp-css-compound-selector.php | 29 / 32 | 90.6% | | class-wp-css-id-selector.php | 12 / 12 | 100% | -| class-wp-css-selector-parser-matcher.php | 110 / 111 | 99.1% | +| class-wp-css-selector-parser-matcher.php | 120 / 124 | 96.8% | | class-wp-css-type-selector.php | 15 / 17 | 88.2% | -| **TOTAL** | **384 / 408** | **94.1%** | +| **TOTAL** | **396 / 424** | **93.4%** | -The 24 unreached lines are all accounted for below. Twelve are a phpdbg -measurement artifact (the code executes); the other twelve are defensive -guards that the public entry points cannot reach. Effective coverage of -reachable code is **396 / 408 = 97.1%**. +The 28 unreached lines are all accounted for below: twelve are a phpdbg +measurement artifact (the code executes), twelve are defensive guards the +public entry points cannot reach, two are the escape decoder's +invalid-byte arm that the input scrub made unreachable through +`from_selectors()`, and two are reachable lines this seed window happens +to miss. Counting the artifact lines as covered, effective coverage is +**408 / 424 = 96.2%**. -(Executable-line totals grew from 401 to 408 with the EOF-escape and -EOF-auto-close changes; two parser-matcher EOF guards that used to be -unreachable defensive lines are now genuinely exercised — see below.) +(Executable-line totals grew from 408 to 424 with the case-insensitive +attribute value list and the invalid-UTF-8 scrub changes.) ## phpdbg `case`-label artifact (12 lines — code executes) @@ -36,8 +38,8 @@ lexbor differential + self-check confirm the corresponding behavior). These are not real gaps: - `class-wp-css-attribute-selector.php` - - 309, 313, 317, 321, 325 — the `~= |= ^= $= *=` matcher operators. - - 350, 351, 356, 357 — the `i`/`I`/`s`/`S` case modifiers. + - 378, 382, 386, 390, 394 — the `~= |= ^= $= *=` matcher operators. + - 419, 420, 425, 426 — the `i`/`I`/`s`/`S` case modifiers. - `class-wp-css-compound-selector.php` - 120, 122, 124 — the `.` / `#` / `[` subclass-selector dispatch. @@ -46,7 +48,7 @@ are not real gaps: These are internal precondition checks that the calling code already guarantees, or branches for grammar the parser never emits: -- `class-wp-css-attribute-selector.php:282` — `return null` when the first +- `class-wp-css-attribute-selector.php:351` — `return null` when the first byte is not `[`. `parse()` is only ever called by `parse_subclass_selector()` *after* it has matched `[`, so the guard never fires. @@ -54,11 +56,11 @@ guarantees, or branches for grammar the parser never emits: "unsupported combinator" arm in the match walker. The parser only ever stores `' '` (descendant) or `'>'` (child) combinators, so the match-time default arm is dead defensively. -- `class-wp-css-compound-selector-list.php:87` — `return false` when the +- `class-wp-css-compound-selector-list.php:107` — `return false` when the processor is not on a `#tag` token. `select()` only invokes matching while positioned on a tag; reachable only by calling `matches()` directly off a non-tag token. -- `class-wp-css-selector-parser-matcher.php:351` — +- `class-wp-css-selector-parser-matcher.php:375` — `next_two_are_valid_escape()` EOF guard; every caller either bound-checks first or only calls it on a known backslash byte. - `class-wp-css-type-selector.php:45` — `return false` when `get_tag()` is @@ -66,11 +68,30 @@ guarantees, or branches for grammar the parser never emits: - `class-wp-css-type-selector.php:75` — `parse()` EOF guard; the compound parser checks `offset < strlen` before calling. -Two guards documented here in earlier revisions are now genuinely covered: -the `parse_string()` EOF guard and the -`check_if_three_code_points_would_start_an_ident_sequence()` EOF guard are -both reached since EOF auto-close lets `[a=` call the value parsers at the -end of input. +## Un-normalized input only (2 lines — pinned by PHPUnit) + +- `class-wp-css-selector-parser-matcher.php:287–288` — the escape decoder's + invalid-byte arm (consume the maximal subpart `_wp_scan_utf8()` reported, + return one U+FFFD). The invalid-UTF-8 scrub in `normalize_selector_input()` + made this arm structurally unreachable through `from_selectors()` — the + fuzzer's only entry point — and it exists for direct `parse()` callers + with un-normalized input. The escape pins in + `tests/phpunit/tests/html-api/wpCssSelectorParserMatcher.php` exercise it + for every invalid-byte decode class under the U+2603 canary. + +## Reachable, but missed by this seed window (2 lines) + +Both lines are demonstrably reachable (witnesses verified directly under +phpdbg) but sit behind enough generator coin flips that a fixed 3000-seed +window may or may not sample them; earlier revisions of this report saw +them flicker in and out across windows: + +- `class-wp-css-attribute-selector.php:345` — the `[x` minimum-length + guard; witness: `[` (also `.a[`, `a[`) at the end of input. +- `class-wp-css-selector-parser-matcher.php:149` — `parse_string()`'s + break when plain string content runs to end of input; witness: `[a="b` + (the `eof-truncated` edge-escape kind reaches it only when its quote-drop + and no-backslash coins both land, ~1 expected case per 3000 seeds). ## Notes on what raised coverage @@ -82,9 +103,17 @@ end of input. kind covers the EOF auto-close paths in the attribute parser, including unterminated strings (with and without a trailing "do nothing" backslash, which keeps the `parse_string` backslash-at-EOF arm exercised). +- The `invalid-utf8` bucket and the `mutated` bucket's raw-byte splice + drive the `wp_scrub_utf8()` replacement branch and its + `_doing_it_wrong()` notice in `normalize_selector_input()` + deterministically (previously hit only organically — `chaos` + byte-slicing its multibyte `unicode` alphabet, `mutated` corrupting the + pools' few multibyte characters), and the splice makes the + unparseable-and-invalid-UTF-8 notice ordering in the worker hot. - A few `invalid`-bucket templates (`[a=`, `[a~`, `[a="bc`, `a.`) reach attribute / string / class parse guards that random structural generation - rarely lands on. With them the per-file numbers above are **deterministic** + rarely lands on. With them the per-file numbers above are stable at the documented 3000-seed window (e.g. `class-wp-css-class-selector.php` reaches 10/10 reliably rather than depending on whether a bare `.` happened - to be sampled). + to be sampled) — apart from the two borderline-frequency lines listed + above. diff --git a/tools/css-selector-fuzz/FINDINGS.md b/tools/css-selector-fuzz/FINDINGS.md index 5e650aac73549..ca408ad84c591 100644 --- a/tools/css-selector-fuzz/FINDINGS.md +++ b/tools/css-selector-fuzz/FINDINGS.md @@ -163,8 +163,8 @@ Implemented and validated: - **Parser-derived oracle tree** (`TreeCapture`): the processor's own parse is ground truth, so **wild / restructured HTML** and **`` fragments** are fuzzed, not only clean trees. -- **Line coverage** measured (93.8%, see `COVERAGE.md`; 96.8% of reachable - code, remainder justified). +- **Line coverage** measured (93.4%, see `COVERAGE.md` — the source of truth + for current numbers; 96.2% effective, remainder justified). - **Automatic minimizer** (`minimize.php`): delta-debugs selector and HTML to a minimal reproducer preserving a chosen signature. diff --git a/tools/css-selector-fuzz/NEXT-STEPS.md b/tools/css-selector-fuzz/NEXT-STEPS.md index b84ec6130f47a..dd3f52d8e774b 100644 --- a/tools/css-selector-fuzz/NEXT-STEPS.md +++ b/tools/css-selector-fuzz/NEXT-STEPS.md @@ -2,7 +2,8 @@ > **Status: all seven work items below are implemented and validated** (see > `README.md`, `COVERAGE.md`, `FINDINGS.md`). The acceptance bar is met: -> coverage measured (93.8%; 96.8% of reachable code, remainder justified); +> coverage measured (93.4%; 96.2% effective — `COVERAGE.md` is the source +> of truth for the current numbers, remainder justified); > three oracles agree on no-quirks supported cases with every divergence > triaged; metamorphic invariants passing; combinator positive-match rate > raised from 14.5% to ~68% (path-directed bucket); minimizer working; a clean @@ -148,15 +149,45 @@ > its quadratic tail were removed by the scrub implementation — see the > invalid-UTF-8 policy entry above.) > +> **Fuzzer coverage for the scrub surface — IMPLEMENTED (2026-06-11):** +> the deferred coverage work for the invalid-UTF-8 scrub landed in three +> pieces. (1) A dedicated `invalid-utf8` generator bucket injects raw +> ill-formed sequences into class/ID/attribute-name idents and quoted +> string operands and carries the post-scrub AST; the per-class maximal- +> subpart U+FFFD counts are pinned independently of `wp_scrub_utf8()` +> (self-check additionally duplicates the class names and byte values, so +> a deleted or drifted table entry fails instead of shrinking the +> assertion). (2) A `mutated`-bucket splice kind inserts raw ill-formed +> sequences at arbitrary byte offsets — no expectations, but it makes the +> worker's invalid-UTF-8 rejection branch hot (scrub + two `select()` +> notices), which no other bucket reached. (3) The explicit lexbor probe: +> lexbor accepts raw invalid selector bytes and replaces them with U+FFFD, +> but NOT per the WHATWG maximal-subpart rule — one U+FFFD per byte for +> truncated sequences (`E2 8C` → 2, spec 1) and one per whole sequence for +> UTF-8-encoded surrogate halves (`ED A0 80` → 1, spec 3) — drafted as +> `lexbor/UPSTREAM-ISSUES.md` issue 6. The differential is unaffected and +> stays live for the bucket: it feeds lexbor the canonical re-render of +> the post-scrub AST (escaped, pure ASCII), the same mechanism that +> sidesteps lexbor's other byte-level parsing bugs. Doc-side observation: +> lexbor keeps raw invalid bytes in the DOM unchanged (same stance as the +> Tag Processor), so raw doc bytes match nothing in either engine. The +> handoff's optional metamorphic relation `parse(s) === parse(scrub(s))` +> was skipped deliberately: it is near-tautological (it could only catch +> a `from_selectors()` bypass, and no public path bypasses it). +> > **Still open from the original follow-up list:** the tooling items in > this file's hardening notes (self-check decoupling, class-NUL injection, -> vacuous-assertion rate, quirks-mode single-oracle gap), plus deferred -> fuzzer coverage for the scrub surface (dedicated invalid-UTF-8 generator -> bucket with maximal-subpart AST expectations, raw-byte mutation class, -> explicit lexbor invalid-byte probe — handoff drafted 2026-06-11; note -> the chaos/mutated buckets already produce invalid-UTF-8 selectors -> organically and lexbor agreed with the scrubbed results across a clean -> 5000-seed run). +> vacuous-assertion rate, quirks-mode single-oracle gap). New small item +> from the 2026-06-11 review: `gen_chaos()`'s whole-codepoint `unicode` +> branch is dead code — it compares the alphabet *string* against the key +> `'unicode'` after the value lookup already happened — so the unicode +> alphabet is byte-sliced by the generic fallback instead. That slicing is +> what makes chaos emit invalid UTF-8 organically (~15% of chaos cases), +> so making the branch live is a behavior decision, not just a cleanup: +> it would remove chaos's organic ill-formed-byte production, leaving the +> deliberate paths (`invalid-utf8` bucket, `mutated` splice) plus +> `mutated`'s residual organic corruption of pool multibyte characters +> (~2% of mutated cases even without the splice). Repo: `/Users/jonsurrell/a8c/wordpress-develop/html-css-fuzz`, branch `html-css-fuzz` (trunk + merged `html-api/add-css-selector-parser`). diff --git a/tools/css-selector-fuzz/lexbor/UPSTREAM-ISSUES.md b/tools/css-selector-fuzz/lexbor/UPSTREAM-ISSUES.md index 9ec23e414dcfa..ef167f2814959 100644 --- a/tools/css-selector-fuzz/lexbor/UPSTREAM-ISSUES.md +++ b/tools/css-selector-fuzz/lexbor/UPSTREAM-ISSUES.md @@ -1,10 +1,12 @@ # lexbor — draft upstream bug reports -Five spec-conformance bugs in liblexbor's CSS selectors support, found while +Six spec-conformance bugs in liblexbor's CSS selectors support, found while using lexbor as a differential oracle for the WordPress HTML-API CSS selector fuzzer (`tools/css-selector-fuzz/`). Issues 1–3 were re-verified directly against the harness on 2026-06-10; issues 4–5 surfaced during the WP -conformance-fix session and were re-verified on 2026-06-11. +conformance-fix session and were re-verified on 2026-06-11; issue 6 came out +of the explicit invalid-byte probe for the WP scrub coverage work +(2026-06-11). - **Pinned version:** lexbor v3.0.0 (`2ae88a1c6b52`), built by `tools/css-selector-fuzz/lexbor/build.sh`. @@ -217,3 +219,60 @@ a feature request rather than a bug if lexbor considers document-language selector rules out of scope for its selectors module — but lexbor is an HTML engine and browsers uniformly implement the folding, so matching against HTML documents diverges from every browser without it. + +## Issue 6 — ill-formed UTF-8 in selectors is not decoded per the Encoding Standard + +CSS Syntax Level 3 decodes the input byte stream via the Encoding Standard +before tokenizing: + +> To decode bytes, ... Otherwise, decode bytes with fallback encoding utf-8. +> — https://www.w3.org/TR/css-syntax-3/#input-byte-stream (§3.2) + +The Encoding Standard's UTF-8 decoder replaces each **maximal subpart of an +ill-formed subsequence** with a single U+FFFD (the boundaries follow the +decoder's byte-range tables; see also Unicode §3.9 "U+FFFD Substitution of +Maximal Subparts"): + +> https://encoding.spec.whatwg.org/#utf-8-decoder + +lexbor accepts raw ill-formed bytes in selectors (no parse error) and +replaces them with U+FFFD, but with different boundaries: a truncated +multi-byte sequence yields one U+FFFD **per byte** instead of one per +maximal subpart, and a UTF-8-encoded surrogate half (`ED A0 80`–`ED BF +BF`) is decoded permissively as a **single unit** yielding one U+FFFD +instead of three. Verified at v3.0.0 by matching raw-byte class selectors +against elements whose class attributes contain literal U+FFFD runs +(`
` = 1×U+FFFD ... `
` = 4×U+FFFD; +`�` below is U+FFFD, U+FFFD counts in parentheses): + +| selector bytes | WHATWG decode | lexbor | +|-----------------------|----------------|----------------| +| `.ab` | `a�b` (1) ✅ | `a��b` (2) ❌ | +| `.ab` | `a�b` (1) ✅ | `a���b` (3) ❌ | +| `.ab` | `a���b` (3) ✅ | `a�b` (1) ❌ | +| `.ab` | `a���b` (3) ✅ | `a�b` (1) ❌ | +| `.a<80>b` | `a�b` (1) | `a�b` (1) ✅ | +| `.ab` | `a�b` (1) | `a�b` (1) ✅ | +| `.ab` | `a��b` (2) | `a��b` (2) ✅ | +| `.ab` | `a���b` (3) | `a���b` (3) ✅ | +| `.ab` | `a����b` (4) | `a����b` (4) ✅ | + +The agreeing rows are controls where per-byte replacement coincides with +the maximal-subpart rule (lone continuation/lead bytes, overlongs whose +subparts are all single bytes, beyond-U+10FFFF). The same behavior applies +inside string tokens (`[x="p<80>q"]` matches `x="p�q"`). Two truncated +sequences are exactly where the algorithms separate: `E2 8C` is **one** +maximal subpart (E2 accepts two continuations and 8C is a valid first +continuation), while `ED A0` is **not** a subpart at all (ED restricts its +first continuation to 80–9F), so `ED A0 80` is three. + +Notes for the filing agent: browsers only exercise this decode through the +stylesheet byte stream (JS `querySelectorAll` strings are already UTF-16), +so compare against an external stylesheet with raw bytes, or against +another Encoding Standard implementation (e.g. `TextDecoder('utf-8')`, +whose output for the byte sequences above shows the maximal-subpart +boundaries directly). Document-side context: lexbor stores raw ill-formed +bytes from the HTML byte stream unchanged in the DOM (a raw `<80>` in a +class attribute is matched by no selector, not even one with the same raw +bytes), so the repro must put literal U+FFFD characters in the document +and raw bytes only in the selector. From 42c267a642ae46bac2298bf35f11e8059e74b352 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 11 Jun 2026 23:48:05 +0200 Subject: [PATCH 185/634] Build lexbor harness from master --- tools/css-selector-fuzz/NEXT-STEPS.md | 6 +++--- tools/css-selector-fuzz/README.md | 10 ++++----- .../lexbor/UPSTREAM-ISSUES.md | 12 +++++------ tools/css-selector-fuzz/lexbor/build.sh | 21 ++++++++++++------- tools/css-selector-fuzz/lexbor/harness.c | 4 ++-- tools/css-selector-fuzz/lib/LexborOracle.php | 4 ++-- 6 files changed, 31 insertions(+), 26 deletions(-) diff --git a/tools/css-selector-fuzz/NEXT-STEPS.md b/tools/css-selector-fuzz/NEXT-STEPS.md index dd3f52d8e774b..36988221a90fe 100644 --- a/tools/css-selector-fuzz/NEXT-STEPS.md +++ b/tools/css-selector-fuzz/NEXT-STEPS.md @@ -292,9 +292,9 @@ case-sensitively in no-quirks (`WP_HTML_Tag_Processor::is_quirks_mode()`); type names are always case-insensitive. Do NOT trust lexbor on quirks-mode case behavior. Restrict the lexbor differential to **no-quirks documents** (emit ``), and keep `ReferenceMatcher` as the authority for the -quirks-mode path. Pin the exact lexbor version used and note whether #368 is -fixed in it. Re-evaluate enabling quirks comparison only after verifying lexbor's -behavior against that issue. +quirks-mode path. Record the exact lexbor master commit used and note whether +#368 is fixed in it. Re-evaluate enabling quirks comparison only after verifying +lexbor's behavior against that issue. - Also surface (don't auto-fail) **attribute default case-insensitivity**: Selectors-4/HTML define a set of attributes matched case-insensitively by diff --git a/tools/css-selector-fuzz/README.md b/tools/css-selector-fuzz/README.md index f0abff0934da5..cfcfda666cf7e 100644 --- a/tools/css-selector-fuzz/README.md +++ b/tools/css-selector-fuzz/README.md @@ -106,9 +106,9 @@ produces the same document, the same selector, and the same verdict. ## lexbor harness Build with `sh tools/css-selector-fuzz/lexbor/build.sh` (clones and builds -liblexbor, pinned to v3.0.0 = `2ae88a1c6b52`). The worker auto-detects the -binary at `tools/css-selector-fuzz/lexbor/harness` and reports per-batch -tallies, persisted to `state.json` under `lexbor`: +liblexbor from upstream `master`; the build script prints the exact commit). +The worker auto-detects the binary at `tools/css-selector-fuzz/lexbor/harness` +and reports per-batch tallies, persisted to `state.json` under `lexbor`: - `compared` — the differential ran and matched fid-multisets. - `tree-gated` — WP and lexbor built different trees; differential skipped. @@ -119,9 +119,9 @@ tallies, persisted to `state.json` under `lexbor`: a loud warning if these appear after the harness had run, so a third oracle that dies mid-run cannot hide behind a green run. -Known lexbor issues compensated for at this pin: +Known lexbor issues compensated for when present: -- [#368](https://github.com/lexbor/lexbor/issues/368) (open at v3.0.0): +- [#368](https://github.com/lexbor/lexbor/issues/368): class and `#id` selectors match ASCII case-insensitively even in no-quirks documents (`[id=…]` attribute matching is correctly case-sensitive). Detected by a startup probe; when present, lexbor is diff --git a/tools/css-selector-fuzz/lexbor/UPSTREAM-ISSUES.md b/tools/css-selector-fuzz/lexbor/UPSTREAM-ISSUES.md index ef167f2814959..40c2ccb80f97c 100644 --- a/tools/css-selector-fuzz/lexbor/UPSTREAM-ISSUES.md +++ b/tools/css-selector-fuzz/lexbor/UPSTREAM-ISSUES.md @@ -8,8 +8,9 @@ conformance-fix session and were re-verified on 2026-06-11; issue 6 came out of the explicit invalid-byte probe for the WP scrub coverage work (2026-06-11). -- **Pinned version:** lexbor v3.0.0 (`2ae88a1c6b52`), built by - `tools/css-selector-fuzz/lexbor/build.sh`. +- **Default build target:** lexbor upstream `master`, built by + `tools/css-selector-fuzz/lexbor/build.sh`. Record the exact commit printed + by the build script when verifying any issue. - **Upstream repo:** https://github.com/lexbor/lexbor - **Already filed upstream — do NOT refile:** [#368](https://github.com/lexbor/lexbor/issues/368) (class/`#id` selectors @@ -17,10 +18,9 @@ of the explicit invalid-byte probe for the WP scrub coverage work ## Instructions for the filing agent -1. **Re-verify at lexbor master first.** The pin is v3.0.0; any of these may - already be fixed. Edit `build.sh` to build master (or clone/build manually) - and re-run the repros below. Only file what still reproduces, and say in - the report which commit you tested. +1. **Re-verify at current lexbor master first.** Any of these may already be + fixed. Run `build.sh` and re-run the repros below. Only file what still + reproduces, and say in the report which commit you tested. 2. **Search for duplicates** before filing (suggested queries: `~=`, `attr-modifier`, `case insensitive modifier`, `ident code point`, `U+00B7`, `non-ascii`, `EOF`, `unclosed`, `simple block`, diff --git a/tools/css-selector-fuzz/lexbor/build.sh b/tools/css-selector-fuzz/lexbor/build.sh index 186a7e5b703b6..a1471675bc815 100644 --- a/tools/css-selector-fuzz/lexbor/build.sh +++ b/tools/css-selector-fuzz/lexbor/build.sh @@ -2,10 +2,11 @@ # # Builds the lexbor differential harness. # -# Pinned lexbor version: v3.0.0 (2ae88a1c6b5261830eff73ee12bb3cdf805f3cfe). +# Builds against upstream lexbor master. The exact commit is printed after +# each build and recorded in the build cache. # Note: lexbor issue #368 ("Class/ID selectors are ASCII case-insensitive -# even in no-quirks mode") is still OPEN at this version; the PHP adapter -# detects it at startup and compensates (see LexborOracle.php). +# even in no-quirks mode") is detected at startup and compensated for when +# present (see LexborOracle.php). # # Usage: # sh tools/css-selector-fuzz/lexbor/build.sh [lexbor-src-dir] @@ -16,27 +17,31 @@ set -e HERE="$(cd "$(dirname "$0")" && pwd)" SRC="${1:-/tmp/lexbor-src}" -PIN="2ae88a1c6b5261830eff73ee12bb3cdf805f3cfe" +BRANCH="master" if [ ! -d "$SRC" ]; then echo "Cloning lexbor into $SRC ..." git clone https://github.com/lexbor/lexbor "$SRC" fi -git -C "$SRC" checkout --quiet "$PIN" +git -C "$SRC" fetch --quiet origin "$BRANCH" +git -C "$SRC" checkout --quiet -B "$BRANCH" "origin/$BRANCH" +REV="$(git -C "$SRC" rev-parse --verify HEAD)" +STAMP="$SRC/build/.lexbor-rev" -if [ ! -f "$SRC/build/liblexbor_static.a" ]; then - echo "Building liblexbor_static ..." +if [ ! -f "$SRC/build/liblexbor_static.a" ] || [ ! -f "$STAMP" ] || [ "$(cat "$STAMP")" != "$REV" ]; then + echo "Building liblexbor_static ($BRANCH $REV) ..." mkdir -p "$SRC/build" cd "$SRC/build" cmake -DCMAKE_BUILD_TYPE=Release -DLEXBOR_BUILD_SHARED=OFF \ -DLEXBOR_BUILD_STATIC=ON -DLEXBOR_BUILD_TESTS=OFF \ -DLEXBOR_BUILD_EXAMPLES=OFF .. > /dev/null make -j8 lexbor_static > /dev/null + printf '%s\n' "$REV" > "$STAMP" cd "$HERE" fi cc -O2 -Wall -Wextra -o "$HERE/harness" "$HERE/harness.c" \ -I "$SRC/source" "$SRC/build/liblexbor_static.a" -echo "Built $HERE/harness (lexbor $PIN)" +echo "Built $HERE/harness (lexbor $BRANCH $REV)" diff --git a/tools/css-selector-fuzz/lexbor/harness.c b/tools/css-selector-fuzz/lexbor/harness.c index ebd3aa32f4b4a..582c387a92f86 100644 --- a/tools/css-selector-fuzz/lexbor/harness.c +++ b/tools/css-selector-fuzz/lexbor/harness.c @@ -21,8 +21,8 @@ * for elements without one (matching the fuzzer's placeholder convention). * Tags are ASCII-uppercased. * - * Build: see build.sh next to this file. Pinned lexbor version recorded - * there and in the fuzzer README. + * Build: see build.sh next to this file. The script builds upstream lexbor + * master and prints the exact commit used. */ #include diff --git a/tools/css-selector-fuzz/lib/LexborOracle.php b/tools/css-selector-fuzz/lib/LexborOracle.php index a7a6864aa62ab..2dd74c9e92e54 100644 --- a/tools/css-selector-fuzz/lib/LexborOracle.php +++ b/tools/css-selector-fuzz/lib/LexborOracle.php @@ -19,7 +19,7 @@ * ASCII case-insensitively even in no-quirks mode ( attribute selectors * like [id=x] are correctly case-sensitive ). Detected by probe at startup; * when present, lexbor is compared against the reference matcher run with - * quirks-style class/ID folding. Open at the pinned v3.0.0. + * quirks-style class/ID folding. */ class LexborOracle { @@ -62,7 +62,7 @@ public static function available(): bool { return true; } - /** Whether the pinned lexbor exhibits issue #368 ( class/ID case folding ). */ + /** Whether the built lexbor exhibits issue #368 ( class/ID case folding ). */ public static function has_issue_368(): bool { return self::$issue368; } From 9d1129c2135266461280ae4d113edcf6bcc42779 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 12 Jun 2026 08:42:56 +0200 Subject: [PATCH 186/634] CSS selector fuzz: harden fuzzer follow-ups --- tools/css-selector-fuzz/FINDINGS.md | 7 +- tools/css-selector-fuzz/NEXT-STEPS.md | 43 +++---- tools/css-selector-fuzz/README.md | 44 ++++--- .../lib/DocumentGenerator.php | 52 +++++++- tools/css-selector-fuzz/lib/LexborOracle.php | 32 ++++- .../lib/ReferenceMatcher.php | 20 +-- .../lib/SelectorGenerator.php | 5 +- .../lib/WildDocumentGenerator.php | 27 +++- tools/css-selector-fuzz/lib/Worker.php | 65 ++++++++-- tools/css-selector-fuzz/runner.php | 59 ++++++++- tools/css-selector-fuzz/tests/self-check.php | 119 ++++++++++++++++-- 11 files changed, 369 insertions(+), 104 deletions(-) diff --git a/tools/css-selector-fuzz/FINDINGS.md b/tools/css-selector-fuzz/FINDINGS.md index ca408ad84c591..e58b256962364 100644 --- a/tools/css-selector-fuzz/FINDINGS.md +++ b/tools/css-selector-fuzz/FINDINGS.md @@ -17,9 +17,10 @@ completely clean, and the lexbor differential (third independent oracle) agreed with the reference matcher on every compared no-quirks case (0 `lexbor-divergence`). Caveats on the strength of that agreement: roughly half of the `compared` cases (and ~62% of all match assertions across buckets) are vacuous `[] == []`; -quirks-mode class/ID matching is excluded from the differential (lexbor #368) -and so rests on `ReferenceMatcher` alone. See `README.md` for the full -disclosure. +older lexbor builds with #368 exclude quirks-mode class/ID matching from the +differential, though current harnesses include it when the startup probe reports +reliable class/#id behavior in both no-quirks and quirks mode. See `README.md` +for the full disclosure. Reproduce any case: `php tools/css-selector-fuzz/replay.php --selector '' [--html '']`. Auto-minimize a failing seed: `php tools/css-selector-fuzz/minimize.php --seed ` diff --git a/tools/css-selector-fuzz/NEXT-STEPS.md b/tools/css-selector-fuzz/NEXT-STEPS.md index 36988221a90fe..8746f5493c529 100644 --- a/tools/css-selector-fuzz/NEXT-STEPS.md +++ b/tools/css-selector-fuzz/NEXT-STEPS.md @@ -14,16 +14,17 @@ > (`CSS selector:` commits `7419a9fef6` / `0cefeb2fc8` / `16d03e2c5f`), each > with PHPUnit regression tests. A post-fix 5000-seed run is clean. > -> **Open follow-up hardening (post-review):** `tests/self-check.php` runs its -> parse-expectation assertions over a fixed seed window (1–400) that, against -> an *unfixed* core, dodges the known core bugs only by seed luck. On this -> branch the bugs are fixed so the collision risk is gone, but the hazard -> returns whenever the tooling runs against a core without the fixes (e.g. -> cherry-picked onto trunk before the fixes land) or when a future unfixed bug -> is found. Decouple self-check from unfixed core bugs — e.g. allowlist known -> signatures in the parse-expectation loop — as a standalone hardening. This is -> worth doing on its own (it makes self-check robust to *any* future generator -> change) and is the prerequisite for randomized class-NUL document injection. +> **Fuzzer-side follow-up hardening implemented (2026-06-12):** +> `tests/self-check.php` now allowlists known core parse-bug signatures in its +> fixed seed-window parse-expectation loop, while unknown mismatches still fail. +> The safe and wild document generators now inject NUL into random class tokens +> and expose the decoded U+FFFD token to class-selector generation, without +> leaking raw class values into the generic attribute-value pool. The lexbor +> differential includes quirks documents whenever the startup probe confirms +> class/#id behavior in both no-quirks and quirks mode (local master-built +> harness `3a2d595fe8c50e5076ac79c02b2ded79a777bb52` passes), and `runner.php` +> reports per-bucket/per-target vacuous and non-vacuous match assertion rates +> under `matchStats`. > > **Candidate finding 4 — FIXED:** per CSS Syntax 3 §4.3.8, `\` followed by > EOF is a valid escape (EOF is not a newline), and §4.3.7 says consuming it @@ -175,19 +176,15 @@ > was skipped deliberately: it is near-tautological (it could only catch > a `from_selectors()` bypass, and no public path bypasses it). > -> **Still open from the original follow-up list:** the tooling items in -> this file's hardening notes (self-check decoupling, class-NUL injection, -> vacuous-assertion rate, quirks-mode single-oracle gap). New small item -> from the 2026-06-11 review: `gen_chaos()`'s whole-codepoint `unicode` -> branch is dead code — it compares the alphabet *string* against the key -> `'unicode'` after the value lookup already happened — so the unicode -> alphabet is byte-sliced by the generic fallback instead. That slicing is -> what makes chaos emit invalid UTF-8 organically (~15% of chaos cases), -> so making the branch live is a behavior decision, not just a cleanup: -> it would remove chaos's organic ill-formed-byte production, leaving the -> deliberate paths (`invalid-utf8` bucket, `mutated` splice) plus -> `mutated`'s residual organic corruption of pool multibyte characters -> (~2% of mutated cases even without the splice). +> **Still open:** `gen_chaos()`'s whole-codepoint `unicode` branch is dead +> code — it compares the alphabet *string* against the key `'unicode'` after +> the value lookup already happened — so the unicode alphabet is byte-sliced +> by the generic fallback instead. That slicing is what makes chaos emit +> invalid UTF-8 organically (~15% of chaos cases), so making the branch live +> is a behavior decision, not just a cleanup: it would remove chaos's organic +> ill-formed-byte production, leaving the deliberate paths (`invalid-utf8` +> bucket, `mutated` splice) plus `mutated`'s residual organic corruption of +> pool multibyte characters (~2% of mutated cases even without the splice). Repo: `/Users/jonsurrell/a8c/wordpress-develop/html-css-fuzz`, branch `html-css-fuzz` (trunk + merged `html-api/add-css-selector-parser`). diff --git a/tools/css-selector-fuzz/README.md b/tools/css-selector-fuzz/README.md index cfcfda666cf7e..655d52293cc29 100644 --- a/tools/css-selector-fuzz/README.md +++ b/tools/css-selector-fuzz/README.md @@ -45,6 +45,9 @@ produces the same document, the same selector, and the same verdict. path-directed generation is that the *combinator/breadcrumb* walker — the part most likely to harbor a matching bug — is now exercised with real depth, not that every assertion is non-vacuous. + `runner.php` persists per-bucket/per-target match assertion counts and + vacuous/non-vacuous rates under `matchStats` in `state.json`, so this + distribution is reported on every run instead of relying on stale notes. - `unsupported` — valid CSS the API intentionally rejects (pseudo-classes and -elements, `+`/`~`/`||` combinators, namespaces, non-type context selectors); must not parse. @@ -88,15 +91,16 @@ produces the same document, the same selector, and the same verdict. Skipped for ASTs containing invalid UTF-8 (reachable only from chaos/mutated inputs), which the renderer cannot round-trip. - lexbor differential (third, independent oracle; requires the harness — - see below): on no-quirks documents whose selector parsed, a canonical + see below): on full-document cases whose selector parsed, a canonical re-render of the verified AST is matched by liblexbor and compared, - as a multiset of fids, against the reference matcher. Gated on WP and + as a multiset of fids, against the reference matcher. Quirks documents + participate only when the startup probe confirms lexbor's class/#id + folding behavior in both no-quirks and quirks mode. Gated on WP and lexbor building the same element tree (fid/tag/ancestry), so it tests - the selector layer, not tree construction. Verdicts: `lexbor-divergence` - (lexbor ≠ reference) is a fuzzer-oracle problem; `match-mismatch-html` - with no accompanying divergence means reference == lexbor ≠ WP — a - high-confidence WP finding. (Roughly half of `compared` cases are - themselves non-vacuous; the rest assert `[] == []` on both engines.) + the selector layer, not tree construction. Verdicts: + `lexbor-divergence` (lexbor ≠ reference) is a fuzzer-oracle problem; + `match-mismatch-html` with no accompanying divergence means reference + == lexbor ≠ WP — a high-confidence WP finding. - Repeating a case yields a byte-identical result digest (determinism). Note the digest covers the WP-under-test surface (selector, html, parse-nullness, ASTs, failure invariants) but **not** the lexbor @@ -112,7 +116,8 @@ and reports per-batch tallies, persisted to `state.json` under `lexbor`: - `compared` — the differential ran and matched fid-multisets. - `tree-gated` — WP and lexbor built different trees; differential skipped. -- `skipped-quirks` / `skipped-utf8` — quirks document / non-UTF-8 AST. +- `skipped-quirks` / `skipped-utf8` — quirks document while lexbor class/#id + case behavior is not trusted / non-UTF-8 AST. - `n/a` — the differential does not apply (unparseable selector, fragment, no captured tree). - `unavailable` / `error` — the harness was missing or died. The runner prints @@ -127,14 +132,9 @@ Known lexbor issues compensated for when present: case-sensitive). Detected by a startup probe; when present, lexbor is compared against the reference matcher run with quirks-style class/ID folding, and quirks-mode documents are excluded from the differential - entirely. **Consequence — a real coverage hole:** quirks-mode class/ID - matching has no independent third oracle. `ReferenceMatcher` is the sole - authority there, and it encodes the same "ASCII-only case fold in quirks" - reading WP does (both fold via ASCII-only lowercasing), so if that reading - is wrong they would be wrong identically and lexbor — the one engine that - could disagree — is excluded. This is inherent to lexbor #368 being open; - it is the weakest-covered behavior in the suite and is called out here - rather than papered over. + entirely. The same startup probe also checks class and `#id` selectors in + quirks mode; only when all four probes pass is quirks-mode class/ID matching + included in the differential. - lexbor rejects uppercase `I`/`S` attribute-selector modifiers, and its non-ASCII ident-codepoint table omits U+00B7 and U+00C0–U+00F6 (it starts at U+00F8), rejecting e.g. `.Über` while accepting `.über`. @@ -159,13 +159,11 @@ The match oracle's independence differs between class and attribute selectors: splits on ASCII whitespace and folds NUL → U+FFFD per token; `ReferenceMatcher::class_matches()` reimplements that independently (and is pinned against `class_list()` on NUL/FF boundary inputs by `self-check.php`). - The random document generators do **not** emit control bytes inside class - values, so the *randomized* fuzzing never exercises this boundary — it is - covered only by the deterministic self-check cases. Randomized document-side - injection is deliberately deferred: adding it to the hot path perturbs the - deterministic self-check seed space enough to surface the known Bug 3, which - would first require decoupling `self-check.php` from the unfixed core bugs. - A worthwhile, scoped future improvement. + The safe and wild random document generators now inject NUL into class + tokens occasionally and expose the decoded U+FFFD token to class-selector + generation. Raw class attribute values are intentionally kept out of the + generic `attrValues` pool so attribute-selector generation does not inherit + class-list-only decoding semantics. - **Attribute values are matched through a single shared read.** Both WP's attribute matcher and `ReferenceMatcher::attr_matches()` read the same `get_attribute()` output, so a value-decoding bug there would be shared and diff --git a/tools/css-selector-fuzz/lib/DocumentGenerator.php b/tools/css-selector-fuzz/lib/DocumentGenerator.php index 20e6e99607421..20da2825b6ed2 100644 --- a/tools/css-selector-fuzz/lib/DocumentGenerator.php +++ b/tools/css-selector-fuzz/lib/DocumentGenerator.php @@ -314,7 +314,7 @@ private function random_attrs(): array { } $this->pools['attrNames'][] = ascii_strtolower( $name ); - if ( is_string( $value ) ) { + if ( is_string( $value ) && 'class' !== $lower ) { $this->pools['attrValues'][] = $value; } @@ -328,9 +328,12 @@ private function random_class_value(): string { $count = $this->prng->int( 1, 4 ); $classes = array(); for ( $i = 0; $i < $count; $i++ ) { - $class = $this->random_word( true ); - $classes[] = $class; - $this->pools['classes'][] = $class; + $class = $this->random_word( true ); + $raw_class = $this->maybe_inject_class_nul( $class ); + $classes[] = $raw_class; + foreach ( self::class_tokens( $raw_class ) as $token ) { + $this->pools['classes'][] = $token; + } } $ws = array( ' ', ' ', ' ', "\t", "\n", "\f", ' ' ); @@ -347,6 +350,23 @@ private function random_class_value(): string { return $value; } + private function maybe_inject_class_nul( string $class ): string { + if ( '' === $class || ! $this->prng->chance( 12 ) ) { + return $class; + } + + $points = utf8_codepoints( $class ); + $at = $this->prng->int( 0, count( $points ) ); + $out = ''; + foreach ( $points as $i => $point ) { + if ( $i === $at ) { + $out .= "\0"; + } + $out .= $point[0]; + } + return $at === count( $points ) ? $out . "\0" : $out; + } + private function random_id_value(): string { $id = $this->random_word( true ); $this->pools['ids'][] = $id; @@ -581,4 +601,28 @@ public static function get_attribute_value( array $element, string $name ) { } return null; } + + /** + * Class tokens as seen by selector matching: ASCII whitespace separates + * tokens, and NUL inside a token is exposed as U+FFFD by class_list(). + * + * @return string[] + */ + public static function class_tokens( string $class_value ): array { + $tokens = array(); + $length = strlen( $class_value ); + $at = 0; + $ws = " \t\r\n\f"; + while ( $at < $length ) { + $at += strspn( $class_value, $ws, $at ); + if ( $at >= $length ) { + break; + } + + $token_length = strcspn( $class_value, $ws, $at ); + $tokens[] = str_replace( "\0", "\u{FFFD}", substr( $class_value, $at, $token_length ) ); + $at += $token_length; + } + return $tokens; + } } diff --git a/tools/css-selector-fuzz/lib/LexborOracle.php b/tools/css-selector-fuzz/lib/LexborOracle.php index 2dd74c9e92e54..afb508ddc1278 100644 --- a/tools/css-selector-fuzz/lib/LexborOracle.php +++ b/tools/css-selector-fuzz/lib/LexborOracle.php @@ -19,7 +19,8 @@ * ASCII case-insensitively even in no-quirks mode ( attribute selectors * like [id=x] are correctly case-sensitive ). Detected by probe at startup; * when present, lexbor is compared against the reference matcher run with - * quirks-style class/ID folding. + * quirks-style class/ID folding. Quirks documents are compared only when + * the probe also confirms class and #id selectors fold in quirks mode. */ class LexborOracle { @@ -33,6 +34,8 @@ class LexborOracle { private static $available = null; /** @var bool */ private static $issue368 = false; + /** @var bool */ + private static $quirks_class_id_reliable = false; public static function harness_path(): string { return dirname( __DIR__ ) . '/lexbor/harness'; @@ -49,15 +52,31 @@ public static function available(): bool { return false; } - // Probe: sanity plus issue-#368 detection. + // Probe: sanity plus class/#id case-sensitivity behavior. $sane = self::query( '
', 'div.a' ); if ( null === $sane || array( 'x' ) !== $sane['matches'] ) { self::stop(); return false; } - $folded = self::query( '
', '.A' ); - self::$issue368 = null !== $folded && array( 'x' ) === $folded['matches']; + $no_quirks_class = self::query( '
', '.A' ); + $no_quirks_id = self::query( '
', '#A' ); + $quirks_class = self::query( '
', '.A' ); + $quirks_id = self::query( '
', '#A' ); + foreach ( array( $no_quirks_class, $no_quirks_id, $quirks_class, $quirks_id ) as $probe ) { + if ( null === $probe || null !== $probe['error'] ) { + self::stop(); + return false; + } + } + + self::$issue368 = array( 'x' ) === $no_quirks_class['matches'] + || array( 'x' ) === $no_quirks_id['matches']; + self::$quirks_class_id_reliable = ! self::$issue368 + && array() === $no_quirks_class['matches'] + && array() === $no_quirks_id['matches'] + && array( 'x' ) === $quirks_class['matches'] + && array( 'x' ) === $quirks_id['matches']; self::$available = true; return true; } @@ -67,6 +86,11 @@ public static function has_issue_368(): bool { return self::$issue368; } + /** Whether lexbor can be trusted on quirks class/#id case folding. */ + public static function quirks_class_id_reliable(): bool { + return self::$quirks_class_id_reliable; + } + /** * Runs one case through lexbor. * diff --git a/tools/css-selector-fuzz/lib/ReferenceMatcher.php b/tools/css-selector-fuzz/lib/ReferenceMatcher.php index e86aa4e2e990b..ea422078e9893 100644 --- a/tools/css-selector-fuzz/lib/ReferenceMatcher.php +++ b/tools/css-selector-fuzz/lib/ReferenceMatcher.php @@ -223,25 +223,7 @@ private static function class_matches( string $wanted, array $row, bool $quirks return false; } - $length = strlen( $class_value ); - $at = 0; - while ( $at < $length ) { - $at += strspn( $class_value, self::WHITESPACE, $at ); - if ( $at >= $length ) { - break; - } - $word_length = strcspn( $class_value, self::WHITESPACE, $at ); - $word = substr( $class_value, $at, $word_length ); - $at += $word_length; - - /* - * WP_HTML_Tag_Processor::class_list() replaces NUL with U+FFFD in - * each class token before comparison; model that so a class value - * containing a raw NUL matches a `\0`-escaped ( U+FFFD ) selector - * the same way select() does. - */ - $word = str_replace( "\0", "\u{FFFD}", $word ); - + foreach ( DocumentGenerator::class_tokens( $class_value ) as $word ) { if ( $quirks ? ascii_strtolower( $word ) === ascii_strtolower( $wanted ) diff --git a/tools/css-selector-fuzz/lib/SelectorGenerator.php b/tools/css-selector-fuzz/lib/SelectorGenerator.php index fb93f8d66216d..668ad57bcace2 100644 --- a/tools/css-selector-fuzz/lib/SelectorGenerator.php +++ b/tools/css-selector-fuzz/lib/SelectorGenerator.php @@ -957,7 +957,7 @@ private function path_compound_for( array $element ): array { $class_value = DocumentGenerator::get_attribute_value( $element, 'class' ); if ( is_string( $class_value ) ) { - foreach ( preg_split( '/[ \t\n\f\r]+/', $class_value, -1, PREG_SPLIT_NO_EMPTY ) as $word ) { + foreach ( DocumentGenerator::class_tokens( $class_value ) as $word ) { $features[] = array( 'kind' => 'class', 'name' => $word ); } } @@ -974,6 +974,9 @@ private function path_compound_for( array $element ): array { continue; } $seen_attrs[ $lower ] = true; + if ( 'class' === $lower && is_string( $attr[1] ) && false !== strpos( $attr[1], "\0" ) ) { + continue; + } $features[] = $this->path_attr_feature( $lower, $attr[1], 'html' === ( $element['namespace'] ?? 'html' ) ); } diff --git a/tools/css-selector-fuzz/lib/WildDocumentGenerator.php b/tools/css-selector-fuzz/lib/WildDocumentGenerator.php index 78ae5a329f162..3cd7dada17cc6 100644 --- a/tools/css-selector-fuzz/lib/WildDocumentGenerator.php +++ b/tools/css-selector-fuzz/lib/WildDocumentGenerator.php @@ -299,9 +299,11 @@ private function random_attrs(): array { $words = array(); $n = $this->prng->int( 1, 3 ); for ( $j = 0; $j < $n; $j++ ) { - $word = $this->random_word(); - $words[] = $word; - $this->pools['classes'][] = $word; + $word = $this->maybe_inject_class_nul( $this->random_word() ); + $words[] = $word; + foreach ( DocumentGenerator::class_tokens( $word ) as $token ) { + $this->pools['classes'][] = $token; + } } $value = implode( ' ', $words ); } elseif ( 'id' === $lower ) { @@ -317,7 +319,7 @@ private function random_attrs(): array { } $this->pools['attrNames'][] = $lower; - if ( is_string( $value ) ) { + if ( is_string( $value ) && 'class' !== $lower ) { $this->pools['attrValues'][] = $value; } $attrs[] = array( $name, $value ); @@ -326,6 +328,23 @@ private function random_attrs(): array { return $attrs; } + private function maybe_inject_class_nul( string $class ): string { + if ( '' === $class || ! $this->prng->chance( 12 ) ) { + return $class; + } + + $points = utf8_codepoints( $class ); + $at = $this->prng->int( 0, count( $points ) ); + $out = ''; + foreach ( $points as $i => $point ) { + if ( $i === $at ) { + $out .= "\0"; + } + $out .= $point[0]; + } + return $at === count( $points ) ? $out . "\0" : $out; + } + private function render_attrs( array $attrs ): string { $out = ''; foreach ( $attrs as $attr ) { diff --git a/tools/css-selector-fuzz/lib/Worker.php b/tools/css-selector-fuzz/lib/Worker.php index 86ad865d50e37..f701d87974657 100644 --- a/tools/css-selector-fuzz/lib/Worker.php +++ b/tools/css-selector-fuzz/lib/Worker.php @@ -62,6 +62,8 @@ class Worker { * failures: array, * selector: string, * html: string, + * lexbor: string, + * matchStats: array, * } */ public static function run_case( int $seed ): array { @@ -78,6 +80,7 @@ public static function run_case( int $seed ): array { 'detail' => $detail, ); }; + $match_stats = array(); /* * The processor's own parse is the matching oracle's ground truth. @@ -301,6 +304,9 @@ static function () use ( $complex_list ) { } $html_matches = self::check_select_matches( 'html', $selector_string, $document, $expected, $record ); + if ( null !== $html_matches ) { + self::note_match_assertion( $match_stats, 'html', $expected, $html_matches ); + } // lexbor parses full documents only; fragments skip it. if ( ! ( $document['fragment'] ?? false ) ) { @@ -312,7 +318,10 @@ static function () use ( $complex_list ) { if ( null !== $compound_ast && null !== $tag_rows ) { $expected = ReferenceMatcher::expected_tag_matches_rows( $compound_ast, $tag_rows ); - self::check_select_matches( 'tag', $selector_string, $document, $expected, $record ); + $tag_matches = self::check_select_matches( 'tag', $selector_string, $document, $expected, $record ); + if ( null !== $tag_matches ) { + self::note_match_assertion( $match_stats, 'tag', $expected, $tag_matches ); + } } elseif ( null === $compound_list && null === $compound_error ) { self::check_select_rejection( 'tag', $selector_string, $document, $record ); } @@ -359,6 +368,7 @@ static function ( $failure ) { 'selector' => $selector_string, 'html' => $document['html'], 'lexbor' => $lexbor_state, + 'matchStats' => $match_stats, ); } @@ -768,14 +778,43 @@ private static function check_select_matches( string $target, string $selector_s return $actual; } + private static function note_match_assertion( array &$match_stats, string $target, array $expected, array $actual ): void { + if ( ! isset( $match_stats[ $target ] ) ) { + $match_stats[ $target ] = array( + 'assertions' => 0, + 'nonVacuous' => 0, + ); + } + + ++$match_stats[ $target ]['assertions']; + if ( array() !== $expected || array() !== $actual ) { + ++$match_stats[ $target ]['nonVacuous']; + } + } + + private static function finalize_match_stats( array $match_stats ): array { + foreach ( $match_stats as $bucket => $targets ) { + foreach ( $targets as $target => $counts ) { + $assertions = (int) ( $counts['assertions'] ?? 0 ); + $non_vacuous = (int) ( $counts['nonVacuous'] ?? 0 ); + $vacuous = max( 0, $assertions - $non_vacuous ); + + $match_stats[ $bucket ][ $target ]['vacuous'] = $vacuous; + $match_stats[ $bucket ][ $target ]['nonVacuousRate'] = $assertions > 0 ? round( $non_vacuous / $assertions, 4 ) : 0.0; + $match_stats[ $bucket ][ $target ]['vacuousRate'] = $assertions > 0 ? round( $vacuous / $assertions, 4 ) : 0.0; + } + } + return $match_stats; + } + /** * Runs the lexbor differential — the THIRD, independent matching opinion. * - * Quirks-mode documents are excluded ( lexbor #368 makes its quirks - * behavior untrustworthy and WP's quirks class/ID folding is owned by - * ReferenceMatcher ). The comparison only runs when lexbor built the - * same element tree as WP ( fid/tag/ancestry multiset ), so it tests - * the selector layer, not tree construction. + * Quirks-mode documents are excluded unless the startup probe confirms + * lexbor has reliable class/#id case folding in both no-quirks and quirks + * mode. The comparison only runs when lexbor built the same element tree + * as WP ( fid/tag/ancestry multiset ), so it tests the selector layer, + * not tree construction. * * Verdict triage: * - 'lexbor-divergence' lexbor != reference: a fuzzer-oracle problem @@ -793,7 +832,7 @@ private static function check_lexbor_differential( array $complex_ast, string $s if ( ! LexborOracle::available() ) { return 'unavailable'; } - if ( $quirks ) { + if ( $quirks && ! LexborOracle::quirks_class_id_reliable() ) { return 'skipped-quirks'; } @@ -1115,6 +1154,7 @@ public static function run_batch( array $options ): array { $buckets = array(); $signatures = array(); $lexbor = array(); + $match_stats = array(); $last_seed = null; $stop_reason = 'completed'; @@ -1145,6 +1185,16 @@ public static function run_batch( array $options ): array { $buckets[ $result['bucket'] ] = ( $buckets[ $result['bucket'] ] ?? 0 ) + 1; $lexbor[ $result['lexbor'] ] = ( $lexbor[ $result['lexbor'] ] ?? 0 ) + 1; $last_seed = $seed; + foreach ( $result['matchStats'] as $target => $stats ) { + if ( ! isset( $match_stats[ $result['bucket'] ][ $target ] ) ) { + $match_stats[ $result['bucket'] ][ $target ] = array( + 'assertions' => 0, + 'nonVacuous' => 0, + ); + } + $match_stats[ $result['bucket'] ][ $target ]['assertions'] += $stats['assertions']; + $match_stats[ $result['bucket'] ][ $target ]['nonVacuous'] += $stats['nonVacuous']; + } foreach ( $result['failures'] as $failure ) { ++$failures; @@ -1179,6 +1229,7 @@ public static function run_batch( array $options ): array { 'buckets' => $buckets, 'signatures' => $signatures, 'lexbor' => $lexbor, + 'matchStats' => self::finalize_match_stats( $match_stats ), 'stopReason' => $stop_reason, 'durationMs' => (int) round( 1000 * ( microtime( true ) - $started_at ) ), ); diff --git a/tools/css-selector-fuzz/runner.php b/tools/css-selector-fuzz/runner.php index fc3db262b282a..414eb167a660e 100644 --- a/tools/css-selector-fuzz/runner.php +++ b/tools/css-selector-fuzz/runner.php @@ -114,6 +114,48 @@ function css_selector_fuzz_worker_summary( string $stdout ): ?array { return null; } +/** Merges per-bucket/per-target match assertion counts. */ +function css_selector_fuzz_merge_match_stats( array &$target, array $source ): void { + foreach ( $source as $bucket => $targets ) { + foreach ( $targets as $match_target => $stats ) { + if ( ! isset( $target[ $bucket ][ $match_target ] ) ) { + $target[ $bucket ][ $match_target ] = array( + 'assertions' => 0, + 'nonVacuous' => 0, + ); + } + $target[ $bucket ][ $match_target ]['assertions'] += (int) ( $stats['assertions'] ?? 0 ); + $target[ $bucket ][ $match_target ]['nonVacuous'] += (int) ( $stats['nonVacuous'] ?? 0 ); + } + } +} + +/** Adds derived rates after all count aggregation is finished. */ +function css_selector_fuzz_finalize_match_stats( array $stats ): array { + foreach ( $stats as $bucket => $targets ) { + foreach ( $targets as $match_target => $counts ) { + $assertions = (int) ( $counts['assertions'] ?? 0 ); + $non_vacuous = (int) ( $counts['nonVacuous'] ?? 0 ); + $vacuous = max( 0, $assertions - $non_vacuous ); + + $stats[ $bucket ][ $match_target ]['vacuous'] = $vacuous; + $stats[ $bucket ][ $match_target ]['nonVacuousRate'] = $assertions > 0 ? round( $non_vacuous / $assertions, 4 ) : 0.0; + $stats[ $bucket ][ $match_target ]['vacuousRate'] = $assertions > 0 ? round( $vacuous / $assertions, 4 ) : 0.0; + } + } + return $stats; +} + +function css_selector_fuzz_write_state( string $state_path, array $state ): void { + $state['matchStats'] = css_selector_fuzz_finalize_match_stats( $state['matchStats'] ?? array() ); + write_json_file( $state_path, $state ); +} + +function css_selector_fuzz_state_for_output( array $state ): array { + $state['matchStats'] = css_selector_fuzz_finalize_match_stats( $state['matchStats'] ?? array() ); + return $state; +} + $options = parse_cli_options( $argv ); if ( option_bool( $options, 'help', false ) || option_bool( $options, 'h', false ) ) { echo "Usage: php tools/css-selector-fuzz/runner.php [--start-seed N] [--max-seeds N] [--duration-seconds N] [--chunk-size N] [--timeout-ms N] [--output-dir DIR] [--stop-on-failure]\n"; @@ -159,10 +201,11 @@ function css_selector_fuzz_worker_summary( string $stdout ): ?array { 'buckets' => array(), 'signatures' => array(), 'lexbor' => array(), + 'matchStats' => array(), 'nextSeed' => $start_seed, 'stopReason' => null, ); -write_json_file( $state_path, $state ); +css_selector_fuzz_write_state( $state_path, $state ); $deadline = $duration_seconds > 0 ? microtime( true ) + $duration_seconds : null; $seed = $start_seed; @@ -231,9 +274,16 @@ function css_selector_fuzz_worker_summary( string $stdout ): ?array { } else { ++$state['casesCompleted']; $state['failures'] += $single_summary['failures']; + foreach ( $single_summary['buckets'] as $bucket => $bucket_count ) { + $state['buckets'][ $bucket ] = ( $state['buckets'][ $bucket ] ?? 0 ) + $bucket_count; + } foreach ( $single_summary['signatures'] as $signature => $signature_count ) { $state['signatures'][ $signature ] = ( $state['signatures'][ $signature ] ?? 0 ) + $signature_count; } + foreach ( $single_summary['lexbor'] ?? array() as $lexbor_state => $lexbor_count ) { + $state['lexbor'][ $lexbor_state ] = ( $state['lexbor'][ $lexbor_state ] ?? 0 ) + $lexbor_count; + } + css_selector_fuzz_merge_match_stats( $state['matchStats'], $single_summary['matchStats'] ?? array() ); } } } else { @@ -248,12 +298,13 @@ function css_selector_fuzz_worker_summary( string $stdout ): ?array { foreach ( $summary['lexbor'] ?? array() as $lexbor_state => $lexbor_count ) { $state['lexbor'][ $lexbor_state ] = ( $state['lexbor'][ $lexbor_state ] ?? 0 ) + $lexbor_count; } + css_selector_fuzz_merge_match_stats( $state['matchStats'], $summary['matchStats'] ?? array() ); } $seed += $count; $state['nextSeed'] = $seed; $state['updatedAt'] = gmdate( 'c' ); - write_json_file( $state_path, $state ); + css_selector_fuzz_write_state( $state_path, $state ); if ( $stop_on_failure && $state['failures'] > 0 ) { $state['stopReason'] = 'stop-on-failure'; @@ -265,7 +316,7 @@ function css_selector_fuzz_worker_summary( string $stdout ): ?array { $state['stopReason'] = 'max-seeds'; } $state['updatedAt'] = gmdate( 'c' ); -write_json_file( $state_path, $state ); +css_selector_fuzz_write_state( $state_path, $state ); /* * The lexbor differential is the third oracle. If it ever ran ( 'compared' ) @@ -282,5 +333,5 @@ function css_selector_fuzz_worker_summary( string $stdout ): ?array { fwrite( STDERR, "NOTE: lexbor third oracle never ran (harness not built?); run `sh tools/css-selector-fuzz/lexbor/build.sh` for the differential.\n" ); } -echo json_encode_safe( $state ) . "\n"; +echo json_encode_safe( css_selector_fuzz_state_for_output( $state ) ) . "\n"; exit( 0 === $state['failures'] ? 0 : 2 ); diff --git a/tools/css-selector-fuzz/tests/self-check.php b/tools/css-selector-fuzz/tests/self-check.php index 8d9df7e378b70..9664367f1e300 100644 --- a/tools/css-selector-fuzz/tests/self-check.php +++ b/tools/css-selector-fuzz/tests/self-check.php @@ -14,6 +14,7 @@ use CssSelectorFuzz\DocumentGenerator; use CssSelectorFuzz\Prng; use CssSelectorFuzz\SelectorGenerator; +use CssSelectorFuzz\WildDocumentGenerator; use CssSelectorFuzz\Worker; use function CssSelectorFuzz\utf8_codepoints; @@ -28,6 +29,52 @@ function check( bool $condition, string $message ): void { fwrite( STDERR, "FAIL: {$message}\n" ); } +function known_core_parse_mismatch( string $selector, bool $expected, bool $actual ): ?string { + if ( $expected === $actual || ! $expected || $actual ) { + return null; + } + + if ( ! wp_is_valid_utf8( $selector ) ) { + return 'invalid-utf8-input-scrub'; + } + if ( str_ends_with( $selector, '\\' ) ) { + return 'backslash-at-eof-escape'; + } + if ( substr_count( $selector, '[' ) > substr_count( $selector, ']' ) ) { + return 'eof-auto-closes-attribute-selector'; + } + if ( preg_match( '/\\[[^\\]]*=\\s*[-_a-zA-Z0-9]\\]$/', $selector ) ) { + return 'single-char-unquoted-attribute-value-at-eof'; + } + if ( has_identity_escape_after_multibyte( $selector ) ) { + return 'identity-escape-after-multibyte'; + } + + return null; +} + +function has_identity_escape_after_multibyte( string $selector ): bool { + $seen_multibyte = false; + $length = strlen( $selector ); + for ( $i = 0; $i < $length; $i++ ) { + $byte = ord( $selector[ $i ] ); + if ( $byte > 0x7F ) { + $seen_multibyte = true; + continue; + } + if ( ! $seen_multibyte || '\\' !== $selector[ $i ] || $i + 1 >= $length ) { + continue; + } + + $next = $selector[ $i + 1 ]; + if ( "\n" === $next || "\r" === $next || "\f" === $next || ctype_xdigit( $next ) ) { + continue; + } + return true; + } + return false; +} + Bootstrap::load(); // --- Prng determinism and independence ------------------------------------- @@ -65,6 +112,7 @@ function check( bool $condition, string $message ): void { // --- Selector generator expectations over many seeds ----------------------- $by_bucket = array(); +$allowed_parse_mismatches = array(); for ( $seed = 1; $seed <= 400; $seed++ ) { $prng = new Prng( (string) $seed, 'self-check-selector' ); $document = DocumentGenerator::generate( $prng->fork( 'doc' ) ); @@ -76,20 +124,67 @@ function check( bool $condition, string $message ): void { $complex = WP_CSS_Complex_Selector_List::from_selectors( $selector['selector'] ); if ( null !== $selector['expectCompound'] ) { - check( - $selector['expectCompound'] === ( null !== $compound ), - "Seed {$seed} ({$selector['bucket']}): compound parse expectation for: " . \CssSelectorFuzz\printable_bytes( $selector['selector'] ) - ); + $expected = $selector['expectCompound']; + $actual = null !== $compound; + $known = known_core_parse_mismatch( $selector['selector'], $expected, $actual ); + if ( null !== $known ) { + $allowed_parse_mismatches[ "compound:{$known}" ] = ( $allowed_parse_mismatches[ "compound:{$known}" ] ?? 0 ) + 1; + } else { + check( + $expected === $actual, + "Seed {$seed} ({$selector['bucket']}): compound parse expectation for: " . \CssSelectorFuzz\printable_bytes( $selector['selector'] ) + ); + } } if ( null !== $selector['expectComplex'] ) { - check( - $selector['expectComplex'] === ( null !== $complex ), - "Seed {$seed} ({$selector['bucket']}): complex parse expectation for: " . \CssSelectorFuzz\printable_bytes( $selector['selector'] ) - ); + $expected = $selector['expectComplex']; + $actual = null !== $complex; + $known = known_core_parse_mismatch( $selector['selector'], $expected, $actual ); + if ( null !== $known ) { + $allowed_parse_mismatches[ "complex:{$known}" ] = ( $allowed_parse_mismatches[ "complex:{$known}" ] ?? 0 ) + 1; + } else { + check( + $expected === $actual, + "Seed {$seed} ({$selector['bucket']}): complex parse expectation for: " . \CssSelectorFuzz\printable_bytes( $selector['selector'] ) + ); + } } } check( count( $by_bucket ) >= 5, 'Bucket variety: saw ' . count( $by_bucket ) . ' buckets.' ); +if ( array() !== $allowed_parse_mismatches ) { + fwrite( STDERR, 'Allowed known core parse bug signatures: ' . \CssSelectorFuzz\json_encode_safe( $allowed_parse_mismatches ) . "\n" ); +} + +// --- Document generator: randomized class NUL injection -------------------- + +$safe_class_nul = 0; +for ( $seed = 1; $seed <= 200; $seed++ ) { + $document = DocumentGenerator::generate( new Prng( (string) $seed, 'self-check-class-nul-safe' ) ); + if ( false !== strpos( $document['html'], "\0" ) ) { + ++$safe_class_nul; + check( false === str_contains( implode( "\n", $document['pools']['attrValues'] ), "\0" ), "Safe document {$seed}: class NUL does not leak into attrValues pool." ); + check( \CssSelectorFuzz\ast_strings_are_utf8( $document['pools']['classes'] ), "Safe document {$seed}: class pool strings stay valid UTF-8." ); + check( in_array( true, array_map( static function ( string $class ): bool { + return false !== strpos( $class, "\u{FFFD}" ); + }, $document['pools']['classes'] ), true ), "Safe document {$seed}: class pool contains decoded U+FFFD token." ); + } +} +check( $safe_class_nul > 0, "Safe document generator emits randomized class NUL values ({$safe_class_nul} of 200)." ); + +$wild_class_nul = 0; +for ( $seed = 1; $seed <= 200; $seed++ ) { + $document = WildDocumentGenerator::generate( new Prng( (string) $seed, 'self-check-class-nul-wild' ) ); + if ( false !== strpos( $document['html'], "\0" ) ) { + ++$wild_class_nul; + check( false === str_contains( implode( "\n", $document['pools']['attrValues'] ), "\0" ), "Wild document {$seed}: class NUL does not leak into attrValues pool." ); + check( \CssSelectorFuzz\ast_strings_are_utf8( $document['pools']['classes'] ), "Wild document {$seed}: class pool strings stay valid UTF-8." ); + check( in_array( true, array_map( static function ( string $class ): bool { + return false !== strpos( $class, "\u{FFFD}" ); + }, $document['pools']['classes'] ), true ), "Wild document {$seed}: class pool contains decoded U+FFFD token." ); + } +} +check( $wild_class_nul > 0, "Wild document generator emits randomized class NUL values ({$wild_class_nul} of 200)." ); // --- Invalid-UTF-8 bucket: post-scrub AST expectations by construction ------ // from_selectors() replaces each maximal subpart of an ill-formed UTF-8 @@ -224,10 +319,10 @@ function select_fids( string $html, string $selector ): array { // --- Class-value decode boundary (ReferenceMatcher vs WP class_list) -------- // WP's class_list() folds NUL -> U+FFFD and treats FF as a separator; the // reference matcher reimplements tokenization independently. Pin both engines -// against each other on these boundary inputs ( exercised deterministically -// here since the random document generator does not emit control bytes in -// class values — see README #10 ). Each case also checks the reference matcher -// agrees with select() over a TreeCapture of the same markup. +// against each other on these boundary inputs; randomized generator sampling +// above verifies that the same NUL boundary is present in the hot path. Each +// case also checks the reference matcher agrees with select() over a +// TreeCapture of the same markup. function ref_fids( string $html, string $selector ): array { $capture = \CssSelectorFuzz\TreeCapture::capture( $html ); From 202905aec712af214c224988b5cca6154f61a42d Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 12 Jun 2026 21:18:51 +0200 Subject: [PATCH 187/634] CSS selector fuzz: Update moved selector-fix references --- tools/css-selector-fuzz/FINDINGS.md | 10 +++++----- tools/css-selector-fuzz/NEXT-STEPS.md | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/css-selector-fuzz/FINDINGS.md b/tools/css-selector-fuzz/FINDINGS.md index e58b256962364..16ed2d734e79e 100644 --- a/tools/css-selector-fuzz/FINDINGS.md +++ b/tools/css-selector-fuzz/FINDINGS.md @@ -1,12 +1,12 @@ # CSS Selector Fuzzer — Findings -Run: branch `html-css-fuzz` @ `46334f170b`, PHP 8.4.21. 5000 deterministic +Run: branch `html-css-fuzz` @ `5da3afedd0`, PHP 8.4.21. 5000 deterministic seeds, 0 crashes/timeouts. Three distinct, reproduced WordPress-core correctness bugs in the new HTML-API CSS selector support. Every selector below is valid, supported CSS that the API mis-handles **without** reporting lack of support. **Status: all three bugs are fixed on this branch** (commit prefix -`CSS selector:` — Bug 1 `7419a9fef6`, Bug 2 `0cefeb2fc8`, Bug 3 `16d03e2c5f`), +`CSS selector:` — Bug 1 `aed6cfb4aa`, Bug 2 `989e18da8a`, Bug 3 `0a87b20178`), each with PHPUnit regression tests that fail pre-fix. A post-fix 5000-seed run is clean (0 failures, 0 crashes). The repros below no longer trigger; they remain as regression anchors and Trac-ready minimal test cases. @@ -61,7 +61,7 @@ non-hex identity-escape branch is wrong. Depending on what wrong codepoint is produced this also causes spurious parse failures (a valid selector returns `null`). -**Fix (landed in `7419a9fef6`):** read the next codepoint from the byte +**Fix (landed in `aed6cfb4aa`):** read the next codepoint from the byte offset: `mb_substr( substr( $input, $offset ), 0, 1, 'UTF-8' )`. --- @@ -88,7 +88,7 @@ Reproduction against `………`: | `[x$=""]` | `I` | none | | `[x~=""]` | none ✅ | none | -**Fix (landed in `0cefeb2fc8`):** in `matches()`, return `false` for `^= $= *=` +**Fix (landed in `989e18da8a`):** in `matches()`, return `false` for `^= $= *=` when `'' === $this->value`, before the `substr_compare`/`strpos` calls. `~=` needs no guard — a whitespace-delimited list never yields an empty item — and a test pins that. (No `substr_compare` length edge exists here: `-strlen('')` @@ -123,7 +123,7 @@ character of the selector string. | `[a^=b]` | parsed ✅ (2-char operator) | | `[a=b].c` | parsed ✅ (trailing content) | -**Fix (landed in `16d03e2c5f`):** change `>=` to `>` (need +**Fix (landed in `0a87b20178`):** change `>=` to `>` (need `strlen - $updated_offset >= 3`). --- diff --git a/tools/css-selector-fuzz/NEXT-STEPS.md b/tools/css-selector-fuzz/NEXT-STEPS.md index 8746f5493c529..322d666ad1fe4 100644 --- a/tools/css-selector-fuzz/NEXT-STEPS.md +++ b/tools/css-selector-fuzz/NEXT-STEPS.md @@ -11,7 +11,7 @@ > which still reproduce. The notes below are retained as the design rationale. > > **Core fixes landed:** the three FINDINGS.md bugs are fixed on this branch -> (`CSS selector:` commits `7419a9fef6` / `0cefeb2fc8` / `16d03e2c5f`), each +> (`CSS selector:` commits `aed6cfb4aa` / `989e18da8a` / `0a87b20178`), each > with PHPUnit regression tests. A post-fix 5000-seed run is clean. > > **Fuzzer-side follow-up hardening implemented (2026-06-12):** From f9e6771d40f46f12eff485cc0e2a79bbc73fdc0a Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 12 Jun 2026 22:20:19 +0200 Subject: [PATCH 188/634] CSS Tokenizer: Add CSS token processor --- .../css-api/class-wp-css-builder.php | 241 + .../css-api/class-wp-css-token-processor.php | 1793 ++++++ src/wp-settings.php | 2 + .../phpunit/data/css-api/css-test-cases.json | 4923 +++++++++++++++++ .../tests/css-api/wpCssTokenProcessor.php | 2446 ++++++++ 5 files changed, 9405 insertions(+) create mode 100644 src/wp-includes/css-api/class-wp-css-builder.php create mode 100644 src/wp-includes/css-api/class-wp-css-token-processor.php create mode 100644 tests/phpunit/data/css-api/css-test-cases.json create mode 100644 tests/phpunit/tests/css-api/wpCssTokenProcessor.php diff --git a/src/wp-includes/css-api/class-wp-css-builder.php b/src/wp-includes/css-api/class-wp-css-builder.php new file mode 100644 index 0000000000000..56ae7a5ba009a --- /dev/null +++ b/src/wp-includes/css-api/class-wp-css-builder.php @@ -0,0 +1,241 @@ += 0x80 ) { + $result .= $value[ $i ]; + continue; + } + + // ASCII letters and underscore: always valid in idents. + if ( + ( $byte >= 0x41 && $byte <= 0x5A ) || // A-Z + ( $byte >= 0x61 && $byte <= 0x7A ) || // a-z + 0x5F === $byte // _ + ) { + $result .= $value[ $i ]; + continue; + } + + // Hyphen: valid in idents, but check for hyphen-digit at start. + if ( 0x2D === $byte ) { + // Hyphen at position 0 followed by a digit at position 1: escape the digit. + if ( 0 === $i && $i + 1 < $length && ord( $value[ $i + 1 ] ) >= 0x30 && ord( $value[ $i + 1 ] ) <= 0x39 ) { + $result .= '-'; + ++$i; + $result .= sprintf( '\\%X ', ord( $value[ $i ] ) ); + continue; + } + $result .= '-'; + continue; + } + + // Digits: valid except at position 0. + if ( $byte >= 0x30 && $byte <= 0x39 ) { + if ( 0 === $i ) { + $result .= sprintf( '\\%X ', $byte ); + } else { + $result .= $value[ $i ]; + } + continue; + } + + // Everything else: hex-escape. + $result .= sprintf( '\\%X ', $byte ); + } + + return $result; + } + + /** + * Create a quoted CSS string from a plain PHP string value. + * + * Example: + * $value = 'CSS & a ""; + * + * CSS strings are quoted many characters that are problematic in HTML + * or may be complicated for rudimentary CSS or HTML processors to handle + * are encoded using Unicode escape sequences. + * + * @see https://www.w3.org/TR/css-syntax-3/#escaping + */ + public static function string( string $value ): string { + $value = wp_scrub_utf8( $value ); + $escaped = strtr( + $value, + array( + // Escape existing backslashes to prevent unintentional escapes in result. + '\\' => '\\5C ', + + // Pre-processing replaces NULLs and some newlines. Replace and escape as necessary. + "\0" => "\u{FFFD}", + + // Normalize and replace newlines. https://www.w3.org/TR/css-syntax-3/#input-preprocessing + "\r\n" => '\\A ', + "\r" => '\\A ', + "\f" => '\\A ', + + // Newlines must be escaped in CSS strings. + "\n" => '\\A ', + + // Arbitrary characters for Unicode escaping: + + // HTML syntax may be problematic. + '<' => '\\3C ', + '>' => '\\3E ', + '&' => '\\26 ', + + // CSS syntax may be problematic. + ',' => '\\2C ', + ';' => '\\3B ', + '{' => '\\7B ', + '}' => '\\7D ', + '"' => '\\22 ', + "'" => '\\27 ', + ) + ); + return "\"{$escaped}\""; + } + + public static function normalize_and_escape_css( string $css ): string { + $css = wp_scrub_utf8( $css ); + $processor = WP_CSS_Token_Processor::create( $css ); + if ( null === $processor ) { + return ''; + } + + $normalized_css = ''; + + while ( $processor->next_token() ) { + switch ( $processor->get_token_type() ) { + + // Basic punctuation: + case WP_CSS_Token_Processor::TOKEN_SEMICOLON: $normalized_css .= ';'; break; + case WP_CSS_Token_Processor::TOKEN_COMMA: $normalized_css .= ','; break; + case WP_CSS_Token_Processor::TOKEN_WHITESPACE: $normalized_css .= ' '; break; + case WP_CSS_Token_Processor::TOKEN_COLON: $normalized_css .= ':'; break; + + // Paired punctuation: + case WP_CSS_Token_Processor::TOKEN_LEFT_BRACE: $normalized_css .= '{'; break; + case WP_CSS_Token_Processor::TOKEN_RIGHT_BRACE: $normalized_css .= '}'; break; + case WP_CSS_Token_Processor::TOKEN_LEFT_PAREN: $normalized_css .= '('; break; + case WP_CSS_Token_Processor::TOKEN_RIGHT_PAREN: $normalized_css .= ')'; break; + case WP_CSS_Token_Processor::TOKEN_LEFT_BRACKET: $normalized_css .= '['; break; + case WP_CSS_Token_Processor::TOKEN_RIGHT_BRACKET: $normalized_css .= ']'; break; + + // "@" + ident + case WP_CSS_Token_Processor::TOKEN_AT_KEYWORD: + $normalized_css .= '@' . self::ident( $processor->get_token_value() ); + break; + + // ident + "(" + case WP_CSS_Token_Processor::TOKEN_FUNCTION: + $normalized_css .= self::ident( $processor->get_token_value() ) . '('; + break; + + /* + * Hash tokens are not idents but their value can be escaped as such. + * + * ‖→ "#" →─┐ ┌──────────────────────────────┐ ┌─→‖ + * ├─→─┤ a-z A-Z 0-9 _ - or non-ASCII ├─→─┤ + * │ └──────────────────────────────┘ │ + * │ ┌──────────────────────────────┐ │ + * ├─→─┤ escape ├─→─┤ + * │ └──────────────────────────────┘ │ + * └──────────────────←───────────────────┘ + */ + case WP_CSS_Token_Processor::TOKEN_HASH: + $normalized_css .= '#' . self::ident( $processor->get_token_value() ); + break; + + case WP_CSS_Token_Processor::TOKEN_DIMENSION: + $normalized_css .= $processor->get_token_value() . $processor->get_token_unit(); + break; + + case WP_CSS_Token_Processor::TOKEN_PERCENTAGE: + $normalized_css .= "%{$processor->get_token_value()}"; + break; + + case WP_CSS_Token_Processor::TOKEN_NUMBER: + $normalized_css .= $processor->get_token_value(); + break; + + case WP_CSS_Token_Processor::TOKEN_DELIM: + $normalized_css .= $processor->get_token_value(); + break; + + case WP_CSS_Token_Processor::TOKEN_IDENT: + $normalized_css .= self::ident( $processor->get_token_value() ); + break; + + case WP_CSS_Token_Processor::TOKEN_STRING: + var_dump( $processor->get_token_value() ); + $normalized_css .= self::string( $processor->get_token_value() ); + break; + + // Keep or strip comments? + case WP_CSS_Token_Processor::TOKEN_COMMENT: + $normalized_css .= substr( $css, $processor->get_token_start(), $processor->get_token_length() ); + break; + + /** + * A is an open string that reaches a newline. + * + * @see https://www.w3.org/TR/css-syntax-3/#consume-string-token + * + * @see https://www.w3.org/TR/css-syntax-3/#preserved-tokens + * > Note: The tokens <}-token>s, <)-token>s, <]-token>, , and are always parse errors, but they are preserved in the token stream by this specification to allow other specs, such as Media Queries, to define more fine-grained error-handling than just dropping an entire declaration or block. + */ + case WP_CSS_Token_Processor::TOKEN_BAD_STRING: + $normalized_css .= substr( $css, $processor->get_token_start(), $processor->get_token_length() ) . "\n"; + break; + + case WP_CSS_Token_Processor::TOKEN_URL: + case WP_CSS_Token_Processor::TOKEN_BAD_URL: + case WP_CSS_Token_Processor::TOKEN_CDC: + case WP_CSS_Token_Processor::TOKEN_CDO: + default: + throw new Error( 'unhandled token type ' . $processor->get_token_type() . ' with value ' . var_export( $processor->get_token_value(), true ) ); + } + } + + return strtr( + $normalized_css, + array( + ' ' => '␠', + "\t" => "␉\t", + "\n" => "␊\n", + ) + ); + } +} diff --git a/src/wp-includes/css-api/class-wp-css-token-processor.php b/src/wp-includes/css-api/class-wp-css-token-processor.php new file mode 100644 index 0000000000000..f77faaa3f8dc4 --- /dev/null +++ b/src/wp-includes/css-api/class-wp-css-token-processor.php @@ -0,0 +1,1793 @@ + Replace any U+000D CARRIAGE RETURN (CR) code points, U+000C FORM FEED (FF) + * > code points, or pairs of U+000D CARRIAGE RETURN (CR) followed by U+000A LINE + * > FEED (LF) in input by a single U+000A LINE FEED (LF) code point. + * > Replace any U+0000 NULL or surrogate code points in input with U+FFFD REPLACEMENT + * > CHARACTER (�). + * + * This processor delays normalization as much as possible. That keeps the raw byte + * positions intact for accurate rewrites while still letting consumers ask for a + * normalized token when they need one. + * + * ### No EOF token + * + * The EOF token is a CSS parsing concept, not CSS tokenization concept. Therefore, + * this processor does not produce it. + * + * ### UTF-8 handling + * + * Only UTF-8 strings are supported. Invalid sequences are replaced with U+FFFD (�) + * using the maximal subpart approach described in + * https://www.unicode.org/versions/Unicode9.0.0/ch03.pdf, section 3.9 Best Practices + * for Using U+FFFD. + * + * ## Usage + * + * Basic iteration: + * + * $css = 'width: 10px;'; + * $processor = WP_CSS_Token_Processor::create( $css ); + * while ( $processor->next_token() ) { + * echo $processor->get_normalized_token(); + * } + * // Outputs: + * // width: 10px; + * + * Rewriting a URL while keeping the rest of the stylesheet intact: + * + * $css = 'background: url(old.jpg) center / cover;'; + * $processor = WP_CSS_Token_Processor::create( $css ); + * while ( $processor->next_token() ) { + * if ( WP_CSS_Token_Processor::TOKEN_URL === $processor->get_token_type() ) { + * $processor->set_value( 'uploads/new.jpg' ); + * } + * } + * $result = $processor->get_updated_css(); + * // background: url(uploads/new.jpg) center / cover; + * + * Gathering diagnostics with byte offsets: + * + * $css = "color: red;\ncolor: re\nd;"; + * $processor = WP_CSS_Token_Processor::create( $css ); + * $bad_strings = array(); + * while ( $processor->next_token() ) { + * if ( WP_CSS_Token_Processor::TOKEN_BAD_STRING === $processor->get_token_type() ) { + * $bad_strings[] = array( + * 'start' => $processor->get_token_start(), + * 'length' => $processor->get_token_length(), + * 'value' => $processor->get_unnormalized_token(), + * ); + * } + * } + * + * @see https://www.w3.org/TR/css-syntax-3/#tokenization + */ +class WP_CSS_Token_Processor { + /** + * Token type constants matching the CSS Syntax Level 3 specification. + * + * @see https://www.w3.org/TR/css-syntax-3/#tokenization + */ + public const TOKEN_WHITESPACE = 'whitespace-token'; + public const TOKEN_COMMENT = 'comment'; + public const TOKEN_STRING = 'string-token'; + + /** + * BAD-STRING tokens occur when a string contains an unescaped newline. + * + * Valid strings: "hello", 'world', "line1\Aline2" (escaped newline) + * Invalid (produces bad-string): "hello + * world" (literal newline breaks the string) + * + * The processor stops at the newline and produces a bad-string token for error recovery. + * + * @see https://www.w3.org/TR/css-syntax-3/#typedef-bad-string-token + */ + public const TOKEN_BAD_STRING = 'bad-string-token'; + public const TOKEN_HASH = 'hash-token'; + public const TOKEN_DELIM = 'delim-token'; + public const TOKEN_NUMBER = 'number-token'; + public const TOKEN_PERCENTAGE = 'percentage-token'; + public const TOKEN_DIMENSION = 'dimension-token'; + public const TOKEN_AT_KEYWORD = 'at-keyword-token'; + public const TOKEN_COLON = 'colon-token'; + public const TOKEN_SEMICOLON = 'semicolon-token'; + public const TOKEN_COMMA = 'comma-token'; + public const TOKEN_LEFT_PAREN = '(-token'; + public const TOKEN_RIGHT_PAREN = ')-token'; + public const TOKEN_LEFT_BRACKET = '[-token'; + public const TOKEN_RIGHT_BRACKET = ']-token'; + public const TOKEN_LEFT_BRACE = '{-token'; + public const TOKEN_RIGHT_BRACE = '}-token'; + public const TOKEN_FUNCTION = 'function-token'; + + /** + * URL tokens represent unquoted URLs in url() notation. + * + * For example, `url(image.jpg)` is a URL token. + * + * Quoted URLs like `url( "https://example.com" )` are handled as a function + * token, _not_ a URL token. + * + * Bad URL tokens are created when invalid characters are encountered in + * a URL token. + * + * @see https://www.w3.org/TR/css-syntax-3/#typedef-url-token + */ + public const TOKEN_URL = 'url-token'; + + /** + * BAD-URL tokens occur when a URL contains invalid characters. + * + * Invalid characters: quotes ("), apostrophes ('), parentheses (() + * Example invalid: url(image(.jpg) or url(image".jpg) + * + * When detected, the processor consumes everything up to ) or EOF. + * This prevents the bad URL from breaking subsequent tokens. + * + * @see https://www.w3.org/TR/css-syntax-3/#typedef-bad-url-token + */ + public const TOKEN_BAD_URL = 'bad-url-token'; + + /** + * Identifier tokens, such as `color`, `margin-top`, `red`, + * `inherit`, `--my-var`, `\x-escaped`, `über` (Unicode), etc. + * + * There are restrictions on the codepoints that start or are contained in + * an identifier, and identifiers may contain escape sequences. + * + * @see https://www.w3.org/TR/css-syntax-3/#typedef-ident-token + */ + public const TOKEN_IDENT = 'ident-token'; + + /** + * CDC (Comment Delimiter Close) token: --> + * + * Legacy token from when CSS was embedded in HTML + * + * Modern CSS no longer needs these, but they're preserved for compatibility. + * In stylesheets, they're typically treated like whitespace. + * + * @see https://www.w3.org/TR/css-syntax-3/#typedef-CDC-token + */ + public const TOKEN_CDC = 'CDC-token'; + + /** + * CDO (Comment Delimiter Open) token: ) + * + * Comment Delimiter Close - legacy HTML comment syntax in CSS. + * + * @see https://www.w3.org/TR/css-syntax-3/#CDC-token-diagram + */ + if ( + $this->at + 2 < $this->length && + '-' === $this->css[ $this->at + 1 ] && + '>' === $this->css[ $this->at + 2 ] + ) { + // Consume them and return a . + $this->at += 3; + $this->token_type = self::TOKEN_CDC; + $this->token_length = 3; + return true; + } + + // Otherwise, if the input stream starts with an ident sequence, + // reconsume the current input code point, consume an ident-like + // token, and return it. + if ( $this->check_if_3_code_points_start_an_ident_sequence( $this->at ) ) { + return $this->consume_ident_like(); + } + + // Otherwise, return a with its value set to the current input code point. + ++$this->at; + $this->token_type = self::TOKEN_DELIM; + $this->token_length = 1; + return true; + } + + /* + * U+003C LESS-THAN SIGN (<) + * If followed by !--, this is a CDO token (\n", + "tokens": [ + { + "type": "CDC-token", + "raw": "-->", + "startIndex": 0, + "endIndex": 3, + "normalized": "-->", + "value": null + }, + { + "type": "whitespace-token", + "raw": "\n", + "startIndex": 3, + "endIndex": 4, + "normalized": "\n", + "value": null + } + ] + }, + "tests/ident/0001": { + "css": "foo\n", + "tokens": [ + { + "type": "ident-token", + "raw": "foo", + "startIndex": 0, + "endIndex": 3, + "normalized": "foo", + "value": "foo" + }, + { + "type": "whitespace-token", + "raw": "\n", + "startIndex": 3, + "endIndex": 4, + "normalized": "\n", + "value": null + } + ] + }, + "tests/ident/0002": { + "css": "--\n", + "tokens": [ + { + "type": "ident-token", + "raw": "--", + "startIndex": 0, + "endIndex": 2, + "normalized": "--", + "value": "--" + }, + { + "type": "whitespace-token", + "raw": "\n", + "startIndex": 2, + "endIndex": 3, + "normalized": "\n", + "value": null + } + ] + }, + "tests/ident/0003": { + "css": "--0\n", + "tokens": [ + { + "type": "ident-token", + "raw": "--0", + "startIndex": 0, + "endIndex": 3, + "normalized": "--0", + "value": "--0" + }, + { + "type": "whitespace-token", + "raw": "\n", + "startIndex": 3, + "endIndex": 4, + "normalized": "\n", + "value": null + } + ] + }, + "tests/ident/0004": { + "css": "-\\\n", + "tokens": [ + { + "type": "delim-token", + "raw": "-", + "startIndex": 0, + "endIndex": 1, + "normalized": "-", + "value": "-" + }, + { + "type": "delim-token", + "raw": "\\", + "startIndex": 1, + "endIndex": 2, + "normalized": "\\", + "value": "\\" + }, + { + "type": "whitespace-token", + "raw": "\n", + "startIndex": 2, + "endIndex": 3, + "normalized": "\n", + "value": null + } + ] + }, + "tests/ident/0005": { + "css": "-\\ \n", + "tokens": [ + { + "type": "ident-token", + "raw": "-\\ ", + "startIndex": 0, + "endIndex": 3, + "normalized": "- ", + "value": "- " + }, + { + "type": "whitespace-token", + "raw": "\n", + "startIndex": 3, + "endIndex": 4, + "normalized": "\n", + "value": null + } + ] + }, + "tests/ident/0006": { + "css": "--💅\n", + "tokens": [ + { + "type": "ident-token", + "raw": "--💅", + "startIndex": 0, + "endIndex": 6, + "normalized": "--💅", + "value": "--💅" + }, + { + "type": "whitespace-token", + "raw": "\n", + "startIndex": 6, + "endIndex": 7, + "normalized": "\n", + "value": null + } + ] + }, + "tests/ident/0007": { + "css": "-§\n", + "tokens": [ + { + "type": "ident-token", + "raw": "-§", + "startIndex": 0, + "endIndex": 3, + "normalized": "-§", + "value": "-§" + }, + { + "type": "whitespace-token", + "raw": "\n", + "startIndex": 3, + "endIndex": 4, + "normalized": "\n", + "value": null + } + ] + }, + "tests/ident/0008": { + "css": "-×\n", + "tokens": [ + { + "type": "ident-token", + "raw": "-×", + "startIndex": 0, + "endIndex": 3, + "normalized": "-×", + "value": "-×" + }, + { + "type": "whitespace-token", + "raw": "\n", + "startIndex": 3, + "endIndex": 4, + "normalized": "\n", + "value": null + } + ] + }, + "tests/ident/0009": { + "css": "--a𐀀\n", + "tokens": [ + { + "type": "ident-token", + "raw": "--a𐀀", + "startIndex": 0, + "endIndex": 7, + "normalized": "--a𐀀", + "value": "--a𐀀" + }, + { + "type": "whitespace-token", + "raw": "\n", + "startIndex": 7, + "endIndex": 8, + "normalized": "\n", + "value": null + } + ] + }, + "tests/ident-like/0001": { + "css": "url(foo)\n", + "tokens": [ + { + "type": "url-token", + "raw": "url(foo)", + "startIndex": 0, + "endIndex": 8, + "normalized": "url(foo)", + "value": "foo" + }, + { + "type": "whitespace-token", + "raw": "\n", + "startIndex": 8, + "endIndex": 9, + "normalized": "\n", + "value": null + } + ] + }, + "tests/ident-like/0002": { + "css": "\\75 Rl(foo)\n", + "tokens": [ + { + "type": "url-token", + "raw": "\\75 Rl(foo)", + "startIndex": 0, + "endIndex": 11, + "normalized": "uRl(foo)", + "value": "foo" + }, + { + "type": "whitespace-token", + "raw": "\n", + "startIndex": 11, + "endIndex": 12, + "normalized": "\n", + "value": null + } + ] + }, + "tests/ident-like/0003": { + "css": "uR\\6c (foo)\n", + "tokens": [ + { + "type": "url-token", + "raw": "uR\\6c (foo)", + "startIndex": 0, + "endIndex": 11, + "normalized": "uRl(foo)", + "value": "foo" + }, + { + "type": "whitespace-token", + "raw": "\n", + "startIndex": 11, + "endIndex": 12, + "normalized": "\n", + "value": null + } + ] + }, + "tests/ident-like/0004": { + "css": "url('foo')\n", + "tokens": [ + { + "type": "function-token", + "raw": "url(", + "startIndex": 0, + "endIndex": 4, + "normalized": "url(", + "value": "url" + }, + { + "type": "string-token", + "raw": "'foo'", + "startIndex": 4, + "endIndex": 9, + "normalized": "'foo'", + "value": "foo" + }, + { + "type": ")-token", + "raw": ")", + "startIndex": 9, + "endIndex": 10, + "normalized": ")", + "value": null + }, + { + "type": "whitespace-token", + "raw": "\n", + "startIndex": 10, + "endIndex": 11, + "normalized": "\n", + "value": null + } + ] + }, + "tests/ident-like/0005": { + "css": "url( 'foo')\n", + "tokens": [ + { + "type": "function-token", + "raw": "url(", + "startIndex": 0, + "endIndex": 4, + "normalized": "url(", + "value": "url" + }, + { + "type": "whitespace-token", + "raw": " ", + "startIndex": 4, + "endIndex": 5, + "normalized": " ", + "value": null + }, + { + "type": "string-token", + "raw": "'foo'", + "startIndex": 5, + "endIndex": 10, + "normalized": "'foo'", + "value": "foo" + }, + { + "type": ")-token", + "raw": ")", + "startIndex": 10, + "endIndex": 11, + "normalized": ")", + "value": null + }, + { + "type": "whitespace-token", + "raw": "\n", + "startIndex": 11, + "endIndex": 12, + "normalized": "\n", + "value": null + } + ] + }, + "tests/ident-like/0006": { + "css": "url( 'foo')\n", + "tokens": [ + { + "type": "function-token", + "raw": "url(", + "startIndex": 0, + "endIndex": 4, + "normalized": "url(", + "value": "url" + }, + { + "type": "whitespace-token", + "raw": " ", + "startIndex": 4, + "endIndex": 6, + "normalized": " ", + "value": null + }, + { + "type": "string-token", + "raw": "'foo'", + "startIndex": 6, + "endIndex": 11, + "normalized": "'foo'", + "value": "foo" + }, + { + "type": ")-token", + "raw": ")", + "startIndex": 11, + "endIndex": 12, + "normalized": ")", + "value": null + }, + { + "type": "whitespace-token", + "raw": "\n", + "startIndex": 12, + "endIndex": 13, + "normalized": "\n", + "value": null + } + ] + }, + "tests/ident-like/0007": { + "css": "url( 'foo')\n", + "tokens": [ + { + "type": "function-token", + "raw": "url(", + "startIndex": 0, + "endIndex": 4, + "normalized": "url(", + "value": "url" + }, + { + "type": "whitespace-token", + "raw": " ", + "startIndex": 4, + "endIndex": 7, + "normalized": " ", + "value": null + }, + { + "type": "string-token", + "raw": "'foo'", + "startIndex": 7, + "endIndex": 12, + "normalized": "'foo'", + "value": "foo" + }, + { + "type": ")-token", + "raw": ")", + "startIndex": 12, + "endIndex": 13, + "normalized": ")", + "value": null + }, + { + "type": "whitespace-token", + "raw": "\n", + "startIndex": 13, + "endIndex": 14, + "normalized": "\n", + "value": null + } + ] + }, + "tests/ident-like/0008": { + "css": "not-url( 'foo')\n", + "tokens": [ + { + "type": "function-token", + "raw": "not-url(", + "startIndex": 0, + "endIndex": 8, + "normalized": "not-url(", + "value": "not-url" + }, + { + "type": "whitespace-token", + "raw": " ", + "startIndex": 8, + "endIndex": 11, + "normalized": " ", + "value": null + }, + { + "type": "string-token", + "raw": "'foo'", + "startIndex": 11, + "endIndex": 16, + "normalized": "'foo'", + "value": "foo" + }, + { + "type": ")-token", + "raw": ")", + "startIndex": 16, + "endIndex": 17, + "normalized": ")", + "value": null + }, + { + "type": "whitespace-token", + "raw": "\n", + "startIndex": 17, + "endIndex": 18, + "normalized": "\n", + "value": null + } + ] + }, + "tests/ident-like/0009": { + "css": "url( foo)\n", + "tokens": [ + { + "type": "url-token", + "raw": "url( foo)", + "startIndex": 0, + "endIndex": 11, + "normalized": "url( foo)", + "value": "foo" + }, + { + "type": "whitespace-token", + "raw": "\n", + "startIndex": 11, + "endIndex": 12, + "normalized": "\n", + "value": null + } + ] + }, + "tests/left-curly-bracket/0001": { + "css": "{\n", + "tokens": [ + { + "type": "{-token", + "raw": "{", + "startIndex": 0, + "endIndex": 1, + "normalized": "{", + "value": null + }, + { + "type": "whitespace-token", + "raw": "\n", + "startIndex": 1, + "endIndex": 2, + "normalized": "\n", + "value": null + } + ] + }, + "tests/left-parenthesis/0001": { + "css": "(\n", + "tokens": [ + { + "type": "(-token", + "raw": "(", + "startIndex": 0, + "endIndex": 1, + "normalized": "(", + "value": null + }, + { + "type": "whitespace-token", + "raw": "\n", + "startIndex": 1, + "endIndex": 2, + "normalized": "\n", + "value": null + } + ] + }, + "tests/left-square-bracket/0001": { + "css": "[\n", + "tokens": [ + { + "type": "[-token", + "raw": "[", + "startIndex": 0, + "endIndex": 1, + "normalized": "[", + "value": null + }, + { + "type": "whitespace-token", + "raw": "\n", + "startIndex": 1, + "endIndex": 2, + "normalized": "\n", + "value": null + } + ] + }, + "tests/less-than/0001": { + "css": "<\n", + "tokens": [ + { + "type": "delim-token", + "raw": "<", + "startIndex": 0, + "endIndex": 1, + "normalized": "<", + "value": "<" + }, + { + "type": "whitespace-token", + "raw": "\n", + "startIndex": 1, + "endIndex": 2, + "normalized": "\n", + "value": null + } + ] + }, + "tests/less-than/0002": { + "css": "` when a raw `--` type selector is + // followed immediately by a child combinator. + if ( '' === $before && '--' === $rendered_type ) { + $before = ' '; + } + $out .= $before . '>' . $this->maybe_ws( 50 ); } else { $out .= $this->ws(); } diff --git a/tools/css-selector-fuzz/tests/self-check.php b/tools/css-selector-fuzz/tests/self-check.php index 9664367f1e300..79c7dd7cfeff4 100644 --- a/tools/css-selector-fuzz/tests/self-check.php +++ b/tools/css-selector-fuzz/tests/self-check.php @@ -149,6 +149,19 @@ function has_identity_escape_after_multibyte( string $selector ): bool { ); } } + + if ( null !== $selector['ast'] && null !== $complex ) { + check( + $selector['ast'] === \CssSelectorFuzz\AstExtractor::from_complex_list( $complex ), + "Seed {$seed} ({$selector['bucket']}): complex AST round-trips for: " . \CssSelectorFuzz\printable_bytes( $selector['selector'] ) + ); + } + if ( null !== $selector['ast'] && null !== $compound ) { + check( + $selector['ast'] === \CssSelectorFuzz\AstExtractor::from_compound_list( $compound ), + "Seed {$seed} ({$selector['bucket']}): compound AST round-trips for: " . \CssSelectorFuzz\printable_bytes( $selector['selector'] ) + ); + } } check( count( $by_bucket ) >= 5, 'Bucket variety: saw ' . count( $by_bucket ) . ' buckets.' ); @@ -156,6 +169,113 @@ function has_identity_escape_after_multibyte( string $selector ): bool { fwrite( STDERR, 'Allowed known core parse bug signatures: ' . \CssSelectorFuzz\json_encode_safe( $allowed_parse_mismatches ) . "\n" ); } +// --- Selector renderer token-boundary regressions ------------------------- +// These pin places where adjacent rendered tokens can accidentally form a +// different token stream. In particular, a raw `--` type selector followed by +// a child combinator must not render as `-->`, which CSS tokenization treats +// as CDC. + +$renderer_boundary_asts = array( + 'cdc-child-combinator' => array( + array( + 'context' => array( + array( '--', '>' ), + ), + 'self' => array( + 'type' => 'a', + 'subs' => null, + ), + ), + ), + 'cdc-nested-child-combinator' => array( + array( + 'context' => array( + array( 'b', '>' ), + array( '--', '>' ), + ), + 'self' => array( + 'type' => 'a', + 'subs' => null, + ), + ), + ), + 'cdc-selector-list-branch' => array( + array( + 'context' => array( + array( '--', '>' ), + ), + 'self' => array( + 'type' => 'a', + 'subs' => null, + ), + ), + array( + 'context' => array(), + 'self' => array( + 'type' => '--', + 'subs' => array( + array( + 'kind' => 'class', + 'name' => 'x', + ), + array( + 'kind' => 'id', + 'name' => '--', + ), + ), + ), + ), + ), + 'attribute-ident-modifier-i' => array( + array( + 'context' => array(), + 'self' => array( + 'type' => null, + 'subs' => array( + array( + 'kind' => 'attr', + 'name' => 'x', + 'matcher' => 'exact', + 'value' => 'i', + 'modifier' => 'case-insensitive', + ), + ), + ), + ), + ), + 'attribute-ident-modifier-s' => array( + array( + 'context' => array(), + 'self' => array( + 'type' => null, + 'subs' => array( + array( + 'kind' => 'attr', + 'name' => 'x', + 'matcher' => 'exact', + 'value' => 's', + 'modifier' => 'case-sensitive', + ), + ), + ), + ), + ), +); + +foreach ( $renderer_boundary_asts as $name => $ast ) { + for ( $seed = 1; $seed <= 75; $seed++ ) { + $selector = SelectorGenerator::render( new Prng( (string) $seed, "self-check-renderer-boundary-{$name}" ), $ast ); + $complex = WP_CSS_Complex_Selector_List::from_selectors( $selector ); + check( null !== $complex, "Renderer boundary {$name} seed {$seed}: parse for " . \CssSelectorFuzz\printable_bytes( $selector ) ); + if ( null !== $complex ) { + check( + $ast === \CssSelectorFuzz\AstExtractor::from_complex_list( $complex ), + "Renderer boundary {$name} seed {$seed}: AST round-trips for " . \CssSelectorFuzz\printable_bytes( $selector ) + ); + } + } +} + // --- Document generator: randomized class NUL injection -------------------- $safe_class_nul = 0; From ce5d9bdca47cc0d4a60f2fe97fca5ace3849adbc Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 15 Jun 2026 22:51:06 +0200 Subject: [PATCH 197/634] CSS selector fuzzer: send raw selectors to lexbor oracle Lexbor parser bugs were hidden because the differential fed lexbor a canonical AST render. Query lexbor with the selector bytes accepted by WordPress, and mark lexbor parse rejects/divergences as lexbor/fuzzer-oracle noise rather than WP findings. --- tools/css-selector-fuzz/NEXT-STEPS.md | 27 +++++++---- tools/css-selector-fuzz/README.md | 32 ++++++++----- .../lib/SelectorGenerator.php | 8 ++-- tools/css-selector-fuzz/lib/Worker.php | 45 +++++++++---------- 4 files changed, 63 insertions(+), 49 deletions(-) diff --git a/tools/css-selector-fuzz/NEXT-STEPS.md b/tools/css-selector-fuzz/NEXT-STEPS.md index 322d666ad1fe4..f22f2ca21c3b9 100644 --- a/tools/css-selector-fuzz/NEXT-STEPS.md +++ b/tools/css-selector-fuzz/NEXT-STEPS.md @@ -14,6 +14,13 @@ > (`CSS selector:` commits `aed6cfb4aa` / `989e18da8a` / `0a87b20178`), each > with PHPUnit regression tests. A post-fix 5000-seed run is clean. > +> **Current lexbor differential behavior (2026-06-15):** lexbor now receives +> the exact selector bytes accepted by WP, not a canonical re-render of the +> parsed AST. `lexbor-parse-reject` remains classified as lexbor/fuzzer-oracle +> noise, never as a WP finding by itself. Historical notes below that say +> canonical re-rendering sidestepped lexbor parser bugs describe the earlier +> differential behavior. +> > **Fuzzer-side follow-up hardening implemented (2026-06-12):** > `tests/self-check.php` now allowlists known core parse-bug signatures in its > fixed seed-window parse-expectation loop, while unknown mismatches still fail. @@ -58,10 +65,12 @@ > truncations (`[`, `[a=`, `[a~`, `[a=b, div`) stay invalid. Verified > against Chromium form-by-form, including an exhaustive per-byte > truncation table in review. lexbor rejects all EOF-truncated forms -> (drafted as `lexbor/UPSTREAM-ISSUES.md` issue 4); the differential is -> unaffected because it compares canonical re-renders. Fuzzer gained an -> `eof-truncated` edge-escape kind and the invalid corpus was reshuffled -> along the new validity boundary; COVERAGE.md regenerated. +> (drafted as `lexbor/UPSTREAM-ISSUES.md` issue 4). Historical note: the +> differential was unaffected at the time because it compared canonical +> re-renders; current behavior feeds lexbor the original selector bytes, so +> these are expected `lexbor-parse-reject` noise, not WP findings. Fuzzer +> gained an `eof-truncated` edge-escape kind and the invalid corpus was +> reshuffled along the new validity boundary; COVERAGE.md regenerated. > > **Invalid-UTF-8 input policy — IMPLEMENTED as scrub (2026-06-11):** > selector strings are UTF-8 text; `normalize_selector_input()` now decodes @@ -166,10 +175,12 @@ > but NOT per the WHATWG maximal-subpart rule — one U+FFFD per byte for > truncated sequences (`E2 8C` → 2, spec 1) and one per whole sequence for > UTF-8-encoded surrogate halves (`ED A0 80` → 1, spec 3) — drafted as -> `lexbor/UPSTREAM-ISSUES.md` issue 6. The differential is unaffected and -> stays live for the bucket: it feeds lexbor the canonical re-render of -> the post-scrub AST (escaped, pure ASCII), the same mechanism that -> sidesteps lexbor's other byte-level parsing bugs. Doc-side observation: +> `lexbor/UPSTREAM-ISSUES.md` issue 6. Historical note: the differential +> used to stay live for the bucket by feeding lexbor the canonical re-render +> of the post-scrub AST (escaped, pure ASCII), the same mechanism that +> sidestepped lexbor's other byte-level parsing bugs. Current behavior feeds +> lexbor the original selector bytes, so these known decoding differences +> surface as lexbor/fuzzer-oracle noise. Doc-side observation: > lexbor keeps raw invalid bytes in the DOM unchanged (same stance as the > Tag Processor), so raw doc bytes match nothing in either engine. The > handoff's optional metamorphic relation `parse(s) === parse(scrub(s))` diff --git a/tools/css-selector-fuzz/README.md b/tools/css-selector-fuzz/README.md index 6025b6e45a10f..9c094692b456d 100644 --- a/tools/css-selector-fuzz/README.md +++ b/tools/css-selector-fuzz/README.md @@ -91,16 +91,18 @@ produces the same document, the same selector, and the same verdict. Skipped for ASTs containing invalid UTF-8 (reachable only from chaos/mutated inputs), which the renderer cannot round-trip. - lexbor differential (third, independent oracle; requires the harness — - see below): on full-document cases whose selector parsed, a canonical - re-render of the verified AST is matched by liblexbor and compared, - as a multiset of fids, against the reference matcher. Quirks documents + see below): on full-document cases whose selector parsed, the exact + selector bytes accepted by WP are matched by liblexbor and compared, as a + multiset of fids, against the reference matcher. Quirks documents participate only when the startup probe confirms lexbor's class/#id folding behavior in both no-quirks and quirks mode. Gated on WP and lexbor building the same element tree (fid/tag/ancestry), so it tests the selector layer, not tree construction. Verdicts: - `lexbor-divergence` (lexbor ≠ reference) is a fuzzer-oracle problem; - `match-mismatch-html` with no accompanying divergence means reference - == lexbor ≠ WP — a high-confidence WP finding. + `lexbor-parse-reject` and `lexbor-divergence` (lexbor ≠ reference) are + lexbor/fuzzer-oracle problems, with `wpFinding: false` in their details; + `match-mismatch-html` with no accompanying `lexbor-parse-reject` or + `lexbor-divergence` means reference == lexbor ≠ WP — a high-confidence WP + finding. - Repeating a case yields a byte-identical result digest (determinism). Note the digest covers the WP-under-test surface (selector, html, parse-nullness, ASTs, failure invariants) but **not** the lexbor @@ -114,17 +116,19 @@ liblexbor from upstream `master`; the build script prints the exact commit). The worker auto-detects the binary at `tools/css-selector-fuzz/lexbor/harness` and reports per-batch tallies, persisted to `state.json` under `lexbor`: -- `compared` — the differential ran and matched fid-multisets. +- `compared` — the differential ran to a selector verdict; parser rejects are + recorded as `lexbor-parse-reject`, and successful parses either match + fid-multisets or record `lexbor-divergence`. - `tree-gated` — WP and lexbor built different trees; differential skipped. -- `skipped-quirks` / `skipped-utf8` — quirks document while lexbor class/#id - case behavior is not trusted / non-UTF-8 AST. +- `skipped-quirks` — quirks document while lexbor class/#id case behavior is + not trusted. - `n/a` — the differential does not apply (unparseable selector, fragment, no captured tree). - `unavailable` / `error` — the harness was missing or died. The runner prints a loud warning if these appear after the harness had run, so a third oracle that dies mid-run cannot hide behind a green run. -Known lexbor issues compensated for when present: +Known lexbor issues and handling: - [#368](https://github.com/lexbor/lexbor/issues/368): class and `#id` selectors match ASCII case-insensitively even in @@ -138,9 +142,13 @@ Known lexbor issues compensated for when present: - lexbor rejects uppercase `I`/`S` attribute-selector modifiers, and its non-ASCII ident-codepoint table omits U+00B7 and U+00C0–U+00F6 (it starts at U+00F8), rejecting e.g. `.Über` while accepting `.über`. - Both sidestepped by the canonical re-render (lowercase modifiers, all - non-ASCII hex-escaped); both are candidate upstream reports, not WP + These can now surface as `lexbor-parse-reject` because lexbor receives the + original selector input; they are candidate upstream reports, not WP findings. +- lexbor's invalid-UTF-8 selector decoding differs from WP's + maximal-subpart scrub. These cases can surface as parser rejects or + divergences, and remain lexbor/fuzzer-oracle noise unless independently + confirmed against WP. - `lxb_selectors_find` reports a node once per matching selector-list branch; `LXB_SELECTORS_OPT_MATCH_FIRST` dedupes. - lexbor matches `[x~=""]` against whitespace-only attribute values diff --git a/tools/css-selector-fuzz/lib/SelectorGenerator.php b/tools/css-selector-fuzz/lib/SelectorGenerator.php index 85a2a7871b2b9..90eadaa2f2427 100644 --- a/tools/css-selector-fuzz/lib/SelectorGenerator.php +++ b/tools/css-selector-fuzz/lib/SelectorGenerator.php @@ -90,11 +90,9 @@ public static function render( Prng $prng, array $list_ast, bool $escape_boost = * Renders a canonical complex-list AST deterministically with minimal * escaping: single spaces around combinators, `, ` between branches, * double-quoted attribute values, lowercase `i`/`s` modifiers, and all - * non-ASCII codepoints hex-escaped. Used to hand a semantically-identical - * selector to external engines: lexbor rejects some byte-level forms WP - * correctly accepts ( uppercase I/S attribute modifiers; raw non-ASCII - * ident codepoints in U+00B7, U+00C0-U+00F6 — its non-ASCII ident table - * starts at U+00F8 ). Escaping sidesteps codepoint classification. + * non-ASCII codepoints hex-escaped. Useful when a deterministic + * semantically-identical selector string is needed from an already parsed + * AST. */ public static function render_canonical( array $list_ast ): string { $branches = array(); diff --git a/tools/css-selector-fuzz/lib/Worker.php b/tools/css-selector-fuzz/lib/Worker.php index f701d87974657..961d24c0245fe 100644 --- a/tools/css-selector-fuzz/lib/Worker.php +++ b/tools/css-selector-fuzz/lib/Worker.php @@ -821,12 +821,15 @@ private static function finalize_match_stats( array $match_stats ): array { * ( or an un-compensated lexbor bug ) — never a * WP verdict on its own. * - 'lexbor-parse-reject' lexbor refused a selector WP accepted. - * - match-mismatch-html with NO lexbor-divergence on the same case - * means reference == lexbor != WP: a - * high-confidence WP finding. + * This is lexbor/fuzzer-oracle noise — never a + * WP verdict on its own. + * - match-mismatch-html with NO lexbor-divergence and NO + * lexbor-parse-reject on the same case means + * reference == lexbor != WP: a high-confidence + * WP finding. * * @return string Tally state: - * unavailable|skipped-quirks|skipped-utf8|error|tree-gated|compared. + * unavailable|skipped-quirks|error|tree-gated|compared. */ private static function check_lexbor_differential( array $complex_ast, string $selector_string, array $document, array $rows, bool $quirks, array $expected, callable $record ): string { if ( ! LexborOracle::available() ) { @@ -837,22 +840,11 @@ private static function check_lexbor_differential( array $complex_ast, string $s } /* - * lexbor receives a canonical re-render of the (already verified) - * AST rather than the original byte form: the differential targets - * matching semantics, while byte-level parsing (escapes, whitespace, - * modifier case — lexbor e.g. rejects uppercase I/S modifiers) is - * covered by the AST round-trip and metamorphic invariants. ASTs - * containing invalid UTF-8 cannot be re-rendered; since - * from_selectors() scrubs input to U+FFFD before parsing, none should - * exist and this skip is defensive ( a nonzero skipped-utf8 tally - * indicates a normalization bypass ). + * Feed lexbor the exact selector bytes WP parsed. This intentionally + * keeps parser-level lexbor rejections visible as lexbor/fuzzer-oracle + * noise rather than canonicalizing them away. */ - if ( ! ast_strings_are_utf8( $complex_ast ) ) { - return 'skipped-utf8'; - } - $canonical = SelectorGenerator::render_canonical( $complex_ast ); - - $lex = LexborOracle::query( $document['html'], $canonical ); + $lex = LexborOracle::query( $document['html'], $selector_string ); if ( null === $lex ) { return 'error'; } @@ -861,8 +853,11 @@ private static function check_lexbor_differential( array $complex_ast, string $s $record( 'lexbor-parse-reject', array( - 'note' => 'lexbor rejected the canonical form of a selector the WP parser accepted', - 'canonical' => printable_bytes( $canonical ), + 'classification' => 'lexbor/fuzzer-oracle', + 'wpFinding' => false, + 'lexborError' => $lex['error'], + 'note' => 'lexbor rejected the same selector input that WP accepted', + 'selector' => printable_bytes( $selector_string ), ) ); return 'compared'; @@ -905,9 +900,11 @@ private static function check_lexbor_differential( array $complex_ast, string $s $record( 'lexbor-divergence', array( - 'reference' => $expected_for_lexbor, - 'lexbor' => $lex_matches, - 'issue368' => LexborOracle::has_issue_368(), + 'classification' => 'lexbor/fuzzer-oracle', + 'wpFinding' => false, + 'reference' => $expected_for_lexbor, + 'lexbor' => $lex_matches, + 'issue368' => LexborOracle::has_issue_368(), ) ); } From 1be88a47a5779cb266ca8d2e5aa8aa5d9a8c114d Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 17 Jun 2026 13:26:56 +0200 Subject: [PATCH 198/634] HTML API: Preserve escaped type selector asterisks CSS tokenization already distinguishes a literal '*' delimiter from escaped identifiers that decode to '*'. Preserve that distinction in WP_CSS_Type_Selector so only the delimiter path is universal, while escaped asterisks remain ordinary type selectors. --- .../css/class-wp-css-type-selector.php | 21 +++++++--- .../tests/html-api/wpCssTypeSelector.php | 41 +++++++++++++++++++ .../tests/html-api/wpHtmlProcessor-select.php | 7 ++++ .../html-api/wpHtmlTagProcessor-select.php | 7 ++++ 4 files changed, 70 insertions(+), 6 deletions(-) diff --git a/src/wp-includes/html-api/css/class-wp-css-type-selector.php b/src/wp-includes/html-api/css/class-wp-css-type-selector.php index fcb92fd34bc25..3746eefa4fbdd 100644 --- a/src/wp-includes/html-api/css/class-wp-css-type-selector.php +++ b/src/wp-includes/html-api/css/class-wp-css-type-selector.php @@ -18,19 +18,28 @@ */ final class WP_CSS_Type_Selector extends WP_CSS_Selector_Parser_Matcher { /** - * The element type (tag name) to match or '*' to match any element. + * The element type (tag name) to match. * * @var string */ public $type; + /** + * Whether the selector is the universal selector. + * + * @var bool + */ + private $is_universal; + /** * Constructor. * - * @param string $type The element type (tag name) to match or '*' to match any element. + * @param string $type The element type (tag name) to match. + * @param bool $is_universal Whether the selector is the universal selector. */ - private function __construct( string $type ) { - $this->type = $type; + private function __construct( string $type, bool $is_universal = false ) { + $this->type = $type; + $this->is_universal = $is_universal; } /** @@ -54,7 +63,7 @@ public function matches( WP_HTML_Tag_Processor $processor ): bool { * @return bool */ public function matches_tag( string $tag_name ): bool { - if ( '*' === $this->type ) { + if ( $this->is_universal ) { return true; } return 0 === strcasecmp( $tag_name, $this->type ); @@ -70,7 +79,7 @@ public function matches_tag( string $tag_name ): bool { */ public static function parse( WP_CSS_Selector_Token_Stream $tokens ) { if ( $tokens->consume_delim( '*' ) ) { - return new WP_CSS_Type_Selector( '*' ); + return new WP_CSS_Type_Selector( '*', true ); } $result = $tokens->consume_ident(); diff --git a/tests/phpunit/tests/html-api/wpCssTypeSelector.php b/tests/phpunit/tests/html-api/wpCssTypeSelector.php index 917ab005b6980..6d81aa7ff246f 100644 --- a/tests/phpunit/tests/html-api/wpCssTypeSelector.php +++ b/tests/phpunit/tests/html-api/wpCssTypeSelector.php @@ -29,6 +29,47 @@ public function test_parse_type( string $input, ?string $expected = null, ?strin } } + /** + * @ticket 62653 + * + * @dataProvider data_escaped_asterisk_type_selectors + */ + public function test_escaped_asterisk_is_type_selector_not_universal( string $input ) { + $tokens = WP_CSS_Selector_Token_Stream::from_selectors( $input, WP_CSS_Type_Selector::class ); + $result = WP_CSS_Type_Selector::parse( $tokens ); + + $this->assertInstanceOf( WP_CSS_Type_Selector::class, $result ); + $this->assertSame( '*', $result->type ); + $this->assertFalse( $result->matches_tag( 'DIV' ) ); + $this->assertSame( '', $tokens->get_remaining_text() ); + } + + /** + * @ticket 62653 + */ + public function test_literal_asterisk_is_universal_selector() { + $tokens = WP_CSS_Selector_Token_Stream::from_selectors( '*', WP_CSS_Type_Selector::class ); + $result = WP_CSS_Type_Selector::parse( $tokens ); + + $this->assertInstanceOf( WP_CSS_Type_Selector::class, $result ); + $this->assertSame( '*', $result->type ); + $this->assertTrue( $result->matches_tag( 'DIV' ) ); + } + + /** + * Data provider. + * + * @return array + */ + public static function data_escaped_asterisk_type_selectors(): array { + return array( + 'identity escape' => array( '\\*' ), + 'lowercase hex escape' => array( '\\2a' ), + 'uppercase hex escape' => array( '\\2A' ), + 'padded hex escape' => array( '\\00002A' ), + ); + } + /** * Data provider. * diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php index fcb1acf3fa7d6..d9da35a224062 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessor-select.php @@ -45,6 +45,13 @@ public function test_selects_all_matches( string $html, string $selector, int $m public static function data_selectors(): array { return array( 'any' => array( '

', '*', 5 ), + 'escaped * type selector' => array( '

', '\\*', 0 ), + 'escaped lowercase hex * type' => array( '

', '\\2a', 0 ), + 'escaped uppercase hex * type' => array( '

', '\\2A', 0 ), + 'escaped padded hex * type' => array( '

', '\\00002A', 0 ), + 'escaped p type selector' => array( '

', '\\p', 1 ), + 'escaped hex p type selector' => array( '

', '\\70', 1 ), + 'escaped padded hex p type' => array( '

', '\\000070', 1 ), 'quirks mode ID' => array( '

In quirks mode, ID matching is case-insensitive.', '#id', 2 ), 'quirks mode class' => array( '

In quirks mode, class matching is case-insensitive.', '.c', 2 ), 'no-quirks mode ID' => array( '

In no-quirks mode, ID matching is case-sensitive.', '#id', 1 ), diff --git a/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php b/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php index 96bb8e1b4457d..dafa64aba7ec5 100644 --- a/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php +++ b/tests/phpunit/tests/html-api/wpHtmlTagProcessor-select.php @@ -44,6 +44,13 @@ public static function data_selectors(): array { return array( 'simple type' => array( '

', 'div', 2 ), 'any type' => array( '
', '*', 2 ), + 'escaped * type selector' => array( '

', '\\*', 0 ), + 'escaped lowercase hex * type' => array( '

', '\\2a', 0 ), + 'escaped uppercase hex * type' => array( '

', '\\2A', 0 ), + 'escaped padded hex * type' => array( '

', '\\00002A', 0 ), + 'escaped p type selector' => array( '

', '\\p', 1 ), + 'escaped hex p type selector' => array( '

', '\\70', 1 ), + 'escaped padded hex p type' => array( '

', '\\000070', 1 ), 'simple class' => array( '
', '.x', 2 ), 'simple id' => array( '
', '#x', 2 ), From 981fc3d6fcf2da9cdb0b64c7e83a821c1f3dd12d Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 25 Jun 2026 11:34:31 +0200 Subject: [PATCH 199/634] Fix escaped asterisk selector fuzz oracle --- tools/css-selector-fuzz/lib/AstExtractor.php | 43 +++++++++- .../lib/ReferenceMatcher.php | 20 +++-- .../lib/SelectorGenerator.php | 35 ++++++-- tools/css-selector-fuzz/tests/self-check.php | 85 +++++++++++++++++-- 4 files changed, 160 insertions(+), 23 deletions(-) diff --git a/tools/css-selector-fuzz/lib/AstExtractor.php b/tools/css-selector-fuzz/lib/AstExtractor.php index 593bce73f84ea..4068e3fb4b990 100644 --- a/tools/css-selector-fuzz/lib/AstExtractor.php +++ b/tools/css-selector-fuzz/lib/AstExtractor.php @@ -54,7 +54,7 @@ private static function from_complex( \WP_CSS_Complex_Selector $selector ): arra if ( ! in_array( $pair[1], array( ' ', '>' ), true ) ) { throw new \UnexpectedValueException( 'Context selector uses unsupported combinator: ' . var_export( $pair[1], true ) ); } - $context[] = array( $pair[0]->type, $pair[1] ); + $context[] = self::from_type_selector_context_pair( $pair[0], $pair[1] ); } return array( @@ -79,10 +79,49 @@ private static function from_compound( \WP_CSS_Compound_Selector $selector ): ar throw new \UnexpectedValueException( 'Compound selector has neither type nor subclass selectors.' ); } - return array( + $out = array( 'type' => null === $selector->type_selector ? null : $selector->type_selector->type, 'subs' => $subs, ); + if ( null !== $selector->type_selector ) { + self::add_type_selector_metadata( $out, $selector->type_selector ); + } + + return $out; + } + + private static function from_type_selector_context_pair( \WP_CSS_Type_Selector $selector, string $combinator ): array { + $pair = array( $selector->type, $combinator ); + if ( self::should_disambiguate_asterisk_type_selector( $selector ) ) { + $pair[] = false; + } + return $pair; + } + + private static function add_type_selector_metadata( array &$compound, \WP_CSS_Type_Selector $selector ): void { + if ( self::should_disambiguate_asterisk_type_selector( $selector ) ) { + $compound['typeIsUniversal'] = false; + } + } + + private static function should_disambiguate_asterisk_type_selector( \WP_CSS_Type_Selector $selector ): bool { + $is_universal = self::type_selector_is_universal( $selector ); + if ( $is_universal && '*' !== $selector->type ) { + throw new \UnexpectedValueException( 'Universal type selector has unexpected type: ' . var_export( $selector->type, true ) ); + } + return '*' === $selector->type && ! $is_universal; + } + + private static function type_selector_is_universal( \WP_CSS_Type_Selector $selector ): bool { + $reflection = new \ReflectionProperty( \WP_CSS_Type_Selector::class, 'is_universal' ); + if ( PHP_VERSION_ID < 80100 ) { + $reflection->setAccessible( true ); + } + $value = $reflection->getValue( $selector ); + if ( ! is_bool( $value ) ) { + throw new \UnexpectedValueException( 'Type selector universal flag is not a boolean.' ); + } + return $value; } private static function from_subclass( $sub ): array { diff --git a/tools/css-selector-fuzz/lib/ReferenceMatcher.php b/tools/css-selector-fuzz/lib/ReferenceMatcher.php index ea422078e9893..1b61be59cff47 100644 --- a/tools/css-selector-fuzz/lib/ReferenceMatcher.php +++ b/tools/css-selector-fuzz/lib/ReferenceMatcher.php @@ -168,11 +168,13 @@ private static function explore_context( array $context, array $ancestor_tags ): return false; } - list( $type, $combinator ) = $context[0]; - $rest = array_slice( $context, 1 ); + $pair = $context[0]; + list( $type, $combinator ) = $pair; + $is_universal = array_key_exists( 2, $pair ) ? (bool) $pair[2] : null; + $rest = array_slice( $context, 1 ); if ( '>' === $combinator ) { - return self::type_matches( $type, $ancestor_tags[0] ) + return self::type_matches( $type, $ancestor_tags[0], $is_universal ) && self::explore_context( $rest, array_slice( $ancestor_tags, 1 ) ); } @@ -180,7 +182,7 @@ private static function explore_context( array $context, array $ancestor_tags ): $count = count( $ancestor_tags ); for ( $i = 0; $i < $count; $i++ ) { if ( - self::type_matches( $type, $ancestor_tags[ $i ] ) && + self::type_matches( $type, $ancestor_tags[ $i ], $is_universal ) && self::explore_context( $rest, array_slice( $ancestor_tags, $i + 1 ) ) ) { return true; @@ -190,7 +192,8 @@ private static function explore_context( array $context, array $ancestor_tags ): } public static function compound_matches( array $compound, array $row, bool $quirks, bool $html_attr_ci = true ): bool { - if ( null !== $compound['type'] && ! self::type_matches( $compound['type'], $row['tag'] ) ) { + $is_universal = array_key_exists( 'typeIsUniversal', $compound ) ? (bool) $compound['typeIsUniversal'] : null; + if ( null !== $compound['type'] && ! self::type_matches( $compound['type'], $row['tag'], $is_universal ) ) { return false; } foreach ( (array) $compound['subs'] as $sub ) { @@ -201,8 +204,11 @@ public static function compound_matches( array $compound, array $row, bool $quir return true; } - private static function type_matches( string $type, string $tag ): bool { - return '*' === $type || ascii_strtolower( $type ) === ascii_strtolower( $tag ); + private static function type_matches( string $type, string $tag, ?bool $is_universal = null ): bool { + if ( null === $is_universal ) { + $is_universal = '*' === $type; + } + return $is_universal || ascii_strtolower( $type ) === ascii_strtolower( $tag ); } private static function sub_matches( array $sub, array $row, bool $quirks, bool $html_attr_ci ): bool { diff --git a/tools/css-selector-fuzz/lib/SelectorGenerator.php b/tools/css-selector-fuzz/lib/SelectorGenerator.php index 90eadaa2f2427..86f91bc99f46f 100644 --- a/tools/css-selector-fuzz/lib/SelectorGenerator.php +++ b/tools/css-selector-fuzz/lib/SelectorGenerator.php @@ -100,13 +100,17 @@ public static function render_canonical( array $list_ast ): string { $out = ''; foreach ( array_reverse( $complex['context'] ) as $pair ) { list( $type, $combinator ) = $pair; - $out .= '*' === $type ? '*' : self::canonical_ident( $type ); + $out .= self::type_is_universal( $type, self::context_type_is_universal( $pair ) ) + ? '*' + : self::canonical_ident( $type ); $out .= '>' === $combinator ? ' > ' : ' '; } $compound = $complex['self']; if ( null !== $compound['type'] ) { - $out .= '*' === $compound['type'] ? '*' : self::canonical_ident( $compound['type'] ); + $out .= self::type_is_universal( $compound['type'], self::compound_type_is_universal( $compound ) ) + ? '*' + : self::canonical_ident( $compound['type'] ); } foreach ( (array) $compound['subs'] as $sub ) { switch ( $sub['kind'] ) { @@ -312,8 +316,8 @@ public static function generate( Prng $prng, array $pools, ?array $rows = null, * parsed WP_CSS_* objects): * * list: array of complex - * complex: array( 'context' => array( array( type, combinator ) ... right-to-left ), 'self' => compound ) - * compound: array( 'type' => string|null, 'subs' => array|null ) + * complex: array( 'context' => array( array( type, combinator[, is_universal] ) ... right-to-left ), 'self' => compound ) + * compound: array( 'type' => string|null, 'subs' => array|null, 'typeIsUniversal' => bool optional ) * sub: array( 'kind' => 'class'|'id', 'name' => string ) * | array( 'kind' => 'attr', 'name' => string, 'matcher' => string|null, * 'value' => string|null, 'modifier' => string|null ) @@ -1138,7 +1142,7 @@ private function path_near_miss( array $list, array $element ): array { $fid = $element['fid']; $flips = array( 'wrong-class', 'wrong-attr' ); - if ( null !== $compound['type'] && '*' !== $compound['type'] ) { + if ( null !== $compound['type'] && ! self::type_is_universal( $compound['type'], self::compound_type_is_universal( $compound ) ) ) { $flips[] = 'wrong-type'; } foreach ( $complex['context'] as $pair ) { @@ -1156,6 +1160,7 @@ private function path_near_miss( array $list, array $element ): array { $other = $this->prng->choice( DocumentGenerator::SAFE_TAGS ); } while ( $other === $tag ); $complex['self']['type'] = $this->prng->chance( 25 ) ? $this->random_case( $other ) : $other; + unset( $complex['self']['typeIsUniversal'] ); return array( array( $complex ), null, $fid ); case 'wrong-attr': @@ -1227,7 +1232,9 @@ private function render_complex( array $complex ): string { $reversed = array_reverse( $complex['context'] ); foreach ( $reversed as $pair ) { list( $type, $combinator ) = $pair; - $rendered_type = '*' === $type ? '*' : $this->render_ident( $type ); + $rendered_type = self::type_is_universal( $type, self::context_type_is_universal( $pair ) ) + ? '*' + : $this->render_ident( $type ); $out .= $rendered_type; if ( '>' === $combinator ) { $before = $this->maybe_ws( 50 ); @@ -1247,7 +1254,9 @@ private function render_complex( array $complex ): string { private function render_compound( array $compound ): string { $out = ''; if ( null !== $compound['type'] ) { - $out .= '*' === $compound['type'] ? '*' : $this->render_ident( $compound['type'] ); + $out .= self::type_is_universal( $compound['type'], self::compound_type_is_universal( $compound ) ) + ? '*' + : $this->render_ident( $compound['type'] ); } foreach ( (array) $compound['subs'] as $sub ) { switch ( $sub['kind'] ) { @@ -1265,6 +1274,18 @@ private function render_compound( array $compound ): string { return $out; } + private static function context_type_is_universal( array $pair ): ?bool { + return array_key_exists( 2, $pair ) ? (bool) $pair[2] : null; + } + + private static function compound_type_is_universal( array $compound ): ?bool { + return array_key_exists( 'typeIsUniversal', $compound ) ? (bool) $compound['typeIsUniversal'] : null; + } + + private static function type_is_universal( string $type, ?bool $explicit ): bool { + return null === $explicit ? '*' === $type : $explicit; + } + private function render_attr_selector( array $sub ): string { $out = '[' . $this->maybe_ws( 20 ) . $this->render_ident( $sub['name'] ) . $this->maybe_ws( 20 ); diff --git a/tools/css-selector-fuzz/tests/self-check.php b/tools/css-selector-fuzz/tests/self-check.php index 79c7dd7cfeff4..7815919cc759b 100644 --- a/tools/css-selector-fuzz/tests/self-check.php +++ b/tools/css-selector-fuzz/tests/self-check.php @@ -436,13 +436,7 @@ function select_fids( string $html, string $selector ): array { check( array( 'e4' ) === select_fids( $known_html, '[data-v|="hello"]' ), 'Known: [data-v|=hello].' ); check( array( 'e7' ) === select_fids( $known_html, '[lang^="en"]' ), 'Known: [lang^=en].' ); -// --- Class-value decode boundary (ReferenceMatcher vs WP class_list) -------- -// WP's class_list() folds NUL -> U+FFFD and treats FF as a separator; the -// reference matcher reimplements tokenization independently. Pin both engines -// against each other on these boundary inputs; randomized generator sampling -// above verifies that the same NUL boundary is present in the hot path. Each -// case also checks the reference matcher agrees with select() over a -// TreeCapture of the same markup. +// --- Known-answer matcher helpers ------------------------------------------ function ref_fids( string $html, string $selector ): array { $capture = \CssSelectorFuzz\TreeCapture::capture( $html ); @@ -454,6 +448,83 @@ function ref_fids( string $html, string $selector ): array { return \CssSelectorFuzz\ReferenceMatcher::expected_html_matches_rows( $ast, $capture['htmlRows'], $capture['quirks'] ); } +function complex_ast( string $selector ): ?array { + $list = WP_CSS_Complex_Selector_List::from_selectors( $selector ); + return null === $list ? null : \CssSelectorFuzz\AstExtractor::from_complex_list( $list ); +} + +// --- Escaped asterisk type selectors --------------------------------------- + +$literal_asterisk_ast = complex_ast( '*' ); +check( null !== $literal_asterisk_ast, 'Asterisk type distinction: literal universal parses.' ); +if ( null !== $literal_asterisk_ast ) { + check( '*' === $literal_asterisk_ast[0]['self']['type'], 'Asterisk type distinction: literal universal decodes to "*".' ); + check( ! array_key_exists( 'typeIsUniversal', $literal_asterisk_ast[0]['self'] ), 'Asterisk type distinction: literal universal keeps legacy AST shape.' ); +} + +foreach ( array( '\\*', '\\2a', '\\2A', '\\00002A' ) as $selector ) { + $ast = complex_ast( $selector ); + check( null !== $ast, "Asterisk type distinction: escaped selector parses ({$selector})." ); + if ( null === $ast ) { + continue; + } + check( '*' === $ast[0]['self']['type'], "Asterisk type distinction: escaped selector decodes to type * ({$selector})." ); + check( false === ( $ast[0]['self']['typeIsUniversal'] ?? null ), "Asterisk type distinction: escaped selector is not universal ({$selector})." ); + check( $literal_asterisk_ast !== $ast, "Asterisk type distinction: escaped selector AST differs from literal universal ({$selector})." ); +} + +$escaped_asterisk_item_ast = array( + array( + 'context' => array(), + 'self' => array( + 'type' => '*', + 'subs' => array( array( 'kind' => 'class', 'name' => 'item' ) ), + 'typeIsUniversal' => false, + ), + ), +); +$canonical_escaped_asterisk_item = SelectorGenerator::render_canonical( $escaped_asterisk_item_ast ); +check( + $escaped_asterisk_item_ast === complex_ast( $canonical_escaped_asterisk_item ), + 'Asterisk type distinction: canonical renderer escapes literal type *.' +); +for ( $seed = 1; $seed <= 30; $seed++ ) { + $rendered = SelectorGenerator::render( new Prng( (string) $seed, 'self-check-escaped-asterisk-type' ), $escaped_asterisk_item_ast ); + check( + $escaped_asterisk_item_ast === complex_ast( $rendered ), + "AST renderer escaped type * seed {$seed}: AST round-trips for " . \CssSelectorFuzz\printable_bytes( $rendered ) + ); +} + +$asterisk_html = '' + . '

' + . ''; + +foreach ( + array( + '*.item' => array( 'a3', 'a4' ), + '\\*.item' => array(), + '\\2a.item' => array(), + '\\00002A.item' => array(), + '* > .item' => array( 'a3', 'a4' ), + '\\* > .item' => array(), + '\\2a > .item' => array(), + ) as $selector => $expected +) { + $wp = select_fids( $asterisk_html, $selector ); + $ref = ref_fids( $asterisk_html, $selector ); + check( $expected === $wp, "Asterisk type distinction ({$selector}): select() == expected." ); + check( $ref === $wp, "Asterisk type distinction ({$selector}): ReferenceMatcher == select()." ); +} + +// --- Class-value decode boundary (ReferenceMatcher vs WP class_list) -------- +// WP's class_list() folds NUL -> U+FFFD and treats FF as a separator; the +// reference matcher reimplements tokenization independently. Pin both engines +// against each other on these boundary inputs; randomized generator sampling +// above verifies that the same NUL boundary is present in the hot path. Each +// case also checks the reference matcher agrees with select() over a +// TreeCapture of the same markup. + $nul_html = ""; $ff_html = ""; From 504582864a1b4eda3c0d09bf6a9178b807d4a90e Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 26 Jun 2026 09:12:06 +0200 Subject: [PATCH 200/634] Ignore generated Lexbor harness --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 15876fa47fee8..03dfe96ce5672 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,7 @@ wp-tests-config.php /packagehash.txt /.gutenberg-hash /artifacts +/tools/css-selector-fuzz/lexbor/harness /setup.log /coverage From de2572b1da20f0fe6f53eebd6b8bf10ae066dd2f Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Sun, 9 Aug 2026 18:49:43 +0000 Subject: [PATCH 201/634] Tests: Use `assertNull()` instead of `assertSame()` with `null`. Using the dedicated `assertNull()` assertion instead of `assertSame( null, $actual )` clarifies intent and produces more descriptive failure messages. Developed in https://github.com/WordPress/wordpress-develop/pull/12818. Follow-up to r62969. Props Soean. See #64894. git-svn-id: https://develop.svn.wordpress.org/trunk@63161 602fd350-edb4-49c9-b593-d223f7449a82 --- tests/phpunit/tests/functions/maybeSerialize.php | 2 +- tests/phpunit/tests/post/types.php | 2 +- tests/phpunit/tests/post/wpAfterInsertPost.php | 4 ++-- .../tests/rest-api/rest-settings-controller.php | 2 +- tests/phpunit/tests/theme/wpGetBlockCssSelector.php | 12 ++++++------ 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/phpunit/tests/functions/maybeSerialize.php b/tests/phpunit/tests/functions/maybeSerialize.php index c7ee7179b5984..a4725217e5377 100644 --- a/tests/phpunit/tests/functions/maybeSerialize.php +++ b/tests/phpunit/tests/functions/maybeSerialize.php @@ -222,7 +222,7 @@ public function test_deserialize_request_utility_filtered_iterator_objects( $val } $callback_value = $property->getValue( $new_value ); - $this->assertSame( null, $callback_value ); + $this->assertNull( $callback_value ); } else { $this->assertSame( $value->count(), unserialize( $serialized )->count() ); } diff --git a/tests/phpunit/tests/post/types.php b/tests/phpunit/tests/post/types.php index 2c8564f22aeab..5ae45c67e1044 100644 --- a/tests/phpunit/tests/post/types.php +++ b/tests/phpunit/tests/post/types.php @@ -626,7 +626,7 @@ public function test_removing_autosave_support_removes_rest_api_controller() { remove_post_type_support( 'foo', 'autosave' ); $post_type_object = get_post_type_object( 'foo' ); - $this->assertSame( null, $post_type_object->get_autosave_rest_controller(), 'Autosave controller should be removed.' ); + $this->assertNull( $post_type_object->get_autosave_rest_controller(), 'Autosave controller should be removed.' ); _unregister_post_type( 'foo' ); } diff --git a/tests/phpunit/tests/post/wpAfterInsertPost.php b/tests/phpunit/tests/post/wpAfterInsertPost.php index c312096245af5..e853fcfa59bcd 100644 --- a/tests/phpunit/tests/post/wpAfterInsertPost.php +++ b/tests/phpunit/tests/post/wpAfterInsertPost.php @@ -157,7 +157,7 @@ public function test_new_post_via_wp_insert_post() { ) ); - $this->assertSame( null, self::$passed_post_before_status ); + $this->assertNull( self::$passed_post_before_status ); $this->assertSame( 'a new post', self::$passed_post_title ); } @@ -197,7 +197,7 @@ public function test_new_post_via_rest_controller() { ); rest_get_server()->dispatch( $request ); - $this->assertSame( null, self::$passed_post_before_title ); + $this->assertNull( self::$passed_post_before_title ); $this->assertSame( 'new title', self::$passed_post_title ); } diff --git a/tests/phpunit/tests/rest-api/rest-settings-controller.php b/tests/phpunit/tests/rest-api/rest-settings-controller.php index e8f90b53f20f1..981ca3dc684b6 100644 --- a/tests/phpunit/tests/rest-api/rest-settings-controller.php +++ b/tests/phpunit/tests/rest-api/rest-settings-controller.php @@ -794,6 +794,6 @@ public function test_provides_setting_metadata_in_schema() { $this->assertSame( 'string', $title['type'] ); $this->assertSame( 'Title', $title['title'] ); $this->assertSame( 'Site title.', $title['description'] ); - $this->assertSame( null, $title['default'] ); + $this->assertNull( $title['default'] ); } } diff --git a/tests/phpunit/tests/theme/wpGetBlockCssSelector.php b/tests/phpunit/tests/theme/wpGetBlockCssSelector.php index d52dff978998c..e382217640b4d 100644 --- a/tests/phpunit/tests/theme/wpGetBlockCssSelector.php +++ b/tests/phpunit/tests/theme/wpGetBlockCssSelector.php @@ -131,7 +131,7 @@ public function test_no_feature_level_selector_via_selectors_api() { ); $selector = wp_get_block_css_selector( $block_type, 'typography' ); - $this->assertSame( null, $selector ); + $this->assertNull( $selector ); } /** @@ -205,7 +205,7 @@ public function test_no_feature_selector_via_experimental_property() { ); $selector = wp_get_block_css_selector( $block_type, 'typography' ); - $this->assertSame( null, $selector ); + $this->assertNull( $selector ); } /** @@ -262,7 +262,7 @@ public function test_no_subfeature_level_selector_via_selectors_api() { ); $selector = wp_get_block_css_selector( $block_type, array( 'typography', 'fontSize' ) ); - $this->assertSame( null, $selector ); + $this->assertNull( $selector ); } /** @@ -297,7 +297,7 @@ public function test_no_subfeature_selector_via_experimental_property() { $block_type, array( 'typography', 'fontSize' ) ); - $this->assertSame( null, $selector ); + $this->assertNull( $selector ); } /** @@ -311,10 +311,10 @@ public function test_empty_target_returns_null() { ); $selector = wp_get_block_css_selector( $block_type, array() ); - $this->assertSame( null, $selector ); + $this->assertNull( $selector ); $selector = wp_get_block_css_selector( $block_type, '' ); - $this->assertSame( null, $selector ); + $this->assertNull( $selector ); } /** From a608816a09604c804d79a74fdd9ca0477e020617 Mon Sep 17 00:00:00 2001 From: Jonathan Desrosiers Date: Mon, 10 Aug 2026 17:21:35 +0000 Subject: [PATCH 202/634] Build/Test Tools: Miscellaneous imrpovements after [62859]. This applies several small changes to improve on the changes aimed at fetching the built Gutenberg asset zip file once per run: - Adds some missing step names. - Converts the `gutenberg-artifact` workflow input from a string to boolean. - Removes overly complex job description. Developed in https://github.com/WordPress/wordpress-develop/pull/12935. Follow up to [62859], [62862]. Props desrosj, irozum. Fixes #65721. git-svn-id: https://develop.svn.wordpress.org/trunk@63162 602fd350-edb4-49c9-b593-d223f7449a82 --- .github/workflows/phpunit-tests.yml | 18 ++++++------------ .../workflows/reusable-phpunit-tests-v3.yml | 14 ++++++-------- .github/workflows/test-coverage.yml | 3 ++- 3 files changed, 14 insertions(+), 21 deletions(-) diff --git a/.github/workflows/phpunit-tests.yml b/.github/workflows/phpunit-tests.yml index 2b9bbfe891640..94a2ddf187d9e 100644 --- a/.github/workflows/phpunit-tests.yml +++ b/.github/workflows/phpunit-tests.yml @@ -53,14 +53,8 @@ permissions: {} jobs: # Downloads and verifies the Gutenberg build once for all PHPUnit jobs. - # - # This condition is the union of the conditions on the jobs that need it, reduced. - # The org matrices require `WordPress/wordpress-develop` or a pull request, and the - # fork matrix requires a pull request, so `wordpress-develop` or a pull request - # covers every case. Keep it in step with those jobs: a narrower condition orphans - # them, because a job that needs a skipped job is skipped too, and a broader one - # downloads a build that nothing consumes. prepare-gutenberg: + name: Prepare Gutenberg Assets uses: ./.github/workflows/reusable-prepare-gutenberg.yml permissions: contents: read @@ -144,7 +138,7 @@ jobs: phpunit-config: ${{ matrix.multisite && 'tests/phpunit/multisite.xml' || 'phpunit.xml.dist' }} tests-domain: ${{ matrix.tests-domain }} report: ${{ matrix.report || false }} - gutenberg-artifact: gutenberg-build + gutenberg-artifact: ${{ needs.prepare-gutenberg.result != 'skipped' }} gutenberg-sha: ${{ needs.prepare-gutenberg.outputs.gutenberg-sha }} # @@ -200,7 +194,7 @@ jobs: memcached: ${{ matrix.memcached }} phpunit-config: ${{ matrix.multisite && 'tests/phpunit/multisite.xml' || 'phpunit.xml.dist' }} report: false - gutenberg-artifact: gutenberg-build + gutenberg-artifact: ${{ needs.prepare-gutenberg.result != 'skipped' }} gutenberg-sha: ${{ needs.prepare-gutenberg.outputs.gutenberg-sha }} # @@ -250,7 +244,7 @@ jobs: memcached: ${{ matrix.memcached }} phpunit-config: ${{ matrix.multisite && 'tests/phpunit/multisite.xml' || 'phpunit.xml.dist' }} report: false - gutenberg-artifact: gutenberg-build + gutenberg-artifact: ${{ needs.prepare-gutenberg.result != 'skipped' }} gutenberg-sha: ${{ needs.prepare-gutenberg.outputs.gutenberg-sha }} # @@ -285,7 +279,7 @@ jobs: db-type: ${{ matrix.db-type }} db-version: ${{ matrix.db-version }} phpunit-test-groups: ${{ matrix.phpunit-test-groups }} - gutenberg-artifact: gutenberg-build + gutenberg-artifact: ${{ needs.prepare-gutenberg.result != 'skipped' }} gutenberg-sha: ${{ needs.prepare-gutenberg.outputs.gutenberg-sha }} # @@ -350,7 +344,7 @@ jobs: memcached: ${{ matrix.memcached || false }} phpunit-config: ${{ matrix.multisite && 'tests/phpunit/multisite.xml' || 'phpunit.xml.dist' }} phpunit-test-groups: ${{ matrix.phpunit-test-groups || '' }} - gutenberg-artifact: gutenberg-build + gutenberg-artifact: ${{ needs.prepare-gutenberg.result != 'skipped' }} gutenberg-sha: ${{ needs.prepare-gutenberg.outputs.gutenberg-sha }} slack-notifications: diff --git a/.github/workflows/reusable-phpunit-tests-v3.yml b/.github/workflows/reusable-phpunit-tests-v3.yml index 6a7f49fba468c..1c09113810dd3 100644 --- a/.github/workflows/reusable-phpunit-tests-v3.yml +++ b/.github/workflows/reusable-phpunit-tests-v3.yml @@ -73,10 +73,10 @@ on: type: boolean default: false gutenberg-artifact: - description: 'The name of a same-workflow artifact containing the prepared Gutenberg build. Optional: callers that omit it download Gutenberg per job.' + description: 'Whether the Gutenberg-sourced assets are sourced from zip artifact.' required: false - type: string - default: '' + type: boolean + default: false gutenberg-sha: description: 'The immutable Gutenberg source SHA verified by the calling workflow.' required: false @@ -146,14 +146,12 @@ jobs: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} persist-credentials: false - # Branches >= 5.9 call this workflow at @trunk without the producer job, so they - # pass no artifact. They skip this step and fall back to a per-job download. + # Only WordPress 7.0+ include Gutenberg-maintained assets from a built zip file. - name: Download prepared Gutenberg build - if: inputs.gutenberg-artifact != '' + if: ${{ inputs.gutenberg-artifact }} uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - # Without a run ID, this action reads only from the caller's current workflow run. - name: ${{ inputs.gutenberg-artifact }} + name: gutenberg-build path: gutenberg digest-mismatch: error diff --git a/.github/workflows/test-coverage.yml b/.github/workflows/test-coverage.yml index ffc650ec370fb..191445ba7167c 100644 --- a/.github/workflows/test-coverage.yml +++ b/.github/workflows/test-coverage.yml @@ -52,6 +52,7 @@ env: jobs: # Downloads and verifies the Gutenberg build once for all coverage jobs. prepare-gutenberg: + name: Prepare Gutenberg Assets uses: ./.github/workflows/reusable-prepare-gutenberg.yml permissions: contents: read @@ -76,7 +77,7 @@ jobs: php: '8.3' multisite: ${{ matrix.multisite }} coverage-report: ${{ matrix.coverage-report }} - gutenberg-artifact: gutenberg-build + gutenberg-artifact: ${{ needs.prepare-gutenberg.result != 'skipped' }} gutenberg-sha: ${{ needs.prepare-gutenberg.outputs.gutenberg-sha }} secrets: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} From 7f8a28c7ae04e855ded7c15062342c8ce3c11770 Mon Sep 17 00:00:00 2001 From: Jonathan Desrosiers Date: Mon, 10 Aug 2026 17:29:41 +0000 Subject: [PATCH 203/634] Build/Test Tools: Move `env:pull` retry logic. This improves the retry mechanism added in [62857] for the `env:pull` command by mvoing the logic from the PHPUnit test workflow into the `docker.js` script so that every `env:pull` command benefits reagardless of context. Follow up to [62857]. Props desrosj, irozum, jorbin. Fixes #65722. git-svn-id: https://develop.svn.wordpress.org/trunk@63163 602fd350-edb4-49c9-b593-d223f7449a82 --- .../workflows/reusable-phpunit-tests-v3.yml | 17 +------ tools/local-env/scripts/docker.js | 44 ++++++++++++++----- 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/.github/workflows/reusable-phpunit-tests-v3.yml b/.github/workflows/reusable-phpunit-tests-v3.yml index 1c09113810dd3..4f7addcd4e60e 100644 --- a/.github/workflows/reusable-phpunit-tests-v3.yml +++ b/.github/workflows/reusable-phpunit-tests-v3.yml @@ -203,21 +203,8 @@ jobs: run: | docker -v - - name: Pull Docker images (with retry) - run: | - for attempt in 1 2 3; do - if npm run env:pull; then - break - fi - - if [ "$attempt" -eq 3 ]; then - echo "npm run env:pull failed after $attempt attempts." - exit 1 - fi - - echo "npm run env:pull failed (attempt $attempt); retrying..." - sleep $(( attempt * 10 )) - done + - name: Pull Docker images + run: npm run env:pull - name: Start Docker environment run: | diff --git a/tools/local-env/scripts/docker.js b/tools/local-env/scripts/docker.js index c7b11f0058424..6a4bd157689e1 100644 --- a/tools/local-env/scripts/docker.js +++ b/tools/local-env/scripts/docker.js @@ -25,17 +25,39 @@ if ( dockerCommand.includes( 'cli' ) && dockerCommand.includes( 'db' ) && ! dock dockerCommand.push( '--defaults' ); } +const composeArgs = [ + 'compose', + ...composeFiles + .map( ( composeFile ) => [ '-f', composeFile ] ) + .flat(), + ...dockerCommand, +]; + +// Failures during image pulls are re-attempted to rule out registry rate limits and network issues. +const maxAttempts = 'pull' === dockerCommand[0] ? 3 : 1; + // Execute any Docker compose command passed to this script. -const returns = spawnSync( - 'docker', - [ - 'compose', - ...composeFiles - .map( ( composeFile ) => [ '-f', composeFile ] ) - .flat(), - ...dockerCommand, - ], - { stdio: 'inherit' } -); +let returns; +for ( let attempt = 1; attempt <= maxAttempts; attempt++ ) { + returns = spawnSync( 'docker', composeArgs, { stdio: 'inherit' } ); + + if ( 0 === returns.status ) { + break; + } + + if ( attempt === maxAttempts ) { + if ( maxAttempts > 1 ) { + console.log( `\ndocker compose ${ dockerCommand[0] } failed after ${ attempt } attempts.` ); + } + + break; + } + + const delay = attempt * 10; + console.log( `\ndocker compose ${ dockerCommand[0] } failed (attempt ${ attempt } of ${ maxAttempts }). Retrying in ${ delay } seconds...\n` ); + + // Sleep synchronously so the retry loop stays in order without going async. + Atomics.wait( new Int32Array( new SharedArrayBuffer( 4 ) ), 0, 0, delay * 1000 ); +} process.exit( returns.status ); From 65ab0183371d61d9f02a6173ef48e023f77360f1 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Mon, 10 Aug 2026 22:26:55 +0000 Subject: [PATCH 204/634] Build/Test Tools: Post-branching updates for `trunk`. Reviewed by jorbin Props wildworks, desrosj, joedolson, jorbin. See #65844. git-svn-id: https://develop.svn.wordpress.org/trunk@63167 602fd350-edb4-49c9-b593-d223f7449a82 --- .github/workflows/check-built-files.yml | 2 +- .github/workflows/cleanup-pull-requests.yml | 2 +- .github/workflows/coding-standards.yml | 6 +++--- .github/workflows/end-to-end-tests.yml | 4 ++-- .github/workflows/javascript-tests.yml | 4 ++-- .github/workflows/javascript-type-checking.yml | 4 ++-- .github/workflows/local-docker-environment.yml | 6 +++--- .github/workflows/performance.yml | 6 +++--- .github/workflows/php-compatibility.yml | 4 ++-- .github/workflows/phpstan-static-analysis.yml | 4 ++-- .github/workflows/phpunit-tests.yml | 14 +++++++------- .github/workflows/test-build-processes.yml | 6 +++--- .github/workflows/test-old-branches.yml | 12 ++++++++---- .github/workflows/upgrade-develop-testing.yml | 12 ++++++------ .github/workflows/upgrade-testing.yml | 2 +- .github/workflows/workflow-lint.yml | 4 ++-- .version-support-mysql.json | 8 ++++++++ .version-support-php.json | 9 +++++++++ SECURITY.md | 1 + composer.json | 2 +- package-lock.json | 4 ++-- package.json | 2 +- src/wp-includes/version.php | 2 +- 23 files changed, 71 insertions(+), 49 deletions(-) diff --git a/.github/workflows/check-built-files.yml b/.github/workflows/check-built-files.yml index 01a239c4eb3b0..3f9ae477c2b3d 100644 --- a/.github/workflows/check-built-files.yml +++ b/.github/workflows/check-built-files.yml @@ -49,6 +49,6 @@ jobs: check-for-built-file-changes: name: Check built files if: ${{ github.repository == 'wordpress/wordpress-develop' }} - uses: ./.github/workflows/reusable-check-built-files.yml + uses: WordPress/wordpress-develop/.github/workflows/reusable-check-built-files.yml@trunk permissions: contents: read diff --git a/.github/workflows/cleanup-pull-requests.yml b/.github/workflows/cleanup-pull-requests.yml index 578710dcf56ac..6c8d38e67b0b7 100644 --- a/.github/workflows/cleanup-pull-requests.yml +++ b/.github/workflows/cleanup-pull-requests.yml @@ -25,4 +25,4 @@ jobs: permissions: pull-requests: write if: ${{ github.repository == 'WordPress/wordpress-develop' }} - uses: ./.github/workflows/reusable-cleanup-pull-requests.yml + uses: WordPress/wordpress-develop/.github/workflows/reusable-cleanup-pull-requests.yml@trunk diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 809abd1da9230..d75cc99eaf920 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -47,7 +47,7 @@ jobs: # Runs the PHP coding standards checks. phpcs: name: Coding standards - uses: ./.github/workflows/reusable-coding-standards-php.yml + uses: WordPress/wordpress-develop/.github/workflows/reusable-coding-standards-php.yml@trunk permissions: contents: read if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }} @@ -55,14 +55,14 @@ jobs: # Runs the JavaScript coding standards checks. jshint: name: Coding standards - uses: ./.github/workflows/reusable-coding-standards-javascript.yml + uses: WordPress/wordpress-develop/.github/workflows/reusable-coding-standards-javascript.yml@trunk permissions: contents: read if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }} slack-notifications: name: Slack Notifications - uses: ./.github/workflows/slack-notifications.yml + uses: WordPress/wordpress-develop/.github/workflows/slack-notifications.yml@trunk permissions: actions: read contents: read diff --git a/.github/workflows/end-to-end-tests.yml b/.github/workflows/end-to-end-tests.yml index 890314f25be49..ee60975b39a0d 100644 --- a/.github/workflows/end-to-end-tests.yml +++ b/.github/workflows/end-to-end-tests.yml @@ -54,7 +54,7 @@ jobs: # Runs the end-to-end test suite. e2e-tests: name: ${{ matrix.label }} - uses: ./.github/workflows/reusable-end-to-end-tests.yml + uses: WordPress/wordpress-develop/.github/workflows/reusable-end-to-end-tests.yml@trunk permissions: contents: read if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }} @@ -69,7 +69,7 @@ jobs: slack-notifications: name: Slack Notifications - uses: ./.github/workflows/slack-notifications.yml + uses: WordPress/wordpress-develop/.github/workflows/slack-notifications.yml@trunk permissions: actions: read contents: read diff --git a/.github/workflows/javascript-tests.yml b/.github/workflows/javascript-tests.yml index 8d96c826d7a57..933bfcd5f8313 100644 --- a/.github/workflows/javascript-tests.yml +++ b/.github/workflows/javascript-tests.yml @@ -50,14 +50,14 @@ jobs: # Runs the WordPress Core JavaScript tests. test-js: name: QUnit Tests - uses: ./.github/workflows/reusable-javascript-tests.yml + uses: WordPress/wordpress-develop/.github/workflows/reusable-javascript-tests.yml@trunk permissions: contents: read if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }} slack-notifications: name: Slack Notifications - uses: ./.github/workflows/slack-notifications.yml + uses: WordPress/wordpress-develop/.github/workflows/slack-notifications.yml@trunk permissions: actions: read contents: read diff --git a/.github/workflows/javascript-type-checking.yml b/.github/workflows/javascript-type-checking.yml index 2572bb4c2fe36..940b48e25ae0a 100644 --- a/.github/workflows/javascript-type-checking.yml +++ b/.github/workflows/javascript-type-checking.yml @@ -43,14 +43,14 @@ jobs: # Runs JavaScript type checking. typecheck: name: JavaScript type checking - uses: ./.github/workflows/reusable-javascript-type-checking-v1.yml + uses: WordPress/wordpress-develop/.github/workflows/reusable-javascript-type-checking-v1.yml@trunk permissions: contents: read if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }} slack-notifications: name: Slack Notifications - uses: ./.github/workflows/slack-notifications.yml + uses: WordPress/wordpress-develop/.github/workflows/slack-notifications.yml@trunk permissions: actions: read contents: read diff --git a/.github/workflows/local-docker-environment.yml b/.github/workflows/local-docker-environment.yml index 856db171726b6..a6aa2bae00803 100644 --- a/.github/workflows/local-docker-environment.yml +++ b/.github/workflows/local-docker-environment.yml @@ -76,7 +76,7 @@ jobs: # build-test-matrix: name: Build Test Matrix - uses: ./.github/workflows/reusable-support-json-reader-v1.yml + uses: WordPress/wordpress-develop/.github/workflows/reusable-support-json-reader-v1.yml@trunk permissions: contents: read if: ${{ github.repository == 'WordPress/wordpress-develop' }} @@ -86,7 +86,7 @@ jobs: # Tests the local Docker environment. environment-tests-mysql: name: PHP ${{ matrix.php }} - uses: ./.github/workflows/reusable-test-local-docker-environment-v1.yml + uses: WordPress/wordpress-develop/.github/workflows/reusable-test-local-docker-environment-v1.yml@trunk permissions: contents: read needs: [ build-test-matrix ] @@ -122,7 +122,7 @@ jobs: slack-notifications: name: Slack Notifications - uses: ./.github/workflows/slack-notifications.yml + uses: WordPress/wordpress-develop/.github/workflows/slack-notifications.yml@trunk permissions: actions: read contents: read diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml index 3690e6822512f..f9c86e7aaefae 100644 --- a/.github/workflows/performance.yml +++ b/.github/workflows/performance.yml @@ -91,7 +91,7 @@ jobs: # Runs the performance test suite. performance: name: ${{ matrix.multisite && 'Multisite' || 'Single Site' }} ${{ matrix.memcached && 'Memcached' || 'Default' }} - uses: ./.github/workflows/reusable-performance-test-v2.yml + uses: WordPress/wordpress-develop/.github/workflows/reusable-performance-test-v2.yml@trunk needs: [ determine-matrix ] permissions: contents: read @@ -109,7 +109,7 @@ jobs: compare: name: ${{ matrix.label }} - uses: ./.github/workflows/reusable-performance-report-v2.yml + uses: WordPress/wordpress-develop/.github/workflows/reusable-performance-report-v2.yml@trunk needs: [ determine-matrix, performance ] permissions: contents: read @@ -130,7 +130,7 @@ jobs: slack-notifications: name: Slack Notifications - uses: ./.github/workflows/slack-notifications.yml + uses: WordPress/wordpress-develop/.github/workflows/slack-notifications.yml@trunk permissions: actions: read contents: read diff --git a/.github/workflows/php-compatibility.yml b/.github/workflows/php-compatibility.yml index 9e30670cdae7e..78f23bbcfe76d 100644 --- a/.github/workflows/php-compatibility.yml +++ b/.github/workflows/php-compatibility.yml @@ -39,14 +39,14 @@ jobs: # Runs PHP compatibility testing. php-compatibility: name: Check PHP compatibility - uses: ./.github/workflows/reusable-php-compatibility.yml + uses: WordPress/wordpress-develop/.github/workflows/reusable-php-compatibility.yml@trunk permissions: contents: read if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }} slack-notifications: name: Slack Notifications - uses: ./.github/workflows/slack-notifications.yml + uses: WordPress/wordpress-develop/.github/workflows/slack-notifications.yml@trunk permissions: actions: read contents: read diff --git a/.github/workflows/phpstan-static-analysis.yml b/.github/workflows/phpstan-static-analysis.yml index 7d7043ac0c1ec..352b78e4c8f43 100644 --- a/.github/workflows/phpstan-static-analysis.yml +++ b/.github/workflows/phpstan-static-analysis.yml @@ -39,14 +39,14 @@ jobs: # Runs PHPStan Static Analysis. phpstan: name: PHP static analysis - uses: ./.github/workflows/reusable-phpstan-static-analysis-v1.yml + uses: WordPress/wordpress-develop/.github/workflows/reusable-phpstan-static-analysis-v1.yml@trunk permissions: contents: read if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }} slack-notifications: name: Slack Notifications - uses: ./.github/workflows/slack-notifications.yml + uses: WordPress/wordpress-develop/.github/workflows/slack-notifications.yml@trunk permissions: actions: read contents: read diff --git a/.github/workflows/phpunit-tests.yml b/.github/workflows/phpunit-tests.yml index 94a2ddf187d9e..fb5da98d1e87c 100644 --- a/.github/workflows/phpunit-tests.yml +++ b/.github/workflows/phpunit-tests.yml @@ -55,7 +55,7 @@ jobs: # Downloads and verifies the Gutenberg build once for all PHPUnit jobs. prepare-gutenberg: name: Prepare Gutenberg Assets - uses: ./.github/workflows/reusable-prepare-gutenberg.yml + uses: WordPress/wordpress-develop/.github/workflows/reusable-prepare-gutenberg.yml@trunk permissions: contents: read if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }} @@ -69,7 +69,7 @@ jobs: # test-with-mysql: name: PHP ${{ matrix.php }} - uses: ./.github/workflows/reusable-phpunit-tests-v3.yml + uses: WordPress/wordpress-develop/.github/workflows/reusable-phpunit-tests-v3.yml@trunk needs: prepare-gutenberg permissions: contents: read @@ -152,7 +152,7 @@ jobs: # test-with-mariadb: name: PHP ${{ matrix.php }} - uses: ./.github/workflows/reusable-phpunit-tests-v3.yml + uses: WordPress/wordpress-develop/.github/workflows/reusable-phpunit-tests-v3.yml@trunk needs: prepare-gutenberg permissions: contents: read @@ -210,7 +210,7 @@ jobs: # test-innovation-releases: name: PHP ${{ matrix.php }} - uses: ./.github/workflows/reusable-phpunit-tests-v3.yml + uses: WordPress/wordpress-develop/.github/workflows/reusable-phpunit-tests-v3.yml@trunk needs: prepare-gutenberg permissions: contents: read @@ -257,7 +257,7 @@ jobs: # html-api-test-groups: name: ${{ matrix.label }} - uses: ./.github/workflows/reusable-phpunit-tests-v3.yml + uses: WordPress/wordpress-develop/.github/workflows/reusable-phpunit-tests-v3.yml@trunk needs: prepare-gutenberg permissions: contents: read @@ -291,7 +291,7 @@ jobs: # limited-matrix-for-forks: name: PHP ${{ matrix.php }} - uses: ./.github/workflows/reusable-phpunit-tests-v3.yml + uses: WordPress/wordpress-develop/.github/workflows/reusable-phpunit-tests-v3.yml@trunk needs: prepare-gutenberg permissions: contents: read @@ -349,7 +349,7 @@ jobs: slack-notifications: name: Slack Notifications - uses: ./.github/workflows/slack-notifications.yml + uses: WordPress/wordpress-develop/.github/workflows/slack-notifications.yml@trunk permissions: actions: read contents: read diff --git a/.github/workflows/test-build-processes.yml b/.github/workflows/test-build-processes.yml index d344c5371bad5..64f6c63481914 100644 --- a/.github/workflows/test-build-processes.yml +++ b/.github/workflows/test-build-processes.yml @@ -48,7 +48,7 @@ jobs: # Tests the WordPress Core build process. test-core-build-process: name: Core running from ${{ matrix.directory }} - uses: ./.github/workflows/reusable-test-core-build-process.yml + uses: WordPress/wordpress-develop/.github/workflows/reusable-test-core-build-process.yml@trunk permissions: contents: read if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }} @@ -83,7 +83,7 @@ jobs: # See https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability. test-core-build-process-additional-os: name: Core running from ${{ matrix.directory }} - uses: ./.github/workflows/reusable-test-core-build-process.yml + uses: WordPress/wordpress-develop/.github/workflows/reusable-test-core-build-process.yml@trunk permissions: contents: read if: ${{ github.repository == 'WordPress/wordpress-develop' }} @@ -98,7 +98,7 @@ jobs: slack-notifications: name: Slack Notifications - uses: ./.github/workflows/slack-notifications.yml + uses: WordPress/wordpress-develop/.github/workflows/slack-notifications.yml@trunk permissions: actions: read contents: read diff --git a/.github/workflows/test-old-branches.yml b/.github/workflows/test-old-branches.yml index 054f1e98a2a1b..b5bef1b88c0bc 100644 --- a/.github/workflows/test-old-branches.yml +++ b/.github/workflows/test-old-branches.yml @@ -25,7 +25,7 @@ on: permissions: {} env: - CURRENTLY_SUPPORTED_BRANCH: '7.0' + CURRENTLY_SUPPORTED_BRANCH: '7.1' jobs: dispatch-workflows-for-old-branches: @@ -45,13 +45,15 @@ jobs: 'test-build-processes.yml' ] branch: [ - '7.0', + '7.1', '7.0', '6.9', '6.8', '6.7', '6.6', '6.5', '6.4', '6.3', '6.2', '6.1','6.0', '5.9', '5.8', '5.7', '5.6', '5.5', '5.4', '5.3', '5.2', '5.1', '5.0', '4.9', '4.8', '4.7' ] include: # PHP Compatibility testing was introduced in 5.5. + - branch: '7.1' + workflow: 'php-compatibility.yml' - branch: '7.0' workflow: 'php-compatibility.yml' - branch: '6.9' @@ -88,6 +90,8 @@ jobs: # End-to-end testing was introduced in 5.3 but was later removed as there were no meaningful assertions. # Starting in 5.8 with #52905, some additional tests with real assertions were introduced. # Branches 5.8 and newer should be tested to confirm no regressions are introduced. + - branch: '7.1' + workflow: 'end-to-end-tests.yml' - branch: '7.0' workflow: 'end-to-end-tests.yml' - branch: '6.9' @@ -118,9 +122,9 @@ jobs: # Performance testing was introduced in 6.2 using Puppeteer but was overhauled to use Playwright instead in 6.4. # Since the workflow frequently failed for 6.2 and 6.3 due to the flaky nature of the Puppeteer tests, # the workflow was removed from those two branches. - - branch: '7.0' + - branch: '7.1' workflow: 'performance.yml' - - branch: '6.9' + - branch: '7.0' workflow: 'performance.yml' # Run all branches monthly, but only the currently supported one twice per month. diff --git a/.github/workflows/upgrade-develop-testing.yml b/.github/workflows/upgrade-develop-testing.yml index 831b470beb418..b36b2c56b0d34 100644 --- a/.github/workflows/upgrade-develop-testing.yml +++ b/.github/workflows/upgrade-develop-testing.yml @@ -43,7 +43,7 @@ jobs: # Build WordPress from the current branch ready for the upgrade tests. build: name: Build - uses: ./.github/workflows/reusable-build-package.yml + uses: WordPress/wordpress-develop/.github/workflows/reusable-build-package.yml@trunk if: ${{ startsWith( github.repository, 'WordPress/' ) && ( github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' ) }} permissions: contents: read @@ -59,7 +59,7 @@ jobs: # being updated to keep the matrix as small as is reasonable. upgrade-tests-develop: name: Upgrade from ${{ matrix.wp }} - uses: ./.github/workflows/reusable-upgrade-testing.yml + uses: WordPress/wordpress-develop/.github/workflows/reusable-upgrade-testing.yml@trunk if: ${{ github.repository == 'WordPress/wordpress-develop' }} needs: [ build ] permissions: @@ -72,7 +72,7 @@ jobs: db-type: [ 'mysql' ] db-version: [ '5.7', '8.4' ] # WordPress 5.3 is the oldest version that supports PHP 7.4. - wp: [ '5.3', '6.9', '7.0' ] + wp: [ '5.3', '6.9', '7.0', '7.1-RC2' ] multisite: [ false, true ] with: os: ${{ matrix.os }} @@ -86,7 +86,7 @@ jobs: # Run a limited set of upgrade tests for the current branch on forks. upgrade-tests-develop-forks: name: Upgrade from ${{ matrix.wp }} - uses: ./.github/workflows/reusable-upgrade-testing.yml + uses: WordPress/wordpress-develop/.github/workflows/reusable-upgrade-testing.yml@trunk if: ${{ github.repository != 'WordPress/wordpress-develop' }} needs: [ build ] permissions: @@ -98,7 +98,7 @@ jobs: php: [ '7.4', '8.4' ] db-type: [ 'mysql' ] db-version: [ '8.4' ] - wp: [ '6.9', '7.0' ] + wp: [ '6.9', '7.0', '7.1-RC2' ] multisite: [ false, true ] with: os: ${{ matrix.os }} @@ -111,7 +111,7 @@ jobs: slack-notifications: name: Slack Notifications - uses: ./.github/workflows/slack-notifications.yml + uses: WordPress/wordpress-develop/.github/workflows/slack-notifications.yml@trunk permissions: actions: read contents: read diff --git a/.github/workflows/upgrade-testing.yml b/.github/workflows/upgrade-testing.yml index 930a82b3139b1..9a9c239e3093d 100644 --- a/.github/workflows/upgrade-testing.yml +++ b/.github/workflows/upgrade-testing.yml @@ -71,7 +71,7 @@ jobs: php: [ '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5' ] db-type: [ 'mysql' ] db-version: [ '5.7', '8.0', '8.4', '9.7' ] - wp: [ '6.9', '7.0' ] + wp: [ '6.9', '7.0', '7.1-RC2' ] multisite: [ false, true ] with: os: ${{ matrix.os }} diff --git a/.github/workflows/workflow-lint.yml b/.github/workflows/workflow-lint.yml index acb74cf5971c7..d86b62ca79646 100644 --- a/.github/workflows/workflow-lint.yml +++ b/.github/workflows/workflow-lint.yml @@ -32,7 +32,7 @@ permissions: {} jobs: lint: name: Lint GitHub Action files - uses: ./.github/workflows/reusable-workflow-lint.yml + uses: WordPress/wordpress-develop/.github/workflows/reusable-workflow-lint.yml@trunk if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }} permissions: security-events: write @@ -41,7 +41,7 @@ jobs: slack-notifications: name: Slack Notifications - uses: ./.github/workflows/slack-notifications.yml + uses: WordPress/wordpress-develop/.github/workflows/slack-notifications.yml@trunk permissions: actions: read contents: read diff --git a/.version-support-mysql.json b/.version-support-mysql.json index 7ab8aa38df392..c7bda38ff5fe9 100644 --- a/.version-support-mysql.json +++ b/.version-support-mysql.json @@ -1,4 +1,12 @@ { + "7-2": [ + "9.7", + "8.4", + "8.0", + "5.7", + "5.6", + "5.5" + ], "7-1": [ "9.7", "8.4", diff --git a/.version-support-php.json b/.version-support-php.json index de510694c65c9..fc0128345fdb5 100644 --- a/.version-support-php.json +++ b/.version-support-php.json @@ -1,4 +1,13 @@ { + "7-2": [ + "7.4", + "8.0", + "8.1", + "8.2", + "8.3", + "8.4", + "8.5" + ], "7-1": [ "7.4", "8.0", diff --git a/SECURITY.md b/SECURITY.md index 20b9b8e4b3890..13e8007009af8 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -10,6 +10,7 @@ Full details of the WordPress Security Policy and the list of covered projects a | Version | Supported | |---------| --------- | +| 7.1.x | Yes | | 7.0.x | Yes | | 6.9.x | Yes | | 6.8.x | Yes | diff --git a/composer.json b/composer.json index 87a4463017a0c..34a8d980259f1 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "wordpress/wordpress", - "version": "7.1.0", + "version": "7.2.0", "license": "GPL-2.0-or-later", "description": "WordPress is open source software you can use to create a beautiful website, blog, or app.", "homepage": "https://wordpress.org", diff --git a/package-lock.json b/package-lock.json index 78985e8f955c0..fe92d5381d923 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "WordPress", - "version": "7.1.0", + "version": "7.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "WordPress", - "version": "7.1.0", + "version": "7.2.0", "license": "GPL-2.0-or-later", "dependencies": { "backbone": "1.6.1", diff --git a/package.json b/package.json index 7b8cdfe8eb8c0..e87e95546a204 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "WordPress", - "version": "7.1.0", + "version": "7.2.0", "description": "WordPress is open source software you can use to create a beautiful website, blog, or app.", "repository": { "type": "svn", diff --git a/src/wp-includes/version.php b/src/wp-includes/version.php index 044d90e4d2487..0b5627887c4d3 100644 --- a/src/wp-includes/version.php +++ b/src/wp-includes/version.php @@ -16,7 +16,7 @@ * * @global string $wp_version */ -$wp_version = '7.1-RC2-63095-src'; +$wp_version = '7.2-alpha-63166-src'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. From 780b1d5cb329b3f5ec7427d7ef8e7a2f8e7b4853 Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Mon, 10 Aug 2026 23:29:54 +0000 Subject: [PATCH 205/634] Code Quality: Correct the case of the `MO` class in a `WP_Locale_Switcher` docblock. Corrects the `@global` annotation for `$l10n` in `WP_Locale_Switcher::load_translations()`, which documented the array as `Mo[]`. The class is `MO`, defined in `wp-includes/pomo/mo.php`; no class named `Mo` exists. Every other `@global` annotation for `$l10n` in core already uses `MO[]`, so this was the sole outlier. The description is also clarified to note that the array is keyed by text domain. This was the only remaining `class.nameCase` occurrence, so the change empties `tests/phpstan/baselines/class.nameCase.neon`. As the baseline header directs, the file is deleted along with its `includes` entry in `phpstan.neon.dist`. The baseline was regenerated with: {{{ composer phpstan:baselines -- --identifier=class.nameCase }}} Developed in https://github.com/WordPress/wordpress-develop/pull/12938. Follow-up to r38961. Props callumbw95, westonruter, mindctrl. See #65817. git-svn-id: https://develop.svn.wordpress.org/trunk@63169 602fd350-edb4-49c9-b593-d223f7449a82 --- phpstan.neon.dist | 1 - src/wp-includes/class-wp-locale-switcher.php | 2 +- tests/phpstan/baselines/class.nameCase.neon | 25 -------------------- 3 files changed, 1 insertion(+), 27 deletions(-) delete mode 100644 tests/phpstan/baselines/class.nameCase.neon diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 3dcf0f6c2c0de..3258c2d9c73e8 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -39,7 +39,6 @@ includes: - tests/phpstan/baselines/booleanOr.alwaysTrue.neon - tests/phpstan/baselines/booleanOr.rightAlwaysTrue.neon - tests/phpstan/baselines/catch.neverThrown.neon - - tests/phpstan/baselines/class.nameCase.neon - tests/phpstan/baselines/class.notFound.neon - tests/phpstan/baselines/deadCode.unreachable.neon - tests/phpstan/baselines/empty.offset.neon diff --git a/src/wp-includes/class-wp-locale-switcher.php b/src/wp-includes/class-wp-locale-switcher.php index 55edef3c9c055..05fbc07a903df 100644 --- a/src/wp-includes/class-wp-locale-switcher.php +++ b/src/wp-includes/class-wp-locale-switcher.php @@ -238,7 +238,7 @@ public function filter_locale( $locale ) { * * @since 4.7.0 * - * @global Mo[] $l10n An array of all currently loaded text domains. + * @global MO[] $l10n An array of all currently loaded text domains, keyed by text domain. * * @param string $locale The locale to load translations for. */ diff --git a/tests/phpstan/baselines/class.nameCase.neon b/tests/phpstan/baselines/class.nameCase.neon deleted file mode 100644 index dd88c5b677aa8..0000000000000 --- a/tests/phpstan/baselines/class.nameCase.neon +++ /dev/null @@ -1,25 +0,0 @@ -# PHPStan baseline for the `class.nameCase` errors in WordPress core. -# -# https://phpstan.org/error-identifiers/class.nameCase -# -# Each entry is scoped to a single file and carries an exact occurrence count, -# so that a new instance is reported as a new error rather than being absorbed -# silently. Fixing an occurrence therefore means decrementing or removing its -# entry here as part of the same change. -# -# The goal is to empty this file and delete it, along with the `includes` entry -# for it in phpstan.neon.dist. -# -# Generated by `composer phpstan:baselines`. Do not edit by hand; regenerate with -# -# composer phpstan:baselines -- --identifier=class.nameCase -# -# which reruns the analysis with this file suppressed so the errors surface again. - -parameters: - ignoreErrors: - - - message: '#^Class MO referenced with incorrect case\: Mo\.$#' - identifier: class.nameCase - count: 1 - path: ../../../src/wp-includes/class-wp-locale-switcher.php From e8f74557e94e1b98d144aafe5b06ddcb4d58955c Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 11 Aug 2026 00:13:22 +0000 Subject: [PATCH 206/634] Build/Test Tools: Add `@phpstan-assert` on `assertWPError` and `assertNotWPError`. Follow-up to r63005. See #65817. git-svn-id: https://develop.svn.wordpress.org/trunk@63170 602fd350-edb4-49c9-b593-d223f7449a82 --- tests/phpunit/includes/abstract-testcase.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/phpunit/includes/abstract-testcase.php b/tests/phpunit/includes/abstract-testcase.php index 98b3456935716..c87e5e7fd077c 100644 --- a/tests/phpunit/includes/abstract-testcase.php +++ b/tests/phpunit/includes/abstract-testcase.php @@ -874,6 +874,8 @@ public function doing_it_wrong_run( $function_name, $message, $version ) { * * @param mixed $actual The value to check. * @param string $message Optional. Message to display when the assertion fails. + * + * @phpstan-assert WP_Error $actual */ public function assertWPError( $actual, $message = '' ) { $this->assertInstanceOf( 'WP_Error', $actual, $message ); @@ -884,6 +886,8 @@ public function assertWPError( $actual, $message = '' ) { * * @param mixed $actual The value to check. * @param string $message Optional. Message to display when the assertion fails. + * + * @phpstan-assert !WP_Error $actual */ public function assertNotWPError( $actual, $message = '' ) { if ( is_wp_error( $actual ) ) { From 588cd50fc10be940a3b629a112521e4554662867 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 11 Aug 2026 00:32:19 +0000 Subject: [PATCH 207/634] Editor: Hoist `count()` out of `for` loop conditions. A `for` condition is evaluated once per iteration plus once more to terminate the loop, so `$index < count( $scripts )` calls `count()` n + 1 times to walk an n-element array whose length never changes. Compute the bound once in the loop initializer instead, matching the idiom already used elsewhere in core. Developed in https://github.com/WordPress/wordpress-develop/pull/12837. Follow-up to r54155, r57565, r58328. Props mukesh27, afercia, westonruter. Fixes #65811. git-svn-id: https://develop.svn.wordpress.org/trunk@63171 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/blocks.php | 6 +++--- src/wp-includes/class-wp-theme-json.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php index a0360ffdc8bf8..f2df7226a6d78 100644 --- a/src/wp-includes/blocks.php +++ b/src/wp-includes/blocks.php @@ -677,7 +677,7 @@ function register_block_type_from_metadata( $file_or_folder, $args = array() ) { $scripts = $metadata[ $metadata_field_name ]; $processed_scripts = array(); if ( is_array( $scripts ) ) { - for ( $index = 0; $index < count( $scripts ); $index++ ) { + for ( $index = 0, $length = count( $scripts ); $index < $length; $index++ ) { $result = register_block_script_handle( $metadata, $metadata_field_name, @@ -711,7 +711,7 @@ function register_block_type_from_metadata( $file_or_folder, $args = array() ) { $modules = $metadata[ $metadata_field_name ]; $processed_modules = array(); if ( is_array( $modules ) ) { - for ( $index = 0; $index < count( $modules ); $index++ ) { + for ( $index = 0, $length = count( $modules ); $index < $length; $index++ ) { $result = register_block_script_module_id( $metadata, $metadata_field_name, @@ -747,7 +747,7 @@ function register_block_type_from_metadata( $file_or_folder, $args = array() ) { $styles = $metadata[ $metadata_field_name ]; $processed_styles = array(); if ( is_array( $styles ) ) { - for ( $index = 0; $index < count( $styles ); $index++ ) { + for ( $index = 0, $length = count( $styles ); $index < $length; $index++ ) { $result = register_block_style_handle( $metadata, $metadata_field_name, diff --git a/src/wp-includes/class-wp-theme-json.php b/src/wp-includes/class-wp-theme-json.php index 1517605bf4aa7..7175d7a88747d 100644 --- a/src/wp-includes/class-wp-theme-json.php +++ b/src/wp-includes/class-wp-theme-json.php @@ -5386,7 +5386,7 @@ public function set_spacing_sizes() { // If there are 7 or fewer steps in the scale revert to numbers for labels instead of t-shirt sizes. if ( $spacing_scale['steps'] <= 7 ) { - for ( $spacing_sizes_count = 0; $spacing_sizes_count < count( $spacing_sizes ); $spacing_sizes_count++ ) { + for ( $spacing_sizes_count = 0, $spacing_sizes_length = count( $spacing_sizes ); $spacing_sizes_count < $spacing_sizes_length; $spacing_sizes_count++ ) { $spacing_sizes[ $spacing_sizes_count ]['name'] = (string) ( $spacing_sizes_count + 1 ); } } From 7416a5cf513cb6502e3e3386109af13776fc35b4 Mon Sep 17 00:00:00 2001 From: Aki Hamano Date: Tue, 11 Aug 2026 02:37:22 +0000 Subject: [PATCH 208/634] Tests: Add unit tests for `wp_schedule_delete_old_privacy_export_files()`. Adds unit test coverage for the scheduling of the recurring cleanup of expired personal data export files. Developed in https://github.com/WordPress/wordpress-develop/pull/5550 Props desrosj, masteradhoc, mindctrl, pbearne, roshniahuja14, wildworks. Fixes #59707. git-svn-id: https://develop.svn.wordpress.org/trunk@63172 602fd350-edb4-49c9-b593-d223f7449a82 --- .../wpScheduleDeleteOldPrivacyExportFiles.php | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 tests/phpunit/tests/functions/wpScheduleDeleteOldPrivacyExportFiles.php diff --git a/tests/phpunit/tests/functions/wpScheduleDeleteOldPrivacyExportFiles.php b/tests/phpunit/tests/functions/wpScheduleDeleteOldPrivacyExportFiles.php new file mode 100644 index 0000000000000..e5786ad148ff0 --- /dev/null +++ b/tests/phpunit/tests/functions/wpScheduleDeleteOldPrivacyExportFiles.php @@ -0,0 +1,75 @@ +assertFalse( wp_next_scheduled( 'wp_privacy_delete_old_export_files' ), 'no export should be scheduled' ); + wp_schedule_delete_old_privacy_export_files(); + $this->assertIsInt( wp_next_scheduled( 'wp_privacy_delete_old_export_files' ), 'export should be scheduled' ); + } + + /** + * check that no schedule is set when WP is in installing mode + * + * @ticket 59707 + */ + public function test_wp_schedule_delete_old_privacy_export_files_is_installing() { + $this->assertFalse( wp_next_scheduled( 'wp_privacy_delete_old_export_files' ), 'no export should be scheduled' ); + + // set to installing mode + $prior = wp_installing(); + wp_installing( true ); + + wp_schedule_delete_old_privacy_export_files(); + + wp_installing( $prior ); + + $this->assertFalse( wp_next_scheduled( 'wp_privacy_delete_old_export_files' ), 'no export should be scheduled while installing' ); + } + + /** + * Check that calling the function when already scheduled does not create a duplicate. + * + * @ticket 59707 + */ + public function test_wp_schedule_delete_old_privacy_export_files_already_scheduled() { + // Schedule ahead of time() so that a duplicate would land on a different timestamp. + wp_schedule_event( strtotime( '+1 hour' ), 'hourly', 'wp_privacy_delete_old_export_files' ); + + // Take a snapshot of the cron option while the event is scheduled. + $expected = _get_cron_array(); + + // The event is already scheduled, so this call should be a no-op. + wp_schedule_delete_old_privacy_export_files(); + + // Check cron option is unchanged. + $this->assertSame( $expected, _get_cron_array(), 'the event should not be scheduled again' ); + } +} From 2b2b6a918784a67bb19c6e166fea0a683edba474 Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Tue, 11 Aug 2026 04:42:06 +0000 Subject: [PATCH 209/634] Docs: Reorder docblock annotations for send_confirmation_on_profile_email(). Moves the `@param` annotation below `@global` per the documentation standards. Props peterwilsoncc, mukesh27. See #64896. git-svn-id: https://develop.svn.wordpress.org/trunk@63173 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/user.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/user.php b/src/wp-includes/user.php index 76bce3966feb2..539240a42e9d2 100644 --- a/src/wp-includes/user.php +++ b/src/wp-includes/user.php @@ -3860,9 +3860,9 @@ function _wp_get_current_user() { * @since 4.9.0 This function was moved from wp-admin/includes/ms.php so it's no longer Multisite specific. * @since 7.0.3 Added the `$user_id` parameter, which is sent with the `personal_options_update` action. * - * @param int $user_id Optional. The ID of the user whose email is being changed. Defaults to `$_POST['user_id']` if set, otherwise 0. - * * @global WP_Error $errors WP_Error object. + * + * @param int $user_id Optional. The ID of the user whose email is being changed. Defaults to `$_POST['user_id']` if set, otherwise 0. */ function send_confirmation_on_profile_email( $user_id = 0 ) { global $errors; From 3397c1c6affe04066be060bf457510aebd91a28b Mon Sep 17 00:00:00 2001 From: Aki Hamano Date: Tue, 11 Aug 2026 06:04:38 +0000 Subject: [PATCH 210/634] Administration: Remove no-JS notices from route-based screens. The Fonts and Connectors screens no longer render their own heading and JavaScript-required notice. The generated page template now provides both for every route-based screen, so the per-screen markup only produced a duplicate heading and notice when JavaScript was disabled. Developed in: https://github.com/WordPress/wordpress-develop/pull/12946 Follow-up to [62954]. Props hbhalodia, wildworks. Fixes #65840. git-svn-id: https://develop.svn.wordpress.org/trunk@63174 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/font-library.php | 18 +----------------- src/wp-admin/options-connectors.php | 18 +----------------- 2 files changed, 2 insertions(+), 34 deletions(-) diff --git a/src/wp-admin/font-library.php b/src/wp-admin/font-library.php index 6129211f45545..abc2ea4f4da70 100644 --- a/src/wp-admin/font-library.php +++ b/src/wp-admin/font-library.php @@ -28,26 +28,10 @@ } // Set the page title -$title = _x( 'Fonts', 'Font Library admin page title' ); -$js_required_message = __( 'The Fonts screen requires JavaScript. Please enable JavaScript in your browser settings to install and manage fonts.' ); +$title = _x( 'Fonts', 'Font Library admin page title' ); require_once ABSPATH . 'wp-admin/admin-header.php'; -?> -
-

- 'error', - 'additional_classes' => array( 'hide-if-js' ), - ) - ); - ?> -
- -
-

- 'error', - 'additional_classes' => array( 'hide-if-js' ), - ) - ); - ?> -
- Date: Tue, 11 Aug 2026 06:13:39 +0000 Subject: [PATCH 211/634] Login and Registration: Clarify the "Remember Me" toggletip text. The help text on the login screen stated that the option reduces how often you are asked to log in. It actually extends how long you stay logged in before being asked again, so the wording now describes that behavior. Follow-up to [62741]. Props joedolson, johnbillion, sabernhardt, wildworks. Fixes #55343. git-svn-id: https://develop.svn.wordpress.org/trunk@63175 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-login.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-login.php b/src/wp-login.php index 0b1d2cff308ec..43689323647de 100644 --- a/src/wp-login.php +++ b/src/wp-login.php @@ -1548,7 +1548,7 @@ function wp_login_viewport_meta() { */ $rememberme_help_text = apply_filters( 'login_remember_me_help_text', - __( 'Selecting "Remember Me" reduces the number of times you’ll be asked to log in using this device. To keep your account secure, use this option only on your personal devices.' ) + __( 'Selecting "Remember Me" increases the length of time until you’re asked to log in again on this device. To keep your account secure, use this option only on your personal devices.' ) ); ?>

From b2ad18825fd09ed1686cf3f25eb919fd78e56df3 Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Tue, 11 Aug 2026 13:16:00 +0000 Subject: [PATCH 212/634] Code Quality: Use `isset()` instead of `in_array()` over `array_keys()` for key lookups. This updates several places in core that test whether an array has a given key: * `in_array( $key, array_keys( $array ), true )` allocates a complete copy of every key and walks it. * `isset( $array[ $key ] )`, on the other hand, does a single hash lookup in constant time with no allocation. Note: For arrays that main contain `null` values, [https://www.php.net/manual/en/function.array-key-exists.php#example-2 array_key_exists()] should be used instead. Developed in https://github.com/WordPress/wordpress-develop/pull/12929. Props mukesh27, siliconforks. Fixes #65842. git-svn-id: https://develop.svn.wordpress.org/trunk@63177 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/includes/class-theme-installer-skin.php | 2 +- src/wp-admin/includes/dashboard.php | 8 +++++--- src/wp-admin/nav-menus.php | 6 +++--- src/wp-includes/block-editor.php | 2 +- src/wp-includes/link-template.php | 2 +- src/wp-includes/media.php | 2 +- src/wp-includes/sitemaps.php | 8 ++++++-- 7 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/wp-admin/includes/class-theme-installer-skin.php b/src/wp-admin/includes/class-theme-installer-skin.php index 81e40122d5bc5..70f3452606fdd 100644 --- a/src/wp-admin/includes/class-theme-installer-skin.php +++ b/src/wp-admin/includes/class-theme-installer-skin.php @@ -248,7 +248,7 @@ private function do_overwrite() { $is_invalid_parent = false; if ( ! empty( $new_theme_data['Template'] ) ) { - $is_invalid_parent = ! in_array( $new_theme_data['Template'], array_keys( $all_themes ), true ); + $is_invalid_parent = ! isset( $all_themes[ $new_theme_data['Template'] ] ); } $rows = array( diff --git a/src/wp-admin/includes/dashboard.php b/src/wp-admin/includes/dashboard.php index 0fe5c62064b64..7a78025214f10 100644 --- a/src/wp-admin/includes/dashboard.php +++ b/src/wp-admin/includes/dashboard.php @@ -568,11 +568,13 @@ function wp_dashboard_quick_press( $message = false, $notice_type = 'error' ) { $post->post_title = ''; // Remove the auto draft title. } } else { - $post = get_default_post_to_edit( 'post', true ); - $user_id = get_current_user_id(); + $post = get_default_post_to_edit( 'post', true ); + $user_id = get_current_user_id(); + $user_blogs = get_blogs_of_user( $user_id ); + $current_blog_id = get_current_blog_id(); // Don't create an option if this is a super admin who does not belong to this site. - if ( in_array( get_current_blog_id(), array_keys( get_blogs_of_user( $user_id ) ), true ) ) { + if ( isset( $user_blogs[ $current_blog_id ] ) ) { update_user_option( $user_id, 'dashboard_quick_press_last_post_id', (int) $post->ID ); // Save post_ID. } } diff --git a/src/wp-admin/nav-menus.php b/src/wp-admin/nav-menus.php index 9998852d06d82..6a9925b0d4708 100644 --- a/src/wp-admin/nav-menus.php +++ b/src/wp-admin/nav-menus.php @@ -196,7 +196,7 @@ // If this menu item is a child of the previous. if ( ! empty( $menu_item_data['menu_item_parent'] ) - && in_array( (int) $menu_item_data['menu_item_parent'], array_keys( $dbids_to_orders ), true ) + && isset( $dbids_to_orders[ (int) $menu_item_data['menu_item_parent'] ] ) && isset( $orders_to_dbids[ $dbids_to_orders[ $menu_item_id ] - 1 ] ) && ( (int) $menu_item_data['menu_item_parent'] === $orders_to_dbids[ $dbids_to_orders[ $menu_item_id ] - 1 ] ) ) { @@ -230,7 +230,7 @@ ) { $_possible_parent_id = (int) get_post_meta( $orders_to_dbids[ $dbids_to_orders[ $parent_db_id ] - 1 ], '_menu_item_menu_item_parent', true ); - if ( in_array( $_possible_parent_id, array_keys( $dbids_to_orders ), true ) ) { + if ( isset( $dbids_to_orders[ $_possible_parent_id ] ) ) { $menu_item_data['menu_item_parent'] = $_possible_parent_id; } else { $menu_item_data['menu_item_parent'] = 0; @@ -256,7 +256,7 @@ // Else this menu item is not a child of the previous. } elseif ( empty( $menu_item_data['menu_order'] ) || empty( $menu_item_data['menu_item_parent'] ) - || ! in_array( (int) $menu_item_data['menu_item_parent'], array_keys( $dbids_to_orders ), true ) + || ! isset( $dbids_to_orders[ (int) $menu_item_data['menu_item_parent'] ] ) || empty( $orders_to_dbids[ $dbids_to_orders[ $menu_item_id ] - 1 ] ) || $orders_to_dbids[ $dbids_to_orders[ $menu_item_id ] - 1 ] !== (int) $menu_item_data['menu_item_parent'] ) { diff --git a/src/wp-includes/block-editor.php b/src/wp-includes/block-editor.php index c21e8d9e9feec..f08c934864916 100644 --- a/src/wp-includes/block-editor.php +++ b/src/wp-includes/block-editor.php @@ -184,7 +184,7 @@ function get_default_block_editor_settings() { } $default_size = get_option( 'image_default_size', 'large' ); - $image_default_size = in_array( $default_size, array_keys( $image_size_names ), true ) ? $default_size : 'large'; + $image_default_size = isset( $image_size_names[ $default_size ] ) ? $default_size : 'large'; $image_dimensions = array(); $all_sizes = wp_get_registered_image_subsizes(); diff --git a/src/wp-includes/link-template.php b/src/wp-includes/link-template.php index 223d6b5548fc6..484a8c8f8591c 100644 --- a/src/wp-includes/link-template.php +++ b/src/wp-includes/link-template.php @@ -3993,7 +3993,7 @@ function get_dashboard_url( $user_id = 0, $path = '', $scheme = 'admin' ) { } else { $current_blog = get_current_blog_id(); - if ( $current_blog && ( user_can( $user_id, 'manage_network' ) || in_array( $current_blog, array_keys( $blogs ), true ) ) ) { + if ( $current_blog && ( user_can( $user_id, 'manage_network' ) || isset( $blogs[ $current_blog ] ) ) ) { $url = admin_url( $path, $scheme ); } else { $active = get_active_blog_for_user( $user_id ); diff --git a/src/wp-includes/media.php b/src/wp-includes/media.php index a31e77b00e26c..075ca04700489 100644 --- a/src/wp-includes/media.php +++ b/src/wp-includes/media.php @@ -114,7 +114,7 @@ function image_constrain_size_for_editor( $width, $height, $size = 'medium', $co if ( (int) $content_width > 0 ) { $max_width = min( (int) $content_width, $max_width ); } - } elseif ( ! empty( $_wp_additional_image_sizes ) && in_array( $size, array_keys( $_wp_additional_image_sizes ), true ) ) { + } elseif ( isset( $_wp_additional_image_sizes[ $size ] ) ) { $max_width = (int) $_wp_additional_image_sizes[ $size ]['width']; $max_height = (int) $_wp_additional_image_sizes[ $size ]['height']; // Only in admin. Assume that theme authors know what they're doing. diff --git a/src/wp-includes/sitemaps.php b/src/wp-includes/sitemaps.php index 656fc5ecaa975..e1d805d671133 100644 --- a/src/wp-includes/sitemaps.php +++ b/src/wp-includes/sitemaps.php @@ -116,8 +116,12 @@ function get_sitemap_url( $name, $subtype_name = '', $page = 1 ) { return false; } - if ( $subtype_name && ! in_array( $subtype_name, array_keys( $provider->get_object_subtypes() ), true ) ) { - return false; + if ( $subtype_name ) { + $object_subtypes = $provider->get_object_subtypes(); + + if ( ! isset( $object_subtypes[ $subtype_name ] ) ) { + return false; + } } $page = absint( $page ); From 73c4e33aca93a2a9e33d38b60217ada359611b2f Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 11 Aug 2026 13:16:49 +0000 Subject: [PATCH 213/634] HTML API: Restore supported tags in modifiable text notice. Developed in https://github.com/WordPress/wordpress-develop/pull/12957. Follow-up to [62715]. Props dmsnell, bernhard-reiter. See #65372. git-svn-id: https://develop.svn.wordpress.org/trunk@63178 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/html-api/class-wp-html-tag-processor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/html-api/class-wp-html-tag-processor.php b/src/wp-includes/html-api/class-wp-html-tag-processor.php index 7ca5191a0f162..a41cf49d174d5 100644 --- a/src/wp-includes/html-api/class-wp-html-tag-processor.php +++ b/src/wp-includes/html-api/class-wp-html-tag-processor.php @@ -4192,7 +4192,7 @@ static function ( $tag_match ) { _doing_it_wrong( __METHOD__, - __( 'This tag does not support setting modifiable text.' ), + __( 'Only the IFRAME, NOEMBED, NOFRAMES, SCRIPT, STYLE, TEXTAREA, TITLE, and XMP tags support setting modifiable text.' ), '7.1.0' ); return false; From 7578111b5731984814d7f0471fd76b0d86422100 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 11 Aug 2026 13:25:23 +0000 Subject: [PATCH 214/634] HTML API: Recognize form feed in RCDATA and RAWTEXT tag closers. Form feeds after closing tag names were not recognized, causing complete elements to appear incomplete. Developed in https://github.com/WordPress/wordpress-develop/pull/12936. Props jonsurrell, westonruter. See #65372. git-svn-id: https://develop.svn.wordpress.org/trunk@63179 602fd350-edb4-49c9-b593-d223f7449a82 --- .../html-api/class-wp-html-tag-processor.php | 2 +- .../tests/html-api/wpHtmlTagProcessor.php | 48 +++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/html-api/class-wp-html-tag-processor.php b/src/wp-includes/html-api/class-wp-html-tag-processor.php index a41cf49d174d5..5745207f38fc4 100644 --- a/src/wp-includes/html-api/class-wp-html-tag-processor.php +++ b/src/wp-includes/html-api/class-wp-html-tag-processor.php @@ -1475,7 +1475,7 @@ private function skip_rcdata( string $tag_name ): bool { * though "textarea" is found within the text. */ $c = $html[ $at ]; - if ( ' ' !== $c && "\t" !== $c && "\r" !== $c && "\n" !== $c && '/' !== $c && '>' !== $c ) { + if ( ' ' !== $c && "\t" !== $c && "\f" !== $c && "\r" !== $c && "\n" !== $c && '/' !== $c && '>' !== $c ) { continue; } diff --git a/tests/phpunit/tests/html-api/wpHtmlTagProcessor.php b/tests/phpunit/tests/html-api/wpHtmlTagProcessor.php index 66e01dbdbed3e..7f59239608d6b 100644 --- a/tests/phpunit/tests/html-api/wpHtmlTagProcessor.php +++ b/tests/phpunit/tests/html-api/wpHtmlTagProcessor.php @@ -2369,6 +2369,54 @@ public static function data_script_tag(): Generator { yield 'Script tag double-escaped with array( "", false ); } + /** + * Ensures that tag-name-terminating characters close RCDATA and RAWTEXT elements. + * + * @ticket 65372 + * + * @dataProvider data_rcdata_and_rawtext_tag_name_terminators + * + * @param non-falsy-string $tag_name The RCDATA or RAWTEXT tag name. + * @param non-falsy-string $tag_name_terminator The tag-name-terminating character. + */ + public function test_rcdata_and_rawtext_end_tags_accept_tag_name_terminators( string $tag_name, string $tag_name_terminator ): void { + $end_tag_closer = '>' === $tag_name_terminator ? '' : '>'; + $processor = new WP_HTML_Tag_Processor( "<{$tag_name}>content" ); + + $this->assertTrue( $processor->next_token(), "Expected to find complete {$tag_name} tag." ); + $this->assertSame( strtoupper( $tag_name ), $processor->get_tag() ); + $this->assertSame( 'content', $processor->get_modifiable_text() ); + $this->assertTrue( $processor->next_tag( 'DIV' ), "Expected to find DIV after the {$tag_name} element." ); + } + + /** + * Provides every RCDATA and RAWTEXT tag with every tag-name-terminating character. + * + * @return Generator Test cases. + */ + public static function data_rcdata_and_rawtext_tag_name_terminators(): Generator { + foreach ( array( 'IFRAME', 'NOEMBED', 'NOFRAMES', 'STYLE', 'XMP', 'TEXTAREA', 'TITLE' ) as $tag_name ) { + foreach ( self::data_tag_name_terminators() as $terminator_name => $terminator_data ) { + yield "{$tag_name} + {$terminator_name}" => array( strtolower( $tag_name ), $terminator_data[0] ); + } + } + } + + /** + * Provides tag-name-terminating characters. + * + * @return Generator Test cases. + */ + public static function data_tag_name_terminators(): Generator { + yield 'SPACE' => array( ' ' ); + yield 'TAB' => array( "\t" ); + yield 'LINE FEED' => array( "\n" ); + yield 'FORM FEED' => array( "\f" ); + yield 'CARRIAGE RETURN' => array( "\r" ); + yield 'SOLIDUS' => array( '/' ); + yield 'GREATER-THAN SIGN' => array( '>' ); + } + /** * Invalid tag names are comments on tag closers. * From 996c6d686405cd9a5d2d2fa167782eb3b6c85d83 Mon Sep 17 00:00:00 2001 From: Aki Hamano Date: Tue, 11 Aug 2026 14:16:28 +0000 Subject: [PATCH 215/634] KSES: Allow functional CSS values in inline styles. The presentation properties allowlisted in [62530] were accepted in name only: any declaration whose value contained a function call was dropped in full, so for users without the `unfiltered_html` capability those properties remained unusable in their canonical form. URL references are routed through the existing protocol validation, so the security model is unchanged. Developed in: https://github.com/WordPress/wordpress-develop/pull/12942 Follow-up to [62530]. Props courane01, hasnainashfaq, irozum, khokansardar, mdridipu, tyxla. Fixes #65832. git-svn-id: https://develop.svn.wordpress.org/trunk@63180 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/kses.php | 25 +++++++- tests/phpunit/tests/kses.php | 116 +++++++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/kses.php b/src/wp-includes/kses.php index 92f866b15daef..9cd0f50f22487 100644 --- a/src/wp-includes/kses.php +++ b/src/wp-includes/kses.php @@ -2638,6 +2638,8 @@ function kses_init() { * @since 6.6.0 Added support for `grid-column`, `grid-row`, and `container-type`. * @since 6.9.0 Added support for `white-space`. * @since 7.1.0 Extended gradient support to allow any single-level nested function. + * Added support for transform functions, `clip-path` basic shapes, + * and URLs in the SVG element reference properties. * * @param string $css A string of CSS rules, decoded from an HTML `style` attribute. * @param string $deprecated Not used. @@ -2906,6 +2908,16 @@ function safecss_filter_attr( $css, $deprecated = '' ) { 'list-style', 'list-style-image', + + // SVG presentation properties that accept url() references. + 'clip-path', + 'fill', + 'marker', + 'marker-end', + 'marker-mid', + 'marker-start', + 'mask', + 'stroke', ); /* @@ -3004,7 +3016,18 @@ function safecss_filter_attr( $css, $deprecated = '' ) { * Nested functions and parentheses are also removed, so long as the parentheses are balanced. */ $css_test_string = preg_replace( - '/\b(?:var|calc|min|max|minmax|clamp|repeat)(\((?:[^()]|(?1))*\))/', + '/\b(?:' + // General purpose value functions. + . 'var|calc|min|max|minmax|clamp|repeat' + // Transform functions. + . '|matrix|matrix3d|perspective' + . '|rotate|rotate3d|rotateX|rotateY|rotateZ' + . '|scale|scale3d|scaleX|scaleY|scaleZ' + . '|skew|skewX|skewY' + . '|translate|translate3d|translateX|translateY|translateZ' + // Basic shape functions, as used by `clip-path`. + . '|circle|ellipse|inset|path|polygon|rect|shape|xywh' + . ')(\((?:[^()]|(?1))*\))/', '', $css_test_string ); diff --git a/tests/phpunit/tests/kses.php b/tests/phpunit/tests/kses.php index f560d88403524..b26bbd307d6aa 100644 --- a/tests/phpunit/tests/kses.php +++ b/tests/phpunit/tests/kses.php @@ -1224,6 +1224,7 @@ public function test_wp_kses_attr_no_attributes_allowed_with_false() { * @ticket 64414 * @ticket 65457 * @ticket 64974 + * @ticket 65832 * * @dataProvider data_safecss_filter_attr * @@ -1766,6 +1767,121 @@ public function data_safecss_filter_attr() { 'css' => 'text-anchor: middle', 'expected' => 'text-anchor: middle', ), + // SVG transform functions (ticket #65832). + array( + 'css' => 'transform: rotate(45deg)', + 'expected' => 'transform: rotate(45deg)', + ), + array( + 'css' => 'transform: translate(10px, 20px)', + 'expected' => 'transform: translate(10px, 20px)', + ), + array( + 'css' => 'transform: scale(1.5)', + 'expected' => 'transform: scale(1.5)', + ), + array( + 'css' => 'transform: matrix(1, 0, 0, 1, 10, 20)', + 'expected' => 'transform: matrix(1, 0, 0, 1, 10, 20)', + ), + array( + 'css' => 'transform: skewX(30deg)', + 'expected' => 'transform: skewX(30deg)', + ), + array( + 'css' => 'transform: skewY(30deg)', + 'expected' => 'transform: skewY(30deg)', + ), + // Multiple transform functions chained. + array( + 'css' => 'transform: rotate(45deg) scale(1.5)', + 'expected' => 'transform: rotate(45deg) scale(1.5)', + ), + // transform: none is unchanged (regression control). + array( + 'css' => 'transform: none', + 'expected' => 'transform: none', + ), + // SVG clip-path shape functions (ticket #65832). + array( + 'css' => 'clip-path: inset(10px)', + 'expected' => 'clip-path: inset(10px)', + ), + array( + 'css' => 'clip-path: circle(50%)', + 'expected' => 'clip-path: circle(50%)', + ), + array( + 'css' => 'clip-path: ellipse(25% 40% at 50% 50%)', + 'expected' => 'clip-path: ellipse(25% 40% at 50% 50%)', + ), + array( + 'css' => 'clip-path: polygon(50% 0%, 100% 100%, 0% 100%)', + 'expected' => 'clip-path: polygon(50% 0%, 100% 100%, 0% 100%)', + ), + array( + 'css' => "clip-path: path('M 0 0 L 100 0 L 50 100 Z')", + 'expected' => "clip-path: path('M 0 0 L 100 0 L 50 100 Z')", + ), + array( + 'css' => 'clip-path: rect(0 100% 100% 0)', + 'expected' => 'clip-path: rect(0 100% 100% 0)', + ), + array( + 'css' => 'clip-path: xywh(0 0 100% 100% round 10px)', + 'expected' => 'clip-path: xywh(0 0 100% 100% round 10px)', + ), + array( + 'css' => 'clip-path: shape(from 0 0, line to 100% 0, line to 50% 100%, close)', + 'expected' => 'clip-path: shape(from 0 0, line to 100% 0, line to 50% 100%, close)', + ), + // Nested functions within a basic shape are allowed. + array( + 'css' => 'clip-path: inset(calc(10px + 1em) round var(--radius))', + 'expected' => 'clip-path: inset(calc(10px + 1em) round var(--radius))', + ), + // SVG url() references for allowlisted properties (ticket #65832). + array( + 'css' => 'clip-path: url(#myClipper)', + 'expected' => 'clip-path: url(#myClipper)', + ), + array( + 'css' => 'fill: url(#gradient1)', + 'expected' => 'fill: url(#gradient1)', + ), + array( + 'css' => 'mask: url(#myMask)', + 'expected' => 'mask: url(#myMask)', + ), + array( + 'css' => 'marker-start: url(#arrowStart)', + 'expected' => 'marker-start: url(#arrowStart)', + ), + array( + 'css' => 'marker-end: url(#arrowEnd)', + 'expected' => 'marker-end: url(#arrowEnd)', + ), + array( + 'css' => 'marker-mid: url(#arrowMid)', + 'expected' => 'marker-mid: url(#arrowMid)', + ), + array( + 'css' => 'marker: url(#marker1)', + 'expected' => 'marker: url(#marker1)', + ), + array( + 'css' => 'stroke: url(#strokeGradient)', + 'expected' => 'stroke: url(#strokeGradient)', + ), + // Disallow javascript: URLs in SVG url() references (security regression). + array( + 'css' => 'fill: url(javascript:alert(1))', + 'expected' => '', + ), + array( + 'css' => 'clip-path: url(javascript:alert(1))', + 'expected' => '', + ), ); } From e2ae46d9d4ca8e53e924749c9203171e940fa251 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 11 Aug 2026 17:42:59 +0000 Subject: [PATCH 216/634] Code Quality: Fully qualify the SimplePie cache type in a docblock. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `@param` annotation for `$type` in `WP_Feed_Cache_Transient::__construct()` documented the type as `Base::TYPE_FEED|Base::TYPE_IMAGE`. The class is declared in the global namespace and imports nothing—it writes `implements SimplePie\Cache\Base` out in full—so the bare `Base` resolved to `\Base`, which exists nowhere in core. The shorthand was carried over in r59141 from `SimplePie\Cache\Base` itself, where it is correct because that file declares `namespace SimplePie\Cache;`. Qualifying both constants makes the annotation consistent with the rest of the docblock, which already spells the interface out in full. This was the only `parameter.unresolvableType` occurrence, so the change empties `tests/phpstan/baselines/parameter.unresolvableType.neon`. As the baseline header directs, the file is deleted along with its `includes` entry in `phpstan.neon.dist`. The baseline was regenerated with: {{{ composer phpstan:baselines -- --identifier=parameter.unresolvableType }}} Developed in https://github.com/WordPress/wordpress-develop/pull/12970. Follow-up to r59141, r63020. Props callumbw95. See #65817. git-svn-id: https://develop.svn.wordpress.org/trunk@63181 602fd350-edb4-49c9-b593-d223f7449a82 --- phpstan.neon.dist | 1 - .../class-wp-feed-cache-transient.php | 8 +++--- .../baselines/parameter.unresolvableType.neon | 25 ------------------- 3 files changed, 4 insertions(+), 30 deletions(-) delete mode 100644 tests/phpstan/baselines/parameter.unresolvableType.neon diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 3258c2d9c73e8..c9b3b48a67073 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -72,7 +72,6 @@ includes: - tests/phpstan/baselines/parameter.defaultValue.neon - tests/phpstan/baselines/parameter.notFound.neon - tests/phpstan/baselines/parameter.phpDocType.neon - - tests/phpstan/baselines/parameter.unresolvableType.neon - tests/phpstan/baselines/parameterByRef.type.neon - tests/phpstan/baselines/parameterByRef.unusedType.neon - tests/phpstan/baselines/property.defaultValue.neon diff --git a/src/wp-includes/class-wp-feed-cache-transient.php b/src/wp-includes/class-wp-feed-cache-transient.php index 2beeab69d2577..8cb177860b26b 100644 --- a/src/wp-includes/class-wp-feed-cache-transient.php +++ b/src/wp-includes/class-wp-feed-cache-transient.php @@ -50,10 +50,10 @@ class WP_Feed_Cache_Transient implements SimplePie\Cache\Base { * @since 3.2.0 Updated to use a PHP5 constructor. * @since 6.7.0 Parameter names have been updated to be in line with the `SimplePie\Cache\Base` interface. * - * @param string $location URL location (scheme is used to determine handler). - * @param string $name Unique identifier for cache object. - * @param Base::TYPE_FEED|Base::TYPE_IMAGE $type Either `TYPE_FEED` ('spc') for SimplePie data, - * or `TYPE_IMAGE` ('spi') for image data. + * @param string $location URL location (scheme is used to determine handler). + * @param string $name Unique identifier for cache object. + * @param SimplePie\Cache\Base::TYPE_FEED|SimplePie\Cache\Base::TYPE_IMAGE $type Either `TYPE_FEED` ('spc') for SimplePie data, + * or `TYPE_IMAGE` ('spi') for image data. */ public function __construct( $location, $name, $type ) { $this->name = 'feed_' . $name; diff --git a/tests/phpstan/baselines/parameter.unresolvableType.neon b/tests/phpstan/baselines/parameter.unresolvableType.neon deleted file mode 100644 index 1193e163ca555..0000000000000 --- a/tests/phpstan/baselines/parameter.unresolvableType.neon +++ /dev/null @@ -1,25 +0,0 @@ -# PHPStan baseline for the `parameter.unresolvableType` errors in WordPress core. -# -# https://phpstan.org/error-identifiers/parameter.unresolvableType -# -# Each entry is scoped to a single file and carries an exact occurrence count, -# so that a new instance is reported as a new error rather than being absorbed -# silently. Fixing an occurrence therefore means decrementing or removing its -# entry here as part of the same change. -# -# The goal is to empty this file and delete it, along with the `includes` entry -# for it in phpstan.neon.dist. -# -# Generated by `composer phpstan:baselines`. Do not edit by hand; regenerate with -# -# composer phpstan:baselines -- --identifier=parameter.unresolvableType -# -# which reruns the analysis with this file suppressed so the errors surface again. - -parameters: - ignoreErrors: - - - message: '#^PHPDoc tag @param for parameter \$type contains unresolvable type\.$#' - identifier: parameter.unresolvableType - count: 1 - path: ../../../src/wp-includes/class-wp-feed-cache-transient.php From ffcf3e96a11fdf2793c7d611660efc353124dfe5 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Tue, 11 Aug 2026 18:37:20 +0000 Subject: [PATCH 217/634] Help/About: Update the About page for 7.1 Introducing the new content for the 7.1 About page. Props joedolson, mdridipu, benjamin_zekavica, wildworks, rcorrales, annezazu, webverts, alanjacobmathew, markoserb, sfougnier, mukesh27, umesh.nevase, ekamran, jorbin, masteradhoc, obenland, krupajnanda, adamsilverstein. Fixes #65698, #65346. svn rm src/wp-admin/images/ git-svn-id: https://develop.svn.wordpress.org/trunk@63182 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/about.php | 62 +++++++++--------- src/wp-admin/contribute.php | 11 ---- src/wp-admin/credits.php | 11 ---- src/wp-admin/css/about.css | 47 ++++++++----- src/wp-admin/freedoms.php | 11 ---- .../images/about-header-credits-rtl.webp | Bin 40906 -> 0 bytes src/wp-admin/images/about-header-credits.webp | Bin 40960 -> 0 bytes .../images/about-header-default-rtl.webp | Bin 18810 -> 0 bytes src/wp-admin/images/about-header-default.webp | Bin 20030 -> 0 bytes .../images/about-header-freedoms-rtl.webp | Bin 43814 -> 0 bytes .../images/about-header-freedoms.webp | Bin 40888 -> 0 bytes .../images/about-header-get-involved-rtl.webp | Bin 15424 -> 0 bytes .../images/about-header-get-involved.webp | Bin 18168 -> 0 bytes .../images/about-header-privacy-rtl.webp | Bin 13612 -> 0 bytes src/wp-admin/images/about-header-privacy.webp | Bin 10926 -> 0 bytes src/wp-admin/images/about-release-badge.svg | 20 +++--- src/wp-admin/images/about-release-logo.svg | 6 -- src/wp-admin/includes/update-core.php | 11 ++++ src/wp-admin/privacy.php | 11 ---- 19 files changed, 83 insertions(+), 107 deletions(-) delete mode 100644 src/wp-admin/images/about-header-credits-rtl.webp delete mode 100644 src/wp-admin/images/about-header-credits.webp delete mode 100644 src/wp-admin/images/about-header-default-rtl.webp delete mode 100644 src/wp-admin/images/about-header-default.webp delete mode 100644 src/wp-admin/images/about-header-freedoms-rtl.webp delete mode 100644 src/wp-admin/images/about-header-freedoms.webp delete mode 100644 src/wp-admin/images/about-header-get-involved-rtl.webp delete mode 100644 src/wp-admin/images/about-header-get-involved.webp delete mode 100644 src/wp-admin/images/about-header-privacy-rtl.webp delete mode 100644 src/wp-admin/images/about-header-privacy.webp delete mode 100644 src/wp-admin/images/about-release-logo.svg diff --git a/src/wp-admin/about.php b/src/wp-admin/about.php index f8c48bb195b3c..71b392c37c59c 100644 --- a/src/wp-admin/about.php +++ b/src/wp-admin/about.php @@ -14,7 +14,7 @@ $title = _x( 'About', 'page title' ); list( $display_version ) = explode( '-', wp_get_wp_version() ); -$display_major_version = '7.0'; +$display_major_version = '7.1'; $release_notes_url = sprintf( /* translators: %s: WordPress version number. */ @@ -34,21 +34,19 @@ sanitize_title( $display_major_version ) ); +$version_text = sprintf( + /* translators: %s: Version number. */ + __( 'WordPress %s' ), + $display_version +); + require_once ABSPATH . 'wp-admin/admin-header.php'; ?>

-

- -

+

@@ -62,22 +60,22 @@
-

-

+

+

-

+

-
- +
+

- +
@@ -85,29 +83,29 @@
- +
-

+

-
- +
+

-

+

-
- +
+

- +
@@ -115,14 +113,14 @@
- +
-

+

-
- +
+

@@ -137,8 +135,8 @@
-

-

+

+

@@ -147,7 +145,7 @@

-

+

@@ -177,7 +175,7 @@
- + <?php echo esc_attr( $version_text ); ?>

diff --git a/src/wp-admin/contribute.php b/src/wp-admin/contribute.php index 4a6989adffa25..9a57a1b57915d 100644 --- a/src/wp-admin/contribute.php +++ b/src/wp-admin/contribute.php @@ -12,22 +12,11 @@ // Used in the HTML title tag. $title = __( 'Get Involved' ); -list( $display_version ) = explode( '-', get_bloginfo( 'version' ) ); -$header_alt_text = sprintf( - /* translators: %s: Version number. */ - __( 'WordPress %s' ), - $display_version -); - require_once ABSPATH . 'wp-admin/admin-header.php'; ?>
-
- <?php echo esc_attr( $header_alt_text ); ?> -
-

diff --git a/src/wp-admin/credits.php b/src/wp-admin/credits.php index 960c334913474..75993cf6652a7 100644 --- a/src/wp-admin/credits.php +++ b/src/wp-admin/credits.php @@ -13,13 +13,6 @@ // Used in the HTML title tag. $title = __( 'Credits' ); -list( $display_version ) = explode( '-', get_bloginfo( 'version' ) ); -$header_alt_text = sprintf( - /* translators: %s: Version number. */ - __( 'WordPress %s' ), - $display_version -); - require_once ABSPATH . 'wp-admin/admin-header.php'; $credits = wp_credits(); @@ -27,10 +20,6 @@
-
- <?php echo esc_attr( $header_alt_text ); ?> -
-

diff --git a/src/wp-admin/css/about.css b/src/wp-admin/css/about.css index 721a98078f0d6..871d819ce905a 100644 --- a/src/wp-admin/css/about.css +++ b/src/wp-admin/css/about.css @@ -21,8 +21,8 @@ .about__container { /* Section backgrounds */ - --background: #ebe8e5; - --subtle-background: #ebe8e5; + --background: #3858e9; + --subtle-background: #f4f4f4; /* Main text color */ --text: #1e1e1e; @@ -278,7 +278,7 @@ .about__section.has-2-columns.is-wider-right, .about__section.has-2-columns.is-wider-left, .about__section.has-3-columns { - display: block; + grid-template-columns: 1fr; margin-bottom: calc(var(--gap) / 2); } @@ -329,10 +329,18 @@ @media screen and (max-width: 600px) { .about__section.has-2-columns { - display: block; + grid-template-columns: 1fr; margin-bottom: var(--gap); } + .about__section.has-2-columns:not(.is-wider-right,.is-wider-left) div:has(img) { + order: 1; + } + + .about__section.has-2-columns:not(.is-wider-right,.is-wider-left) div:not(:has(img)) { + order: 0; + } + .about__section.has-2-columns:not(.has-gutters) .column:nth-of-type(n) { padding-top: calc(var(--gap) / 2); padding-bottom: calc(var(--gap) / 2); @@ -531,7 +539,7 @@ margin: calc(var(--gap) / 2) var(--gap); height: 0; border: none; - border-top: 4px solid var(--accent-3); + border-top: 6px solid var(--accent-3); } .about__container hr.is-small { @@ -581,6 +589,10 @@ .about__container h3.is-larger-heading { font-size: 2em; } + + .about__container h1 { + text-shadow: 0 0 2px var(--background); + } } /* 1.3 - Header */ @@ -596,48 +608,49 @@ padding-right: 26rem; /* Space for the background image. */ min-height: clamp(10rem, 25vw, 18.75rem); border-radius: var(--border-radius); - background-image: url( "../images/about-header-default.webp?ver=20260514" ); + background-image: url( "https://s.w.org/images/core/7.1/about-header-default.webp?ver=20260804" ); background-repeat: no-repeat; background-position: right center; background-size: cover; background-color: var(--background); color: var(--text-light); + margin-bottom: .25rem; } .credits-php .about__header { - background-image: url( "../images/about-header-credits.webp?ver=20260514" ); + background-image: url( "https://s.w.org/images/core/7.1/about-header-credits.webp?ver=20260804" ); } .freedoms-php .about__header { - background-image: url( "../images/about-header-freedoms.webp?ver=20260514" ); + background-image: url( "https://s.w.org/images/core/7.1/about-header-freedoms.webp?ver=20260804" ); } .privacy-php .about__header { - background-image: url( "../images/about-header-privacy.webp?ver=20260514" ); + background-image: url( "https://s.w.org/images/core/7.1/about-header-privacy.webp?ver=20260804" ); } .contribute-php .about__header { - background-image: url( "../images/about-header-get-involved.webp?ver=20260514" ); + background-image: url( "https://s.w.org/images/core/7.1/about-header-get-involved.webp?ver=20260804" ); } [dir="rtl"] .about__header { - background-image: url( "../images/about-header-default-rtl.webp?ver=20260514" ); + background-image: url( "https://s.w.org/images/core/7.1/about-header-default-rtl.webp?ver=20260804" ); } [dir="rtl"] .credits-php .about__header { - background-image: url( "../images/about-header-credits-rtl.webp?ver=20260514" ); + background-image: url( "https://s.w.org/images/core/7.1/about-header-credits-rtl.webp?ver=20260804" ); } [dir="rtl"] .freedoms-php .about__header { - background-image: url( "../images/about-header-freedoms-rtl.webp?ver=20260514" ); + background-image: url( "https://s.w.org/images/core/7.1/about-header-freedoms-rtl.webp?ver=20260804" ); } [dir="rtl"] .privacy-php .about__header { - background-image: url( "../images/about-header-privacy-rtl.webp?ver=20260514" ); + background-image: url( "https://s.w.org/images/core/7.1/about-header-privacy-rtl.webp?ver=20260804" ); } [dir="rtl"] .contribute-php .about__header { - background-image: url( "../images/about-header-get-involved-rtl.webp?ver=20260514" ); + background-image: url( "https://s.w.org/images/core/7.1/about-header-get-involved-rtl.webp?ver=20260804" ); } .about__header-image { @@ -657,7 +670,7 @@ font-size: clamp(2rem, 20vw - 9rem, 4rem); line-height: 1; font-weight: 600; - color: var(--text); + color: var(--text-light); } .about-php .about__header-title h1, @@ -676,7 +689,7 @@ padding: 0; font-size: 1.6rem; line-height: 1.15; - color: var(--text); + color: var(--text-light); } .about__header-navigation { diff --git a/src/wp-admin/freedoms.php b/src/wp-admin/freedoms.php index 9646c4a400eeb..f94413618b164 100644 --- a/src/wp-admin/freedoms.php +++ b/src/wp-admin/freedoms.php @@ -18,22 +18,11 @@ // Used in the HTML title tag. $title = __( 'Freedoms' ); -list( $display_version ) = explode( '-', get_bloginfo( 'version' ) ); -$header_alt_text = sprintf( - /* translators: %s: Version number. */ - __( 'WordPress %s' ), - $display_version -); - require_once ABSPATH . 'wp-admin/admin-header.php'; ?>
-
- <?php echo esc_attr( $header_alt_text ); ?> -
-

diff --git a/src/wp-admin/images/about-header-credits-rtl.webp b/src/wp-admin/images/about-header-credits-rtl.webp deleted file mode 100644 index b65ce15238ea97b50f1b2af09d73fb53bee4396f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40906 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 diff --git a/src/wp-admin/images/about-header-credits.webp b/src/wp-admin/images/about-header-credits.webp deleted file mode 100644 index b83bb5b49e1c4aa60463bf40cdb9b298f7ced2b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40960 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 diff --git a/src/wp-admin/images/about-header-default-rtl.webp b/src/wp-admin/images/about-header-default-rtl.webp deleted file mode 100644 index 7de0c9a4ffec28534933da9029262ce00b43ddfa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18810 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 diff --git a/src/wp-admin/images/about-header-default.webp b/src/wp-admin/images/about-header-default.webp deleted file mode 100644 index 020a92a7265ae8660285362065a9b1699a6d1e3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20030 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 U8s9)(HugtkRof-Wnsx~60EhTKt^fc4 diff --git a/src/wp-admin/images/about-header-freedoms-rtl.webp b/src/wp-admin/images/about-header-freedoms-rtl.webp deleted file mode 100644 index 506c20f4cf6200c1a8bb0d3814573d0c59aa6b58..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43814 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

PcclC(;Opy5 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 E0PW!iumAu6 diff --git a/src/wp-admin/images/about-header-freedoms.webp b/src/wp-admin/images/about-header-freedoms.webp deleted file mode 100644 index 4740e8ab087b0f370fa3fd4dab2f792f5da355e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40888 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

G*`K#scH}rk5L{p@m^CA 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 diff --git a/src/wp-admin/images/about-header-get-involved-rtl.webp b/src/wp-admin/images/about-header-get-involved-rtl.webp deleted file mode 100644 index 4cd5b89c61c004a837e3b1d9abed5b22588a7eb0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15424 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 diff --git a/src/wp-admin/images/about-header-get-involved.webp b/src/wp-admin/images/about-header-get-involved.webp deleted file mode 100644 index 33a6708b9f2faded335e4de5d1d804c488d571db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18168 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 diff --git a/src/wp-admin/images/about-header-privacy-rtl.webp b/src/wp-admin/images/about-header-privacy-rtl.webp deleted file mode 100644 index 0ee585216df5ee340a7d2ef49561ddba6db08036..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13612 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 diff --git a/src/wp-admin/images/about-header-privacy.webp b/src/wp-admin/images/about-header-privacy.webp deleted file mode 100644 index 5178051483f757ecaf301296831cffa005bfc8ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10926 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 ZZjSimhYYND#ozdATz9!XT?7r_-vE>|XN3R& diff --git a/src/wp-admin/images/about-release-badge.svg b/src/wp-admin/images/about-release-badge.svg index 751068ebe62ed..8380db37771cf 100644 --- a/src/wp-admin/images/about-release-badge.svg +++ b/src/wp-admin/images/about-release-badge.svg @@ -1,14 +1,18 @@ - - - - - - + + + + + + - - + + + + + + diff --git a/src/wp-admin/images/about-release-logo.svg b/src/wp-admin/images/about-release-logo.svg deleted file mode 100644 index d497949fe8b74..0000000000000 --- a/src/wp-admin/images/about-release-logo.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/wp-admin/includes/update-core.php b/src/wp-admin/includes/update-core.php index 664fec95298c6..01dba5e25a22f 100644 --- a/src/wp-admin/includes/update-core.php +++ b/src/wp-admin/includes/update-core.php @@ -1150,6 +1150,17 @@ 'wp-includes/images/icon-library/widget.svg', 'wp-includes/images/icon-library/word-count.svg', 'wp-includes/images/icon-library/wordpress.svg', + 'wp-admin/images/about-header-credits.webp', + 'wp-admin/images/about-header-credits-rtl.webp', + 'wp-admin/images/about-header-default.webp', + 'wp-admin/images/about-header-default-rtl.webp', + 'wp-admin/images/about-header-freedoms.webp', + 'wp-admin/images/about-header-freedoms-rtl.webp', + 'wp-admin/images/about-header-get-involved.webp', + 'wp-admin/images/about-header-get-involved-rtl.webp', + 'wp-admin/images/about-header-privacy.webp', + 'wp-admin/images/about-header-privacy-rtl.webp', + 'wp-admin/images/about-release-logo.svg', ); /** diff --git a/src/wp-admin/privacy.php b/src/wp-admin/privacy.php index 1445e5b1ec2b4..bbe6d5ddfc885 100644 --- a/src/wp-admin/privacy.php +++ b/src/wp-admin/privacy.php @@ -12,22 +12,11 @@ // Used in the HTML title tag. $title = __( 'Privacy' ); -list( $display_version ) = explode( '-', get_bloginfo( 'version' ) ); -$header_alt_text = sprintf( - /* translators: %s: Version number. */ - __( 'WordPress %s' ), - $display_version -); - require_once ABSPATH . 'wp-admin/admin-header.php'; ?>
-
- <?php echo esc_attr( $header_alt_text ); ?> -
-

From 15c4b048588ee7b286edd846708f57756b4a519e Mon Sep 17 00:00:00 2001 From: Jonathan Desrosiers Date: Tue, 11 Aug 2026 20:13:21 +0000 Subject: [PATCH 218/634] Build/Test Tools: Skip `pull_request` triggered runs in private repos. This modifies the conditions for GitHub Actions workflow runs so that they do not run within private forks and mirrors for `pull_request` events when the PR is in `draft` status. For situations where this may be desirable, a `Draft Workflow Runs` label can be added to a `draft` pull request to force workflows to run. Props desrosj, jorbin. See #65848. git-svn-id: https://develop.svn.wordpress.org/trunk@63183 602fd350-edb4-49c9-b593-d223f7449a82 --- .github/workflows/coding-standards.yml | 18 +++++- .github/workflows/end-to-end-tests.yml | 9 ++- .github/workflows/javascript-tests.yml | 9 ++- .../workflows/javascript-type-checking.yml | 9 ++- .github/workflows/performance.yml | 12 +++- .github/workflows/php-compatibility.yml | 9 ++- .github/workflows/phpstan-static-analysis.yml | 9 ++- .github/workflows/phpunit-tests.yml | 61 +++++++++++++++++-- .../workflows/test-and-zip-default-themes.yml | 18 +++++- .github/workflows/test-build-processes.yml | 9 ++- .github/workflows/upgrade-develop-testing.yml | 24 ++++++-- .github/workflows/workflow-lint.yml | 11 +++- 12 files changed, 175 insertions(+), 23 deletions(-) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index d75cc99eaf920..9342f2abc7f94 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -50,7 +50,14 @@ jobs: uses: WordPress/wordpress-develop/.github/workflows/reusable-coding-standards-php.yml@trunk permissions: contents: read - if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }} + if: | + github.repository == 'WordPress/wordpress-develop' || ( + github.event_name == 'pull_request' && ( + ! github.event.repository.private || + ! github.event.pull_request.draft || + contains( github.event.pull_request.labels.*.name, 'Draft Workflow Runs' ) + ) + ) # Runs the JavaScript coding standards checks. jshint: @@ -58,7 +65,14 @@ jobs: uses: WordPress/wordpress-develop/.github/workflows/reusable-coding-standards-javascript.yml@trunk permissions: contents: read - if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }} + if: | + github.repository == 'WordPress/wordpress-develop' || ( + github.event_name == 'pull_request' && ( + ! github.event.repository.private || + ! github.event.pull_request.draft || + contains( github.event.pull_request.labels.*.name, 'Draft Workflow Runs' ) + ) + ) slack-notifications: name: Slack Notifications diff --git a/.github/workflows/end-to-end-tests.yml b/.github/workflows/end-to-end-tests.yml index ee60975b39a0d..a7f6be21989f5 100644 --- a/.github/workflows/end-to-end-tests.yml +++ b/.github/workflows/end-to-end-tests.yml @@ -57,7 +57,14 @@ jobs: uses: WordPress/wordpress-develop/.github/workflows/reusable-end-to-end-tests.yml@trunk permissions: contents: read - if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }} + if: | + github.repository == 'WordPress/wordpress-develop' || ( + github.event_name == 'pull_request' && ( + ! github.event.repository.private || + ! github.event.pull_request.draft || + contains( github.event.pull_request.labels.*.name, 'Draft Workflow Runs' ) + ) + ) strategy: fail-fast: false matrix: diff --git a/.github/workflows/javascript-tests.yml b/.github/workflows/javascript-tests.yml index 933bfcd5f8313..ec97fa07c45bd 100644 --- a/.github/workflows/javascript-tests.yml +++ b/.github/workflows/javascript-tests.yml @@ -53,7 +53,14 @@ jobs: uses: WordPress/wordpress-develop/.github/workflows/reusable-javascript-tests.yml@trunk permissions: contents: read - if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }} + if: | + github.repository == 'WordPress/wordpress-develop' || ( + github.event_name == 'pull_request' && ( + ! github.event.repository.private || + ! github.event.pull_request.draft || + contains( github.event.pull_request.labels.*.name, 'Draft Workflow Runs' ) + ) + ) slack-notifications: name: Slack Notifications diff --git a/.github/workflows/javascript-type-checking.yml b/.github/workflows/javascript-type-checking.yml index 940b48e25ae0a..b926821c1facc 100644 --- a/.github/workflows/javascript-type-checking.yml +++ b/.github/workflows/javascript-type-checking.yml @@ -46,7 +46,14 @@ jobs: uses: WordPress/wordpress-develop/.github/workflows/reusable-javascript-type-checking-v1.yml@trunk permissions: contents: read - if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }} + if: | + github.repository == 'WordPress/wordpress-develop' || ( + github.event_name == 'pull_request' && ( + ! github.event.repository.private || + ! github.event.pull_request.draft || + contains( github.event.pull_request.labels.*.name, 'Draft Workflow Runs' ) + ) + ) slack-notifications: name: Slack Notifications diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml index f9c86e7aaefae..ca94c45487305 100644 --- a/.github/workflows/performance.yml +++ b/.github/workflows/performance.yml @@ -50,7 +50,17 @@ jobs: determine-matrix: name: Determine Matrix runs-on: ubuntu-24.04 - if: ${{ ( github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' ) && ! contains( github.event.before, '00000000' ) }} + if: | + ( + github.repository == 'WordPress/wordpress-develop' || ( + github.event_name == 'pull_request' && ( + ! github.event.repository.private || + ! github.event.pull_request.draft || + contains( github.event.pull_request.labels.*.name, 'Draft Workflow Runs' ) + ) + ) + ) && + ! contains( github.event.before, '00000000' ) permissions: actions: read env: diff --git a/.github/workflows/php-compatibility.yml b/.github/workflows/php-compatibility.yml index 78f23bbcfe76d..c91a1652cbc55 100644 --- a/.github/workflows/php-compatibility.yml +++ b/.github/workflows/php-compatibility.yml @@ -42,7 +42,14 @@ jobs: uses: WordPress/wordpress-develop/.github/workflows/reusable-php-compatibility.yml@trunk permissions: contents: read - if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }} + if: | + github.repository == 'WordPress/wordpress-develop' || ( + github.event_name == 'pull_request' && ( + ! github.event.repository.private || + ! github.event.pull_request.draft || + contains( github.event.pull_request.labels.*.name, 'Draft Workflow Runs' ) + ) + ) slack-notifications: name: Slack Notifications diff --git a/.github/workflows/phpstan-static-analysis.yml b/.github/workflows/phpstan-static-analysis.yml index 352b78e4c8f43..e1ab13c68a37d 100644 --- a/.github/workflows/phpstan-static-analysis.yml +++ b/.github/workflows/phpstan-static-analysis.yml @@ -42,7 +42,14 @@ jobs: uses: WordPress/wordpress-develop/.github/workflows/reusable-phpstan-static-analysis-v1.yml@trunk permissions: contents: read - if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }} + if: | + github.repository == 'WordPress/wordpress-develop' || ( + github.event_name == 'pull_request' && ( + ! github.event.repository.private || + ! github.event.pull_request.draft || + contains( github.event.pull_request.labels.*.name, 'Draft Workflow Runs' ) + ) + ) slack-notifications: name: Slack Notifications diff --git a/.github/workflows/phpunit-tests.yml b/.github/workflows/phpunit-tests.yml index fb5da98d1e87c..99b2025e7c52a 100644 --- a/.github/workflows/phpunit-tests.yml +++ b/.github/workflows/phpunit-tests.yml @@ -58,7 +58,14 @@ jobs: uses: WordPress/wordpress-develop/.github/workflows/reusable-prepare-gutenberg.yml@trunk permissions: contents: read - if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }} + if: | + github.repository == 'WordPress/wordpress-develop' || ( + github.event_name == 'pull_request' && ( + ! github.event.repository.private || + ! github.event.pull_request.draft || + contains( github.event.pull_request.labels.*.name, 'Draft Workflow Runs' ) + ) + ) # # Creates a PHPUnit test job for each PHP/MySQL combination. @@ -76,7 +83,16 @@ jobs: secrets: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} WPT_REPORT_API_KEY: ${{ secrets.WPT_REPORT_API_KEY }} - if: ${{ startsWith( github.repository, 'WordPress/' ) && ( github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' ) }} + if: | + startsWith( github.repository, 'WordPress/' ) && ( + github.repository == 'WordPress/wordpress-develop' || ( + github.event_name == 'pull_request' && ( + ! github.event.repository.private || + ! github.event.pull_request.draft || + contains( github.event.pull_request.labels.*.name, 'Draft Workflow Runs' ) + ) + ) + ) strategy: fail-fast: false matrix: @@ -159,7 +175,16 @@ jobs: secrets: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} WPT_REPORT_API_KEY: ${{ secrets.WPT_REPORT_API_KEY }} - if: ${{ startsWith( github.repository, 'WordPress/' ) && ( github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' ) }} + if: | + startsWith( github.repository, 'WordPress/' ) && ( + github.repository == 'WordPress/wordpress-develop' || ( + github.event_name == 'pull_request' && ( + ! github.event.repository.private || + ! github.event.pull_request.draft || + contains( github.event.pull_request.labels.*.name, 'Draft Workflow Runs' ) + ) + ) + ) strategy: fail-fast: false matrix: @@ -217,7 +242,16 @@ jobs: secrets: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} WPT_REPORT_API_KEY: ${{ secrets.WPT_REPORT_API_KEY }} - if: ${{ startsWith( github.repository, 'WordPress/' ) && ( github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' ) }} + if: | + startsWith( github.repository, 'WordPress/' ) && ( + github.repository == 'WordPress/wordpress-develop' || ( + github.event_name == 'pull_request' && ( + ! github.event.repository.private || + ! github.event.pull_request.draft || + contains( github.event.pull_request.labels.*.name, 'Draft Workflow Runs' ) + ) + ) + ) strategy: fail-fast: false matrix: @@ -264,7 +298,16 @@ jobs: secrets: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} WPT_REPORT_API_KEY: ${{ secrets.WPT_REPORT_API_KEY }} - if: ${{ startsWith( github.repository, 'WordPress/' ) && ( github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' ) }} + if: | + startsWith( github.repository, 'WordPress/' ) && ( + github.repository == 'WordPress/wordpress-develop' || ( + github.event_name == 'pull_request' && ( + ! github.event.repository.private || + ! github.event.pull_request.draft || + contains( github.event.pull_request.labels.*.name, 'Draft Workflow Runs' ) + ) + ) + ) strategy: fail-fast: false matrix: @@ -298,7 +341,13 @@ jobs: secrets: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} WPT_REPORT_API_KEY: ${{ secrets.WPT_REPORT_API_KEY }} - if: ${{ ! startsWith( github.repository, 'WordPress/' ) && github.event_name == 'pull_request' }} + if: | + ! startsWith( github.repository, 'WordPress/' ) && + github.event_name == 'pull_request' && ( + ! github.event.repository.private || + ! github.event.pull_request.draft || + contains( github.event.pull_request.labels.*.name, 'Draft Workflow Runs' ) + ) strategy: fail-fast: false matrix: diff --git a/.github/workflows/test-and-zip-default-themes.yml b/.github/workflows/test-and-zip-default-themes.yml index f50c00bdeafe9..30c15408f9736 100644 --- a/.github/workflows/test-and-zip-default-themes.yml +++ b/.github/workflows/test-and-zip-default-themes.yml @@ -69,7 +69,14 @@ jobs: permissions: contents: read timeout-minutes: 10 - if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }} + if: | + github.repository == 'WordPress/wordpress-develop' || ( + github.event_name == 'pull_request' && ( + ! github.event.repository.private || + ! github.event.pull_request.draft || + contains( github.event.pull_request.labels.*.name, 'Draft Workflow Runs' ) + ) + ) strategy: fail-fast: false matrix: @@ -119,7 +126,14 @@ jobs: permissions: contents: read timeout-minutes: 10 - if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }} + if: | + github.repository == 'WordPress/wordpress-develop' || ( + github.event_name == 'pull_request' && ( + ! github.event.repository.private || + ! github.event.pull_request.draft || + contains( github.event.pull_request.labels.*.name, 'Draft Workflow Runs' ) + ) + ) strategy: fail-fast: false matrix: diff --git a/.github/workflows/test-build-processes.yml b/.github/workflows/test-build-processes.yml index 64f6c63481914..be54536d7c6d3 100644 --- a/.github/workflows/test-build-processes.yml +++ b/.github/workflows/test-build-processes.yml @@ -51,7 +51,14 @@ jobs: uses: WordPress/wordpress-develop/.github/workflows/reusable-test-core-build-process.yml@trunk permissions: contents: read - if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }} + if: | + github.repository == 'WordPress/wordpress-develop' || ( + github.event_name == 'pull_request' && ( + ! github.event.repository.private || + ! github.event.pull_request.draft || + contains( github.event.pull_request.labels.*.name, 'Draft Workflow Runs' ) + ) + ) strategy: fail-fast: false matrix: diff --git a/.github/workflows/upgrade-develop-testing.yml b/.github/workflows/upgrade-develop-testing.yml index b36b2c56b0d34..bc920a115321e 100644 --- a/.github/workflows/upgrade-develop-testing.yml +++ b/.github/workflows/upgrade-develop-testing.yml @@ -43,8 +43,17 @@ jobs: # Build WordPress from the current branch ready for the upgrade tests. build: name: Build - uses: WordPress/wordpress-develop/.github/workflows/reusable-build-package.yml@trunk - if: ${{ startsWith( github.repository, 'WordPress/' ) && ( github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' ) }} + uses: ./.github/workflows/reusable-build-package.yml + if: | + startsWith( github.repository, 'WordPress/' ) && ( + github.repository == 'WordPress/wordpress-develop' || ( + github.event_name == 'pull_request' && ( + ! github.event.repository.private || + ! github.event.pull_request.draft || + contains( github.event.pull_request.labels.*.name, 'Draft Workflow Runs' ) + ) + ) + ) permissions: contents: read @@ -86,8 +95,15 @@ jobs: # Run a limited set of upgrade tests for the current branch on forks. upgrade-tests-develop-forks: name: Upgrade from ${{ matrix.wp }} - uses: WordPress/wordpress-develop/.github/workflows/reusable-upgrade-testing.yml@trunk - if: ${{ github.repository != 'WordPress/wordpress-develop' }} + uses: ./.github/workflows/reusable-upgrade-testing.yml + # This job also runs for the push event, which has no draft state to check. + if: | + github.repository != 'WordPress/wordpress-develop' && ( + github.event_name != 'pull_request' || + ! github.event.repository.private || + ! github.event.pull_request.draft || + contains( github.event.pull_request.labels.*.name, 'Draft Workflow Runs' ) + ) needs: [ build ] permissions: contents: read diff --git a/.github/workflows/workflow-lint.yml b/.github/workflows/workflow-lint.yml index d86b62ca79646..f04417964d6aa 100644 --- a/.github/workflows/workflow-lint.yml +++ b/.github/workflows/workflow-lint.yml @@ -32,8 +32,15 @@ permissions: {} jobs: lint: name: Lint GitHub Action files - uses: WordPress/wordpress-develop/.github/workflows/reusable-workflow-lint.yml@trunk - if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }} + uses: ./.github/workflows/reusable-workflow-lint.yml + if: | + github.repository == 'WordPress/wordpress-develop' || ( + github.event_name == 'pull_request' && ( + ! github.event.repository.private || + ! github.event.pull_request.draft || + contains( github.event.pull_request.labels.*.name, 'Draft Workflow Runs' ) + ) + ) permissions: security-events: write actions: read From 93f6c0edfc5613f335ba1f94580b2e6080c83fe1 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Tue, 11 Aug 2026 20:14:30 +0000 Subject: [PATCH 219/634] Help/About: Remove an extra space in a string. Removes an extra space in one of the About page translatable strings. Follow up to [63182]. Props joedolson, alanjacobmathew. See #65698. git-svn-id: https://develop.svn.wordpress.org/trunk@63184 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/about.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-admin/about.php b/src/wp-admin/about.php index 71b392c37c59c..d140fbd8270de 100644 --- a/src/wp-admin/about.php +++ b/src/wp-admin/about.php @@ -90,7 +90,7 @@


- +

From 5226db030cda34382e816a75efeb90046e290fb4 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Tue, 11 Aug 2026 20:44:20 +0000 Subject: [PATCH 220/634] Help/About: Correct the version description. The version description included a reference to a change that did not ship in version 7.1. Props joedolson, annezazu. See #65698. git-svn-id: https://develop.svn.wordpress.org/trunk@63185 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/about.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-admin/about.php b/src/wp-admin/about.php index d140fbd8270de..4a421ac00cfba 100644 --- a/src/wp-admin/about.php +++ b/src/wp-admin/about.php @@ -61,7 +61,7 @@

-

+

From bf0784f3e47f37654ab6f866bb54c1f7e4409b07 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Tue, 11 Aug 2026 22:52:34 +0000 Subject: [PATCH 221/634] Toolbar: Inconsistent text hover color for top-level nodes. Follow up to [63009]. Original commit removed a `:not(.mobile)` qualifier from the `:hover` rule, but not from the default state rule. Remove the default rule as well, so colors are handled consistently. Props fushar, khokansardar, madhavishah01, wildworks, afercia, joedolson. Fixes #65848. git-svn-id: https://develop.svn.wordpress.org/trunk@63188 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/css/admin-bar.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/css/admin-bar.css b/src/wp-includes/css/admin-bar.css index f50c67dd71689..600a0ae45e60b 100644 --- a/src/wp-includes/css/admin-bar.css +++ b/src/wp-includes/css/admin-bar.css @@ -231,7 +231,7 @@ html:lang(he-il) .rtl #wpadminbar * { color: #72aee6; } -#wpadminbar:not(.mobile) > #wp-toolbar li:hover span.ab-label, +#wpadminbar > #wp-toolbar li:hover span.ab-label, #wpadminbar > #wp-toolbar li.hover span.ab-label, /* The adminbar menu may output either links or focusable div elements. */ /* As such, we target the focus state without specifying the element type. */ From e634c333bf01223fdf05bad0146bf7039d7bb032 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Tue, 11 Aug 2026 23:05:13 +0000 Subject: [PATCH 222/634] Toolbar: Match hover state to focus state. Follow up to [63009]. The original commit strengthened the focus state in the admin toolbar, but didn't change the hover state. This created a mismatch in behavior where the admin toolbar behaved differently from the primary admin menu, which has a shared hover and focus state. Apply the focus state to the hover condition as well, so that the behavior matches the admin sidebar. Props fushar, wildworks, ravichudasama01, afercia, joedolson. Fixes #65849. git-svn-id: https://develop.svn.wordpress.org/trunk@63190 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/css/admin-bar.css | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/wp-includes/css/admin-bar.css b/src/wp-includes/css/admin-bar.css index 600a0ae45e60b..e0411701a28e8 100644 --- a/src/wp-includes/css/admin-bar.css +++ b/src/wp-includes/css/admin-bar.css @@ -82,11 +82,19 @@ html:lang(he-il) .rtl #wpadminbar * { outline-offset: -2px; /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; +} + +#wpadminbar a:hover, +#wpadminbar a:focus, +#wpadminbar .ab-item[tabindex="0"]:hover, +#wpadminbar .ab-item[tabindex="0"]:focus { box-shadow: inset 0 -4px 0 0 currentColor; transition: box-shadow 0.1s linear; } +#wpadminbar .ab-submenu a:hover, #wpadminbar .ab-submenu a:focus, +#wpadminbar .ab-submenu .ab-item[tabindex="0"]:hover, #wpadminbar .ab-submenu .ab-item[tabindex="0"]:focus { box-shadow: inset 4px 0 0 0 currentColor; } From 193824cc4b1b0fb5ee17349a00462933c244e029 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Wed, 12 Aug 2026 00:21:45 +0000 Subject: [PATCH 223/634] Build/Test Tools: Treat `DB_COLLATE` and `WP_DEVELOPMENT_MODE` as dynamic in PHPStan. The `DB_COLLATE` and `WP_DEVELOPMENT_MODE` constants both vary per installation, but neither was listed in `dynamicConstantNames`, so PHPStan resolved each to the empty string it is handed during analysis. Every conditional guarding either constant was therefore reported as having a constant result, accounting for two `ternary.alwaysFalse` errors in `class-wp-debug-data.php` and one `booleanAnd.rightAlwaysFalse` error in `class-wpdb.php`. Listing both constants as dynamic resolves all three errors and empties their baselines, which are deleted along with their `includes` entries in `phpstan.neon.dist`. Developed in https://github.com/WordPress/wordpress-develop/pull/12958. Follow-up to r61699, r63023. Props callumbw95. See #65817. git-svn-id: https://develop.svn.wordpress.org/trunk@63191 602fd350-edb4-49c9-b593-d223f7449a82 --- phpstan.neon.dist | 2 -- tests/phpstan/base.neon | 2 ++ .../booleanAnd.rightAlwaysFalse.neon | 25 ------------------- .../baselines/ternary.alwaysFalse.neon | 25 ------------------- 4 files changed, 2 insertions(+), 52 deletions(-) delete mode 100644 tests/phpstan/baselines/booleanAnd.rightAlwaysFalse.neon delete mode 100644 tests/phpstan/baselines/ternary.alwaysFalse.neon diff --git a/phpstan.neon.dist b/phpstan.neon.dist index c9b3b48a67073..fa1e3f209c322 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -31,7 +31,6 @@ includes: - tests/phpstan/baselines/booleanAnd.alwaysFalse.neon - tests/phpstan/baselines/booleanAnd.alwaysTrue.neon - tests/phpstan/baselines/booleanAnd.leftAlwaysTrue.neon - - tests/phpstan/baselines/booleanAnd.rightAlwaysFalse.neon - tests/phpstan/baselines/booleanAnd.rightAlwaysTrue.neon - tests/phpstan/baselines/booleanNot.alwaysFalse.neon - tests/phpstan/baselines/booleanNot.alwaysTrue.neon @@ -88,7 +87,6 @@ includes: - tests/phpstan/baselines/return.unusedType.neon - tests/phpstan/baselines/smallerOrEqual.alwaysTrue.neon - tests/phpstan/baselines/staticClassAccess.privateMethod.neon - - tests/phpstan/baselines/ternary.alwaysFalse.neon - tests/phpstan/baselines/ternary.alwaysTrue.neon - tests/phpstan/baselines/varTag.noVariable.neon - tests/phpstan/baselines/variable.undefined.neon diff --git a/tests/phpstan/base.neon b/tests/phpstan/base.neon index 1c416cb3fe643..ab07051c9ad7a 100644 --- a/tests/phpstan/base.neon +++ b/tests/phpstan/base.neon @@ -79,6 +79,7 @@ parameters: - BACKGROUND_IMAGE - COOKIEPATH - CUSTOM_TAGS + - DB_COLLATE - DISALLOW_FILE_EDIT - DISALLOW_UNFILTERED_HTML - EMPTY_TRASH_DAYS @@ -104,6 +105,7 @@ parameters: - WP_DEBUG - WP_DEBUG_DISPLAY - WP_DEBUG_LOG + - WP_DEVELOPMENT_MODE - WP_LANG_DIR - WP_NETWORK_ADMIN - WP_POST_REVISIONS diff --git a/tests/phpstan/baselines/booleanAnd.rightAlwaysFalse.neon b/tests/phpstan/baselines/booleanAnd.rightAlwaysFalse.neon deleted file mode 100644 index 367c8dd35051c..0000000000000 --- a/tests/phpstan/baselines/booleanAnd.rightAlwaysFalse.neon +++ /dev/null @@ -1,25 +0,0 @@ -# PHPStan baseline for the `booleanAnd.rightAlwaysFalse` errors in WordPress core. -# -# https://phpstan.org/error-identifiers/booleanAnd.rightAlwaysFalse -# -# Each entry is scoped to a single file and carries an exact occurrence count, -# so that a new instance is reported as a new error rather than being absorbed -# silently. Fixing an occurrence therefore means decrementing or removing its -# entry here as part of the same change. -# -# The goal is to empty this file and delete it, along with the `includes` entry -# for it in phpstan.neon.dist. -# -# Generated by `composer phpstan:baselines`. Do not edit by hand; regenerate with -# -# composer phpstan:baselines -- --identifier=booleanAnd.rightAlwaysFalse -# -# which reruns the analysis with this file suppressed so the errors surface again. - -parameters: - ignoreErrors: - - - message: '#^Right side of && is always false\.$#' - identifier: booleanAnd.rightAlwaysFalse - count: 1 - path: ../../../src/wp-includes/class-wpdb.php diff --git a/tests/phpstan/baselines/ternary.alwaysFalse.neon b/tests/phpstan/baselines/ternary.alwaysFalse.neon deleted file mode 100644 index b73c48bc42724..0000000000000 --- a/tests/phpstan/baselines/ternary.alwaysFalse.neon +++ /dev/null @@ -1,25 +0,0 @@ -# PHPStan baseline for the `ternary.alwaysFalse` errors in WordPress core. -# -# https://phpstan.org/error-identifiers/ternary.alwaysFalse -# -# Each entry is scoped to a single file and carries an exact occurrence count, -# so that a new instance is reported as a new error rather than being absorbed -# silently. Fixing an occurrence therefore means decrementing or removing its -# entry here as part of the same change. -# -# The goal is to empty this file and delete it, along with the `includes` entry -# for it in phpstan.neon.dist. -# -# Generated by `composer phpstan:baselines`. Do not edit by hand; regenerate with -# -# composer phpstan:baselines -- --identifier=ternary.alwaysFalse -# -# which reruns the analysis with this file suppressed so the errors surface again. - -parameters: - ignoreErrors: - - - message: '#^Ternary operator condition is always false\.$#' - identifier: ternary.alwaysFalse - count: 2 - path: ../../../src/wp-admin/includes/class-wp-debug-data.php From 3767a6c06a1695e45c2f4730cc353f42aeb4b730 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Wed, 12 Aug 2026 05:28:45 +0000 Subject: [PATCH 224/634] REST API: Bind finalize sub-size file names to their sideload. Fix an issue where the finalize endpoint stored the sub-size file names a client sent without confirming a sideloaded image had produced them for that attachment. Those names are later resolved against the attachment's upload directory and read or deleted, so finalize could record a file the upload never created. To address this, the sideload endpoint now records each name it generates under a `_wp_sideloaded_file` post meta key, and the finalize endpoint accepts a name only when: 1. a prior sideload recorded it in post meta, 2. it is the attachment's own attached file, or 3. it is already stored in the attachment's metadata. Anything else returns a `rest_invalid_sub_size_file` error (HTTP 400) before any metadata is written. Sideloads are also pinned to the attachment's own subdirectory via the `upload_dir` filter, so names are in the directory they later resolve against. Finalize stays safe to repeat: a name already in the attachment's metadata is accepted again. Follow-up to r61982, r62609. Reviewed by westonruter. Props westonruter. See #64804. git-svn-id: https://develop.svn.wordpress.org/trunk@63200 602fd350-edb4-49c9-b593-d223f7449a82 --- .../class-wp-rest-attachments-controller.php | 617 +++++++++++++++--- .../rest-api/rest-attachments-controller.php | 73 ++- tests/qunit/fixtures/wp-api-generated.js | 17 +- 3 files changed, 590 insertions(+), 117 deletions(-) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php index f336f321a9ea2..c17193acfc916 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php @@ -13,6 +13,16 @@ * @since 4.7.0 * * @see WP_REST_Posts_Controller + * + * @phpstan-type Image_Sub_Size array{ + * image_size: non-empty-string|non-empty-list, + * width?: positive-int, + * height?: positive-int, + * file?: non-empty-string, + * mime_type?: non-empty-string, + * filesize?: positive-int, + * original_image?: non-empty-string, + * } */ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller { @@ -47,6 +57,21 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller { */ const META_KEY_SOURCE_IMAGE = 'source_image'; + /** + * Post meta key recording the file names produced by the sideload endpoint. + * + * Each successful sideload appends the file name(s) it created for an + * attachment under this key. The finalize endpoint reads them back to + * confirm every stored sub-size was actually produced here, rather than + * trusting a client-supplied name that could point at another attachment's + * files. Stored as one row per value (via {@see add_post_meta()}) so concurrent + * sideloads never read-modify-write a shared value. + * + * @since 7.1.0 + * @var string + */ + const META_KEY_SIDELOAD_FILE_NAME = '_wp_sideloaded_file'; + /** * Registers the routes for attachments. * @@ -105,8 +130,11 @@ public function register_routes() { 'description' => __( 'Image size. Can be a single size name or an array of size names to register the same file under multiple sizes.' ), 'type' => array( 'string', 'array' ), 'items' => array( - 'type' => 'string', + 'type' => 'string', + 'minLength' => 1, ), + 'minItems' => 1, + 'minLength' => 1, 'required' => true, /* * A custom callback is used instead of the default enum validation @@ -116,37 +144,18 @@ public function register_routes() { * the current list of registered sizes, which reflects sizes added * after route registration (e.g. via add_image_size()). */ - 'validate_callback' => static function ( $value, $request, $param ) { - $valid_sizes = array_keys( wp_get_registered_image_subsizes() ); - $valid_sizes[] = 'original'; - $valid_sizes[] = 'scaled'; - $valid_sizes[] = 'full'; - // Source-format original (e.g. the HEIC kept alongside its JPEG derivative). - $valid_sizes[] = self::IMAGE_SIZE_SOURCE_ORIGINAL; - // Converted-video companions for an animated GIF (the MP4/WebM and its poster). - $valid_sizes[] = 'animated_video'; - $valid_sizes[] = 'animated_video_poster'; - - $items = is_string( $value ) ? array( $value ) : ( is_array( $value ) ? $value : null ); - if ( null === $items ) { - return new WP_Error( - 'rest_invalid_type', - /* translators: %s: Parameter name. */ - sprintf( __( '%s must be a string or an array of strings.' ), $param ) - ); + 'validate_callback' => static function ( $value, WP_REST_Request $request, string $param ) { + /* + * Providing a custom callback replaces the default schema + * validation, so apply the declared schema (type, minLength, + * minItems) before the enum check below. + */ + $schema_validity = rest_validate_request_arg( $value, $request, $param ); + if ( is_wp_error( $schema_validity ) ) { + return $schema_validity; } - foreach ( $items as $item ) { - if ( ! is_string( $item ) || ! in_array( $item, $valid_sizes, true ) ) { - return new WP_Error( - 'rest_not_in_enum', - /* translators: %s: Parameter name. */ - sprintf( __( '%s contains an invalid image size.' ), $param ) - ); - } - } - - return true; + return self::validate_image_size_names( $value, $param ); }, ), 'convert_format' => array( @@ -175,10 +184,50 @@ public function register_routes() { 'type' => 'integer', ), 'sub_sizes' => array( - 'description' => __( 'Array of sub-size metadata collected from sideload responses.' ), - 'type' => 'array', - 'default' => array(), - 'items' => array( + 'description' => __( 'Array of sub-size metadata collected from sideload responses.' ), + 'type' => 'array', + 'default' => array(), + /* + * A finalize request sends one entry per sideloaded sub-size, so + * the ceiling only needs to clear the number of sizes a site can + * register. Bounding it keeps a request from repeating a name + * across an arbitrary number of entries. + */ + 'maxItems' => 100, + /* + * As on the sideload endpoint, the size names are checked in a + * callback rather than an enum, so the set reflects the sizes + * registered when the request runs. The callback sits on + * sub_sizes because a nested property cannot carry one. + */ + 'validate_callback' => static function ( $value, WP_REST_Request $request, string $param ) { + /* + * Providing a custom callback replaces the default schema + * validation, so apply the declared schema first. That is what + * guarantees each entry is an object carrying an image_size of + * the declared type. + */ + $schema_validity = rest_validate_request_arg( $value, $request, $param ); + if ( is_wp_error( $schema_validity ) ) { + return $schema_validity; + } + + foreach ( (array) $value as $index => $sub_size ) { + $sub_size = (array) $sub_size; + + $validity = self::validate_image_size_names( + $sub_size['image_size'] ?? null, + sprintf( '%s[%s][image_size]', $param, $index ) + ); + + if ( is_wp_error( $validity ) ) { + return $validity; + } + } + + return true; + }, + 'items' => array( 'type' => 'object', 'properties' => array( 'image_size' => array( @@ -186,7 +235,10 @@ public function register_routes() { 'type' => array( 'string', 'array' ), 'items' => array( 'type' => 'string', + 'minLength' => 1, ), + 'minItems' => 1, + 'minLength' => 1, 'required' => true, ), 'width' => array( @@ -198,7 +250,8 @@ public function register_routes() { 'minimum' => 1, ), 'file' => array( - 'type' => 'string', + 'type' => 'string', + 'minLength' => 1, ), 'mime_type' => array( 'type' => 'string', @@ -209,7 +262,8 @@ public function register_routes() { 'minimum' => 1, ), 'original_image' => array( - 'type' => 'string', + 'type' => 'string', + 'minLength' => 1, ), ), ), @@ -597,7 +651,7 @@ public function create_item( $request ) { * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, WP_Error object on failure. */ - protected function create_item_from_url( $request ) { + protected function create_item_from_url( WP_REST_Request $request ) { // Sideloading downloads and stores a file, so require the upload capability. if ( ! current_user_can( 'upload_files' ) ) { return new WP_Error( @@ -2462,6 +2516,96 @@ public function sideload_item_permissions_check( $request ) { return $this->edit_media_item_permissions_check( $request ); } + /** + * Validates an image size name, or an array of names sharing a single file. + * + * Shared by the sideload endpoint, which names the size a file is produced + * for, and the finalize endpoint, which names the size each submitted entry + * is stored under. Both need the same set, and finalize accepts a payload of + * its own rather than one this class produced, so leaving it unconstrained + * there would let a submission write an arbitrary key into the metadata + * 'sizes' array or route a file into a branch it was never produced for. + * + * @since 7.1.0 + * + * @param mixed $value The image size name, or an array of names. + * @param string $param Parameter name, used in the error messages. + * @return true|WP_Error True when every name is valid, WP_Error otherwise. + */ + private static function validate_image_size_names( $value, string $param ) { + $special_sizes = self::get_special_image_sizes(); + $regular_sizes = array_values( + array_diff( + array_merge( + array_keys( wp_get_registered_image_subsizes() ), + // Not a registered sub-size, but stored as an ordinary + // entry in the metadata 'sizes' array (PDF thumbnails). + array( 'full' ) + ), + $special_sizes + ) + ); + + if ( is_string( $value ) ) { + $items = array( $value ); + $valid_sizes = array_merge( $regular_sizes, $special_sizes ); + } elseif ( is_array( $value ) ) { + /** + * An array registers one sideloaded file under several size names, + * which only makes sense for regular sub-sizes: each special size + * names a single file with its own handling in + * {@see self::sideload_item()} and its own metadata key in + * {@see self::finalize_item()}. Rejecting them here is what lets the + * array branches in both methods treat an array as regular sizes. + */ + $items = $value; + $valid_sizes = $regular_sizes; + } else { + return new WP_Error( + 'rest_invalid_type', + /* translators: %s: Parameter name. */ + sprintf( __( '%s must be a string or an array of strings.' ), $param ) + ); + } + + foreach ( $items as $item ) { + if ( ! in_array( $item, $valid_sizes, true ) ) { + return new WP_Error( + 'rest_not_in_enum', + /* translators: %s: Parameter name. */ + sprintf( __( '%s contains an invalid image size.' ), $param ) + ); + } + } + + return true; + } + + /** + * Returns the image size names which name a single file rather than a sub-size. + * + * Each of these is handled on its own in {@see self::sideload_item()} and stored + * under its own key by {@see self::finalize_item()}, so unlike a regular + * sub-size none of them may appear in an array of names sharing one file. + * + * @since 7.1.0 + * + * @return string[] Special image size names. + * + * @phpstan-return non-empty-list + */ + private static function get_special_image_sizes(): array { + return array( + 'original', + 'scaled', + // Source-format original (e.g. the HEIC kept alongside its JPEG derivative). + self::IMAGE_SIZE_SOURCE_ORIGINAL, + // Converted-video companions for an animated GIF (the MP4/WebM and its poster). + 'animated_video', + 'animated_video_poster', + ); + } + /** * Validates that uploaded image dimensions are appropriate for the specified image size. * @@ -2625,6 +2769,26 @@ public function sideload_item( WP_REST_Request $request ) { ); } + /* + * Sideloaded files are placed in the same directory as the attachment + * they extend, because the file names produced here are later resolved + * against that directory. An attachment stored outside the uploads + * directory has no such directory to use, so there is nowhere the names + * this would produce could resolve. + */ + $attached_file = get_attached_file( $attachment_id, true ); + $subdir = is_string( $attached_file ) && '' !== $attached_file + ? $this->get_attachment_upload_subdir( $attached_file ) + : null; + + if ( ! is_string( $attached_file ) || '' === $attached_file || null === $subdir ) { + return new WP_Error( + 'rest_sideload_attachment_not_in_uploads', + __( 'The attachment is not stored in the uploads directory, so a file cannot be sideloaded for it.' ), + array( 'status' => 403 ) + ); + } + if ( false === $request['convert_format'] ) { // Prevent image conversion as that is done client-side. add_filter( 'image_editor_output_format', '__return_empty_array', 100 ); @@ -2639,8 +2803,7 @@ public function sideload_item( WP_REST_Request $request ) { * See /wp-includes/functions.php. * With the following filter we can work around this safeguard. */ - $attachment_filename = get_attached_file( $attachment_id, true ); - $attachment_filename = $attachment_filename ? wp_basename( $attachment_filename ) : null; + $attachment_filename = wp_basename( $attached_file ); $filter_filename = static function ( $filename, $ext, $dir, $unique_filename_callback, $alt_filenames, $number ) use ( $attachment_filename ) { return self::filter_wp_unique_filename( $filename, $dir, $number, $attachment_filename ); @@ -2648,24 +2811,34 @@ public function sideload_item( WP_REST_Request $request ) { add_filter( 'wp_unique_filename', $filter_filename, 10, 6 ); - $parent_post = get_post_parent( $attachment_id ); - - $time = null; + // Pin the upload to the attachment's own directory, rather than deriving + // it from the parent post's date as media_handle_upload() does for a + // brand new upload. See the note above where $subdir is resolved. + $filter_upload_dir = static function ( $uploads ) use ( $subdir ) { + if ( + is_array( $uploads ) && + isset( $uploads['basedir'], $uploads['baseurl'] ) && + is_string( $uploads['basedir'] ) && + is_string( $uploads['baseurl'] ) + ) { + $uploads['subdir'] = $subdir; + $uploads['path'] = $uploads['basedir'] . $subdir; + $uploads['url'] = $uploads['baseurl'] . $subdir; + } + return $uploads; + }; - // Matches logic in media_handle_upload(). - // The post date doesn't usually matter for pages, so don't backdate this upload. - if ( $parent_post && 'page' !== $parent_post->post_type && ! str_starts_with( $parent_post->post_date, '0000-00-00' ) ) { - $time = $parent_post->post_date; - } + add_filter( 'upload_dir', $filter_upload_dir, 100 ); if ( ! empty( $files ) ) { - $file = $this->upload_from_file( $files, $headers, $time ); + $file = $this->upload_from_file( $files, $headers ); } else { - $file = $this->upload_from_data( $request->get_body(), $headers, $time ); + $file = $this->upload_from_data( $request->get_body(), $headers ); } remove_filter( 'wp_unique_filename', $filter_filename ); remove_filter( 'image_editor_output_format', '__return_empty_array', 100 ); + remove_filter( 'upload_dir', $filter_upload_dir, 100 ); if ( is_wp_error( $file ) ) { return $file; @@ -2674,7 +2847,7 @@ public function sideload_item( WP_REST_Request $request ) { $type = $file['type']; $path = $file['file']; - /** @var non-empty-string $image_size */ + /** @var non-empty-string|non-empty-list $image_size */ $image_size = $request['image_size']; /* @@ -2688,7 +2861,8 @@ public function sideload_item( WP_REST_Request $request ) { * read and rejected if unreadable; validate_image_dimensions() skips * only the registered-size constraint for it. */ - $skip_dimension_read = in_array( $image_size, array( self::IMAGE_SIZE_SOURCE_ORIGINAL, 'animated_video' ), true ); + $skip_dimension_read = self::IMAGE_SIZE_SOURCE_ORIGINAL === $image_size || 'animated_video' === $image_size; + $size = false; if ( ! $skip_dimension_read ) { /* @@ -2709,13 +2883,14 @@ public function sideload_item( WP_REST_Request $request ) { } /* - * Validate the dimensions match the expected size. An array - * $image_size represents multiple registered sizes sharing a single - * file; those are handled by the per-size branch below, so only - * scalar sizes are validated here. + * Validate the dimensions against every size the file is being + * registered under. An array $image_size shares one file among + * several registered sizes, so the file has to satisfy each of + * them; validating only the scalar case would let a name wrapped + * in a one-element array skip the constraint entirely. */ - if ( ! is_array( $image_size ) ) { - $validation = $this->validate_image_dimensions( $size[0], $size[1], $image_size, $attachment_id ); + foreach ( (array) $image_size as $size_name ) { + $validation = $this->validate_image_dimensions( $size[0], $size[1], $size_name, $attachment_id ); if ( is_wp_error( $validation ) ) { // Clean up the uploaded file. wp_delete_file( $path ); @@ -2734,11 +2909,13 @@ public function sideload_item( WP_REST_Request $request ) { ); if ( is_array( $image_size ) ) { - // Multiple registered sizes share these dimensions, so a single - // sideloaded file is reused for all of them. Arrays only carry - // regular sub-sizes; the special keys below are always scalar. - $size = wp_getimagesize( $path ); - + /** + * Multiple registered sizes share these dimensions, so a single + * sideloaded file is reused for all of them. Arrays only carry + * regular sub-sizes; the special keys below are always scalar + * (ref. {@see self::get_special_image_sizes()}). Those never skip + * the read above, so $size already holds the dimensions. + */ $sub_size_data['width'] = $size ? $size[0] : 0; $sub_size_data['height'] = $size ? $size[1] : 0; $sub_size_data['file'] = wp_basename( $path ); @@ -2768,23 +2945,15 @@ public function sideload_item( WP_REST_Request $request ) { * makes when it scales or rotates an image on upload; see * _wp_image_meta_replace_original(). */ - $current_file = get_attached_file( $attachment_id, true ); - - if ( ! $current_file ) { - return new WP_Error( - 'rest_sideload_no_attached_file', - __( 'Unable to retrieve the attached file for this attachment.' ), - array( 'status' => 404 ) - ); - } - - $sub_size_data['original_image'] = wp_basename( $current_file ); + $sub_size_data['original_image'] = $attachment_filename; // Validate the supplied image before updating the attached file. - $size = wp_getimagesize( $path ); + // $size was read above: neither of these sizes skips that read. $filesize = wp_filesize( $path ); if ( ! $size || ! $filesize ) { + // Clean up the uploaded file, which nothing references yet. + wp_delete_file( $path ); return new WP_Error( 'rest_sideload_invalid_image', __( 'Unable to read the sideloaded image file.' ), @@ -2795,9 +2964,11 @@ public function sideload_item( WP_REST_Request $request ) { // Update the attached file to point to the supplied image. // This writes to _wp_attached_file meta, not _wp_attachment_metadata. if ( - get_attached_file( $attachment_id, true ) !== $path && + $attached_file !== $path && ! update_attached_file( $attachment_id, $path ) ) { + // Clean up the uploaded file, which nothing references yet. + wp_delete_file( $path ); return new WP_Error( 'rest_sideload_update_attached_file_failed', __( 'Unable to update the attached file for this attachment.' ), @@ -2810,8 +2981,7 @@ public function sideload_item( WP_REST_Request $request ) { $sub_size_data['filesize'] = $filesize; $sub_size_data['file'] = _wp_relative_upload_path( $path ); } else { - $size = wp_getimagesize( $path ); - + // As above, $size was already read for every size reaching here. $sub_size_data['width'] = $size ? $size[0] : 0; $sub_size_data['height'] = $size ? $size[1] : 0; $sub_size_data['file'] = wp_basename( $path ); @@ -2819,6 +2989,22 @@ public function sideload_item( WP_REST_Request $request ) { $sub_size_data['filesize'] = wp_filesize( $path ); } + /* + * Record the file names produced for this attachment so finalize can + * confirm every stored sub-size was actually sideloaded here. The + * values recorded are exactly the ones handed back to the client, so + * finalize accepts a submission only when it echoes what was produced. + */ + foreach ( array( 'file', 'original_image' ) as $provenance_key ) { + if ( + isset( $sub_size_data[ $provenance_key ] ) && + is_string( $sub_size_data[ $provenance_key ] ) && + '' !== $sub_size_data[ $provenance_key ] + ) { + add_post_meta( $attachment_id, self::META_KEY_SIDELOAD_FILE_NAME, wp_slash( $sub_size_data[ $provenance_key ] ) ); + } + } + return rest_ensure_response( $sub_size_data ); } @@ -2833,6 +3019,13 @@ public function sideload_item( WP_REST_Request $request ) { * However, here it is desired not to add the suffix in order to maintain the same * naming convention as if the file was uploaded regularly. * + * The suffix is only dropped when no file of that name already exists in $dir, + * so this never returns a name that would overwrite one. The unsuffixed name + * must also derive from the attachment's own file name, and + * {@see self::sideload_item()} pins the upload to the attachment's own + * directory, so any name returned here belongs to the attachment being + * extended. + * * @since 7.1.0 * * @link https://github.com/WordPress/wordpress-develop/blob/30954f7ac0840cfdad464928021d7f380940c347/src/wp-includes/functions.php#L2576-L2582 @@ -2868,6 +3061,175 @@ private static function filter_wp_unique_filename( $filename, $dir, $number, $at return $filename; } + /** + * Validates the `sub_sizes` file names against what this attachment produced. + * + * The {@see self::finalize_item()} method stores the client-supplied `file` + * and `original_image` values in the attachment metadata, where they are + * later resolved within the attachment's upload directory and read or deleted + * (for example by {@see wp_get_original_image_path()}, {@see wp_getimagesize()}, + * and {@see wp_delete_attachment_files()}). + * + * Every file the sideload endpoint creates is recorded under + * {@see self::META_KEY_SIDELOAD_FILE_NAME} as it is produced, using + * server-generated names. finalize accepts a `file` or `original_image` + * value only when it matches one of those recorded names (or the + * attachment's own attached file, which it definitionally owns). + * + * @since 7.1.0 + * + * @param int $attachment_id The attachment being finalized. + * @param array $sub_sizes Sub-size metadata collected from sideloads. + * @return true|WP_Error True if every file name was produced here, WP_Error otherwise. + * + * @phpstan-param list $sub_sizes + */ + protected function validate_sub_size_provenance( int $attachment_id, array $sub_sizes ) { + $allowed = $this->get_sideloaded_file_names( $attachment_id ); + + foreach ( $sub_sizes as $sub_size ) { + foreach ( array( 'file', 'original_image' ) as $key ) { + /* + * Every value that was sent is checked, no matter how unlikely + * a name it looks. A loose emptiness test would wave through + * '0', which is a valid one-character name as far as the schema + * is concerned and is stored like any other. A value the schema + * types as a string but which arrives as something else is + * rejected rather than skipped, so a subclass which widens the + * schema cannot pass an unchecked value on to the metadata. + */ + if ( ! isset( $sub_size[ $key ] ) ) { + continue; + } + + if ( ! is_string( $sub_size[ $key ] ) || ! in_array( $sub_size[ $key ], $allowed, true ) ) { + return new WP_Error( + 'rest_invalid_sub_size_file', + __( 'Invalid sub-size file name. File names must have been produced by a prior sideload for this attachment.' ), + array( 'status' => 400 ) + ); + } + } + } + + return true; + } + + /** + * Returns the file names which a finalize request may store for an attachment. + * + * The set is the file names the sideload endpoint recorded as it produced + * them (ref. {@see self::META_KEY_SIDELOAD_FILE_NAME}), plus the attachment's own + * attached file - accepted in both its uploads-relative and basename form so + * a scaled main-file pointer validates regardless of which the client + * echoes - plus the names already stored in the attachment's own metadata. + * + * @since 7.1.0 + * + * @param int $attachment_id The attachment being finalized. + * @param bool $include_provenance Whether to include the sideload provenance rows. + * Pass false to get only the names recoverable from + * the attached file and stored metadata, e.g. to decide + * whether a provenance row is still needed. Default true. + * @return string[] File names that may appear in the finalize submission. + * + * @phpstan-return list + */ + protected function get_sideloaded_file_names( int $attachment_id, bool $include_provenance = true ): array { + $allowed = array(); + + if ( $include_provenance ) { + foreach ( (array) get_post_meta( $attachment_id, self::META_KEY_SIDELOAD_FILE_NAME ) as $name ) { + if ( is_string( $name ) && '' !== $name ) { + $allowed[] = $name; + } + } + } + + $attached_file = get_post_meta( $attachment_id, '_wp_attached_file', true ); + if ( is_string( $attached_file ) && strlen( $attached_file ) > 0 ) { + $allowed[] = $attached_file; + $allowed[] = wp_basename( $attached_file ); + } + + /* + * Names already stored in this attachment's metadata passed this same + * check when they were written, so accepting them again introduces + * nothing new. + */ + $metadata = wp_get_attachment_metadata( $attachment_id, true ); + if ( is_array( $metadata ) ) { + $stored = array( + $metadata['file'] ?? null, + $metadata['original_image'] ?? null, + $metadata[ self::META_KEY_SOURCE_IMAGE ] ?? null, + $metadata['animated_video'] ?? null, + $metadata['animated_video_poster'] ?? null, + ); + + if ( ! empty( $metadata['sizes'] ) && is_array( $metadata['sizes'] ) ) { + foreach ( $metadata['sizes'] as $size ) { + $stored[] = is_array( $size ) ? ( $size['file'] ?? null ) : null; + } + } + + foreach ( $stored as $name ) { + if ( is_string( $name ) && '' !== $name ) { + $allowed[] = $name; + $allowed[] = wp_basename( $name ); + } + } + } + + return array_values( array_unique( $allowed ) ); + } + + /** + * Returns the uploads subdirectory an attachment is stored in. + * + * Used to place a sideloaded file alongside the attachment it extends. The + * result is concatenated into a filesystem path by the caller, so it is + * returned only when the attachment resolves inside the uploads directory + * and the stored path is well formed. + * + * @since 7.1.0 + * + * @param string $attached_file Absolute path to the attached file. + * @return string|null Subdirectory beginning with a slash, an empty string when the + * attachment sits in the base directory, or null when the + * attachment is not inside the uploads directory. + * + * @phpstan-param non-empty-string $attached_file + */ + protected function get_attachment_upload_subdir( string $attached_file ): ?string { + $uploads = wp_get_upload_dir(); + if ( empty( $uploads['basedir'] ) ) { + return null; + } + + $basedir = untrailingslashit( wp_normalize_path( $uploads['basedir'] ) ); + $file_dir = wp_normalize_path( dirname( $attached_file ) ); + + /* + * The attachment's directory must be the uploads base directory itself + * or a directory inside it. The trailing slash in the prefix comparison + * keeps a sibling directory that merely shares the prefix (for example + * 'uploads-elsewhere' next to 'uploads') from matching. + */ + if ( $file_dir !== $basedir && ! str_starts_with( $file_dir, trailingslashit( $basedir ) ) ) { + return null; + } + + $subdir = (string) substr( $file_dir, strlen( $basedir ) ); + + // A prefix match alone does not rule out a path that climbs back out. + if ( in_array( '..', explode( '/', $subdir ), true ) ) { + return null; + } + + return $subdir; + } + /** * Finalizes an attachment after client-side media processing. * @@ -2890,28 +3252,60 @@ public function finalize_item( WP_REST_Request $request ) { return $post; } + /** + * Sub-size metadata collected from sideload responses. Confirm every + * file name was produced by a prior sideload for this attachment before + * storing it, so a client cannot make finalize record (and later read or + * delete) another attachment's files. + * + * @var list $sub_sizes + */ + $sub_sizes = $request['sub_sizes'] ?? array(); + $provenance = $this->validate_sub_size_provenance( $attachment_id, $sub_sizes ); + if ( is_wp_error( $provenance ) ) { + return $provenance; + } + $metadata = wp_get_attachment_metadata( $attachment_id ); if ( ! is_array( $metadata ) ) { $metadata = array(); } // Apply all sub-size metadata collected from sideload responses. - $sub_sizes = $request['sub_sizes'] ?? array(); - foreach ( $sub_sizes as $sub_size ) { $image_size = $sub_size['image_size']; // When multiple size names share identical dimensions the client // sends a single sub-size entry with an array of names. Register the - // same file under each name. Arrays only contain regular sizes. + // same file under each name. if ( is_array( $image_size ) ) { + /* + * Arrays carry regular sizes only, as the sideload endpoint + * enforces. Each special size names a single file handled by one + * of the branches below, so grouping one under a shared file + * would write it to the wrong place; reject rather than guess. + */ + if ( array_intersect( $image_size, self::get_special_image_sizes() ) ) { + return new WP_Error( + 'rest_invalid_sub_size_name', + __( 'A grouped sub-size entry may only name regular image sizes.' ), + array( 'status' => 400 ) + ); + } + + // As below: `file` is not required by the schema, and a size + // entry that names no file is not worth recording. + if ( empty( $sub_size['file'] ) ) { + continue; + } + $metadata['sizes'] = $metadata['sizes'] ?? array(); foreach ( $image_size as $name ) { $metadata['sizes'][ $name ] = array( 'width' => $sub_size['width'] ?? 0, 'height' => $sub_size['height'] ?? 0, - 'file' => $sub_size['file'] ?? '', + 'file' => $sub_size['file'], 'mime-type' => $sub_size['mime_type'] ?? '', 'filesize' => $sub_size['filesize'] ?? 0, ); @@ -2953,6 +3347,12 @@ public function finalize_item( WP_REST_Request $request ) { $metadata['image_meta']['orientation'] = 1; } } elseif ( self::IMAGE_SIZE_SOURCE_ORIGINAL === $image_size ) { + // As above: `file` is not required by the schema, and each of + // these sizes is nothing but the file it names. + if ( empty( $sub_size['file'] ) ) { + continue; + } + /* * Source-format original: stored under its own meta key so the * scaled-sideload flow (which writes 'original_image') cannot @@ -2962,6 +3362,10 @@ public function finalize_item( WP_REST_Request $request ) { */ $metadata[ self::META_KEY_SOURCE_IMAGE ] = $sub_size['file']; } elseif ( 'animated_video' === $image_size ) { + if ( empty( $sub_size['file'] ) ) { + continue; + } + /* * Converted-video companion of an animated GIF. Stored under its * own meta key; 'original_image' keeps pointing at the GIF. Cleanup @@ -2969,15 +3373,23 @@ public function finalize_item( WP_REST_Request $request ) { */ $metadata['animated_video'] = $sub_size['file']; } elseif ( 'animated_video_poster' === $image_size ) { + if ( empty( $sub_size['file'] ) ) { + continue; + } + // Static first-frame poster for the converted video. $metadata['animated_video_poster'] = $sub_size['file']; } else { + if ( empty( $sub_size['file'] ) ) { + continue; + } + $metadata['sizes'] = $metadata['sizes'] ?? array(); $metadata['sizes'][ $image_size ] = array( 'width' => $sub_size['width'] ?? 0, 'height' => $sub_size['height'] ?? 0, - 'file' => $sub_size['file'] ?? '', + 'file' => $sub_size['file'], 'mime-type' => $sub_size['mime_type'] ?? '', 'filesize' => $sub_size['filesize'] ?? 0, ); @@ -2989,6 +3401,47 @@ public function finalize_item( WP_REST_Request $request ) { wp_update_attachment_metadata( $attachment_id, $metadata ); + /* + * Drop only the provenance rows this request consumed, now that the + * names are recorded in the metadata itself. A row is dropped only once + * its name is recoverable from the stored metadata, so a name the + * 'wp_generate_attachment_metadata' filter removed - or that a failed + * update never persisted - keeps its row and the retried request the + * endpoint documents as idempotent still validates. Rows for sideloads + * that have not been finalized yet survive for a later call, and passing + * the value makes the delete a no-op when the row is already gone, so a + * retried request cleans up without error. Any rows left behind by an + * abandoned upload are removed with the attachment itself. + * + * Retrying is idempotent for the request as it was sent. A name is only + * unavailable to a retry once a later finalize has overwritten the same + * size with a newly sideloaded file, which drops the earlier name from + * the metadata the retry recovers it from. + * + * The names are collected before deleting so a request which repeats + * the same name across many sub-sizes still issues one query per + * distinct name. + */ + $recoverable = $this->get_sideloaded_file_names( $attachment_id, false ); + $consumed = array(); + foreach ( $sub_sizes as $sub_size ) { + foreach ( array( 'file', 'original_image' ) as $key ) { + // Matches the set validate_sub_size_provenance() checked, so + // every name a request was allowed to store is also cleaned up. + if ( + isset( $sub_size[ $key ] ) && + is_string( $sub_size[ $key ] ) && + in_array( $sub_size[ $key ], $recoverable, true ) + ) { + $consumed[] = $sub_size[ $key ]; + } + } + } + + foreach ( array_unique( $consumed ) as $file_name ) { + delete_post_meta( $attachment_id, self::META_KEY_SIDELOAD_FILE_NAME, wp_slash( $file_name ) ); + } + $response_request = new WP_REST_Request( WP_REST_Server::READABLE, rest_get_route_for_post( $attachment_id ) diff --git a/tests/phpunit/tests/rest-api/rest-attachments-controller.php b/tests/phpunit/tests/rest-api/rest-attachments-controller.php index 7f4dcd06c2f71..4dd0b60172cb4 100644 --- a/tests/phpunit/tests/rest-api/rest-attachments-controller.php +++ b/tests/phpunit/tests/rest-api/rest-attachments-controller.php @@ -4102,7 +4102,8 @@ public function test_sideload_scaled_image_requires_auth() { * The image_size argument accepts either a single size name or an array of * size names, so it validates via a custom callback rather than an enum. The * callback must accept 'scaled' and the 'source_original' source-format size, - * and reject unknown sizes. + * reject unknown sizes, and reject a special size sent as an array, since an + * array registers one file under several regular sub-sizes. * * sideload_item() never reads generate_sub_sizes, so advertising it on the * route would silently mislead clients into expecting server-side sub-size @@ -4145,13 +4146,21 @@ public function test_sideload_route_accepts_expected_image_sizes() { 'image_size validation should accept the source_original source-format size.' ); $this->assertTrue( - $validate( array( 'scaled' ), $request, $param_name ), + $validate( array( 'thumbnail', 'medium' ), $request, $param_name ), 'image_size validation should accept an array of size names.' ); + $this->assertTrue( + $validate( array( 'full', 'large' ), $request, $param_name ), + 'image_size validation should accept the full size grouped with a registered size.' + ); $this->assertWPError( $validate( 'not-a-real-size', $request, $param_name ), 'image_size validation should reject an unknown size.' ); + $this->assertWPError( + $validate( array( 'scaled' ), $request, $param_name ), + 'image_size validation should reject a special size sent as an array.' + ); $this->assertArrayNotHasKey( 'generate_sub_sizes', $args, 'Sideload route should not advertise the unused generate_sub_sizes arg.' ); } @@ -4991,20 +5000,19 @@ public function test_finalize_scaled_resets_orientation(): void { $metadata['image_meta']['orientation'] = 6; wp_update_attachment_metadata( $attachment_id, $metadata ); + // Sideload the client-scaled image so finalize has a provenance-backed + // 'scaled' entry to store. + $request = new WP_REST_Request( 'POST', "/wp/v2/media/{$attachment_id}/sideload" ); + $request->set_header( 'Content-Type', 'image/jpeg' ); + $request->set_header( 'Content-Disposition', 'attachment; filename=big-rotated-photo-scaled.jpg' ); + $request->set_param( 'image_size', 'scaled' ); + $request->set_body( (string) file_get_contents( self::$test_file ) ); + $response = rest_get_server()->dispatch( $request ); + $this->assertSame( 200, $response->get_status(), 'Sideloading the scaled image should succeed.' ); + $sub_size = $response->get_data(); + $request = new WP_REST_Request( 'POST', "/wp/v2/media/{$attachment_id}/finalize" ); - $request->set_param( - 'sub_sizes', - array( - array( - 'image_size' => 'scaled', - 'width' => 1920, - 'height' => 2560, - 'file' => '2026/07/big-rotated-photo-scaled.jpg', - 'filesize' => 500000, - 'original_image' => 'big-rotated-photo.jpg', - ), - ) - ); + $request->set_param( 'sub_sizes', array( $sub_size ) ); $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status(), 'Finalize should succeed.' ); @@ -5090,21 +5098,20 @@ public function test_finalize_preserves_image_meta(): void { $original_image_meta = wp_get_attachment_metadata( $attachment_id, true )['image_meta']; - // Finalize with a thumbnail sub-size. + // Sideload a thumbnail sub-size so finalize has a provenance-backed file + // to store. test-image.jpg is 50x50, within the thumbnail maximum. + $request = new WP_REST_Request( 'POST', "/wp/v2/media/{$attachment_id}/sideload" ); + $request->set_header( 'Content-Type', 'image/jpeg' ); + $request->set_header( 'Content-Disposition', 'attachment; filename=2004-07-22-DSC_0008-thumb.jpg' ); + $request->set_param( 'image_size', 'thumbnail' ); + $request->set_body( (string) file_get_contents( DIR_TESTDATA . '/images/test-image.jpg' ) ); + $response = rest_get_server()->dispatch( $request ); + $this->assertSame( 200, $response->get_status(), 'Sideloading a thumbnail should succeed.' ); + $sub_size = $response->get_data(); + + // Finalize with the sideloaded thumbnail sub-size. $request = new WP_REST_Request( 'POST', "/wp/v2/media/{$attachment_id}/finalize" ); - $request->set_param( - 'sub_sizes', - array( - array( - 'image_size' => 'thumbnail', - 'width' => 150, - 'height' => 150, - 'file' => '2004-07-22-DSC_0008-150x150.jpg', - 'mime_type' => 'image/jpeg', - 'filesize' => 5000, - ), - ) - ); + $request->set_param( 'sub_sizes', array( $sub_size ) ); $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status(), 'Finalize should succeed.' ); @@ -5247,12 +5254,16 @@ public function test_sideload_image_size_array() { $this->assertSame( 201, $response->get_status() ); - // Sideload a single file registered under multiple sizes. + /* + * Sideload a single file registered under multiple sizes. The file is + * 50x50 so that it satisfies the registered maximum for every size in + * the group, which is what sharing one file among them requires. + */ $request = new WP_REST_Request( 'POST', "/wp/v2/media/{$attachment_id}/sideload" ); $request->set_header( 'Content-Type', 'image/jpeg' ); $request->set_header( 'Content-Disposition', 'attachment; filename=canola-dup.jpg' ); $request->set_param( 'image_size', array( 'thumbnail', 'medium' ) ); - $request->set_body( (string) file_get_contents( self::$test_file ) ); + $request->set_body( (string) file_get_contents( DIR_TESTDATA . '/images/test-image.jpg' ) ); $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status(), 'Sideloading with an array of sizes should succeed.' ); diff --git a/tests/qunit/fixtures/wp-api-generated.js b/tests/qunit/fixtures/wp-api-generated.js index 1b0eaac6cccd1..4a2d5a3ac7ea8 100644 --- a/tests/qunit/fixtures/wp-api-generated.js +++ b/tests/qunit/fixtures/wp-api-generated.js @@ -3705,8 +3705,11 @@ mockedApiResponse.Schema = { "array" ], "items": { - "type": "string" + "type": "string", + "minLength": 1 }, + "minItems": 1, + "minLength": 1, "required": true }, "convert_format": { @@ -3739,6 +3742,7 @@ mockedApiResponse.Schema = { "description": "Array of sub-size metadata collected from sideload responses.", "type": "array", "default": [], + "maxItems": 100, "items": { "type": "object", "properties": { @@ -3749,8 +3753,11 @@ mockedApiResponse.Schema = { "array" ], "items": { - "type": "string" + "type": "string", + "minLength": 1 }, + "minItems": 1, + "minLength": 1, "required": true }, "width": { @@ -3762,7 +3769,8 @@ mockedApiResponse.Schema = { "minimum": 1 }, "file": { - "type": "string" + "type": "string", + "minLength": 1 }, "mime_type": { "type": "string", @@ -3773,7 +3781,8 @@ mockedApiResponse.Schema = { "minimum": 1 }, "original_image": { - "type": "string" + "type": "string", + "minLength": 1 } } }, From d6de0ec3090d26362834c4f253e89c21bde15f14 Mon Sep 17 00:00:00 2001 From: Aki Hamano Date: Wed, 12 Aug 2026 07:30:55 +0000 Subject: [PATCH 225/634] I18N: Add translator comments in `wp_notify_moderator()`. The trackback and pingback excerpt lines in the comment moderation notification email now document their placeholder for translators. Follow-up to [63030]. Props obenland, SergeyBiryukov, wildworks. See #64899. git-svn-id: https://develop.svn.wordpress.org/trunk@63204 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/pluggable.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wp-includes/pluggable.php b/src/wp-includes/pluggable.php index b283844836b83..aa39c31d78ce5 100644 --- a/src/wp-includes/pluggable.php +++ b/src/wp-includes/pluggable.php @@ -2090,6 +2090,7 @@ function wp_notify_moderator( $comment_id ) { $notify_message .= sprintf( __( 'Website: %1$s (IP address: %2$s, %3$s)' ), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; /* translators: %s: Trackback/pingback/comment author URL. */ $notify_message .= sprintf( __( 'URL: %s' ), $comment->comment_author_url ) . "\r\n"; + /* translators: %s: Trackback excerpt text. */ $notify_message .= sprintf( __( 'Trackback excerpt: %s' ), "\r\n" . $comment_content ) . "\r\n\r\n"; break; @@ -2101,6 +2102,7 @@ function wp_notify_moderator( $comment_id ) { $notify_message .= sprintf( __( 'Website: %1$s (IP address: %2$s, %3$s)' ), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; /* translators: %s: Trackback/pingback/comment author URL. */ $notify_message .= sprintf( __( 'URL: %s' ), $comment->comment_author_url ) . "\r\n"; + /* translators: %s: Pingback excerpt text. */ $notify_message .= sprintf( __( 'Pingback excerpt: %s' ), "\r\n" . $comment_content ) . "\r\n\r\n"; break; From 2260498f3351ecc2702f417499faeeefdeef26ab Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Wed, 12 Aug 2026 11:06:15 +0000 Subject: [PATCH 226/634] Pings/Trackbacks: Adjust auto-approving pingbacks and trackbacks from the same site. Includes: * Updating version annotations to 7.1.0. * Clarifying "this site" means "the same site" in various docs. * Prefixing the new filter with `wp_`. * Extending the tests: * Adds a test to ensure MS sub-site posts are not auto approved. * Adds a test to ensure that post ID sent to filter is zero for external sites. * Adds docs for each test. Developed in https://github.com/WordPress/wordpress-develop/pull/12928. Follow-up to r63036. Props peterwilsoncc, jeremyfelt, youknowriad, wildworks, sabernhardt, SergeyBiryukov. See #65016. git-svn-id: https://develop.svn.wordpress.org/trunk@63207 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/comment.php | 14 ++--- tests/phpunit/tests/comment/checkComment.php | 57 ++++++++++++++++++-- 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/src/wp-includes/comment.php b/src/wp-includes/comment.php index 4ad7d5bbcbcee..7557e9258c87f 100644 --- a/src/wp-includes/comment.php +++ b/src/wp-includes/comment.php @@ -20,13 +20,13 @@ * If the comment author was approved before, then the comment is automatically * approved. * - * Pingbacks originating from this site are automatically approved, as the link - * they report was created by someone who can already publish here. + * Pingbacks originating from the same site are automatically approved, as the + * link they report was created by someone who can already publish here. * * If all checks pass, the function will return true. * * @since 1.2.0 - * @since 7.2.0 Pingbacks from this site are no longer held for moderation. + * @since 7.1.0 Pingbacks from the same site are no longer held for moderation. * * @global wpdb $wpdb WordPress database abstraction object. * @@ -183,18 +183,18 @@ function check_comment( $author, $email, $url, $comment, $user_ip, $user_agent, /** * Filters whether a pingback is approved without being held for moderation. * - * Defaults to true for pingbacks originating from a published post on this + * Defaults to true for pingbacks originating from a published post on the same * site, and false for every other pingback. Trackbacks are never considered, * as they cannot be verified. * - * @since 7.2.0 + * @since 7.1.0 * - * @param bool $approve_pingback Whether to approve the pingback. + * @param bool $approve_pingback Whether to auto-approve the pingback. * @param int $source_id ID of the post on this site the pingback * originated from, or 0 if it came from elsewhere. * @param string $url The URL the pingback was sent from. */ - return (bool) apply_filters( 'auto_approve_pingback', $approve_pingback, $source_id, $url ); + return (bool) apply_filters( 'wp_auto_approve_ping', $approve_pingback, $source_id, $url ); } else { return false; } diff --git a/tests/phpunit/tests/comment/checkComment.php b/tests/phpunit/tests/comment/checkComment.php index f67efa739f6c1..56bd5737f7459 100644 --- a/tests/phpunit/tests/comment/checkComment.php +++ b/tests/phpunit/tests/comment/checkComment.php @@ -306,6 +306,8 @@ public function test_should_return_false_for_a_comment_whose_author_url_is_a_pos } /** + * Test auto approvals can be turned off via the `wp_auto_approve_ping` filter. + * * @ticket 65016 */ public function test_auto_approve_pingback_should_be_able_to_hold_a_pingback_from_this_site() { @@ -313,23 +315,45 @@ public function test_auto_approve_pingback_should_be_able_to_hold_a_pingback_fro $source_url = get_permalink( self::factory()->post->create() ); - add_filter( 'auto_approve_pingback', '__return_false' ); + add_filter( 'wp_auto_approve_ping', '__return_false' ); $this->assertFalse( check_comment( 'Site Title', '', $source_url, 'Excerpt.', '192.168.0.1', '', 'pingback' ) ); } /** + * Test auto approvals can be turned on via the `wp_auto_approve_ping` filter. + * * @ticket 65016 */ public function test_auto_approve_pingback_should_be_able_to_approve_a_pingback_from_another_site() { update_option( 'comment_previously_approved', '1' ); - add_filter( 'auto_approve_pingback', '__return_true' ); + add_filter( 'wp_auto_approve_ping', '__return_true' ); $this->assertTrue( check_comment( 'Site Title', '', 'http://example.com/a-post/', 'Excerpt.', '192.168.0.1', '', 'pingback' ) ); } /** + * Ensure pingbacks from Multisite sub-sites are not auto approved. + * + * @ticket 65016 + * @group ms-required + */ + public function test_auto_approve_pingback_should_not_approve_from_a_different_ms_site() { + update_option( 'comment_previously_approved', '1' ); + + $new_blog = self::factory()->blog->create(); + + switch_to_blog( $new_blog ); + $source_url = get_permalink( self::factory()->post->create() ); + restore_current_blog(); + + $this->assertFalse( check_comment( 'Site Title', '', $source_url, 'Excerpt.', '192.168.0.1', '', 'pingback' ) ); + } + + /** + * Ensure the `wp_auto_approve_ping` filter receives the post ID for same site pings. + * * @ticket 65016 */ public function test_auto_approve_pingback_should_receive_the_source_post_id() { @@ -340,7 +364,7 @@ public function test_auto_approve_pingback_should_receive_the_source_post_id() { $observed = null; add_filter( - 'auto_approve_pingback', + 'wp_auto_approve_ping', static function ( $approve, $source_id ) use ( &$observed ) { $observed = $source_id; return $approve; @@ -354,6 +378,33 @@ static function ( $approve, $source_id ) use ( &$observed ) { $this->assertSame( $post_id, $observed ); } + /** + * Ensure the `wp_auto_approve_ping` filter does not receive a post ID for off-site pings. + * + * @ticket 65016 + */ + public function test_auto_approve_pingback_should_receive_the_post_id_zero_for_off_site_pings() { + update_option( 'comment_previously_approved', '1' ); + + $post_permalink = get_permalink( self::factory()->post->create() ); + $source_url = str_replace( home_url( '/' ), 'http://wordpress.org/', $post_permalink ); + + $observed = null; + add_filter( + 'wp_auto_approve_ping', + static function ( $approve, $source_id ) use ( &$observed ) { + $observed = $source_id; + return $approve; + }, + 10, + 2 + ); + + check_comment( 'Site Title', '', $source_url, 'Excerpt.', '192.168.0.1', '', 'pingback' ); + + $this->assertSame( 0, $observed ); + } + /** * Data provider. * From 7daaa5004ec7deb41c808273b02475ea252e6017 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 12 Aug 2026 12:02:18 +0000 Subject: [PATCH 227/634] Media: Prevent loading images into Imagick which might be PostScript. Props ehtis, dmsnell, jeremyfelt, westonruter, SergeyBiryukov, aaroncampbell, jorbin, batmoo, johnbillion, lancewillett, tyxla, vortfu, xknown. git-svn-id: https://develop.svn.wordpress.org/trunk@63210 602fd350-edb4-49c9-b593-d223f7449a82 --- .../class-wp-image-editor-imagick.php | 260 ++++++++++++++++-- tests/phpstan/baselines/argument.type.neon | 10 - 2 files changed, 235 insertions(+), 35 deletions(-) diff --git a/src/wp-includes/class-wp-image-editor-imagick.php b/src/wp-includes/class-wp-image-editor-imagick.php index 2cb3a694c567b..57ed7c79e56ae 100644 --- a/src/wp-includes/class-wp-image-editor-imagick.php +++ b/src/wp-includes/class-wp-image-editor-imagick.php @@ -21,6 +21,28 @@ class WP_Image_Editor_Imagick extends WP_Image_Editor { */ protected $image; + /** + * Temporarily stores stream image data while processing internally. + * + * @see self::pdf_load_source() + * + * @since 7.0.4 + * + * @var string|null + */ + private $stream_file_data = null; + + /** + * Temporarily stores the parsed given name for an image while processing internally. + * + * @see self::pdf_load_source() + * + * @since 7.0.4 + * + * @var string|null + */ + private $image_given_name = null; + public function __destruct() { if ( $this->image instanceof Imagick ) { // We don't need the original in memory anymore. @@ -130,30 +152,208 @@ public function load() { return true; } - if ( ! is_file( $this->file ) && ! wp_is_stream( $this->file ) ) { + $is_stream = wp_is_stream( $this->file ); + $is_file = ! $is_stream && is_file( $this->file ); + + // Only allow loading files or streams. + if ( ! $is_file && ! $is_stream ) { return new WP_Error( 'error_loading_image', __( 'File does not exist?' ), $this->file ); } + // Establish the provided filename based on the kind of resource being loaded. + $given_filename = $this->file; + if ( 0 === strncasecmp( $given_filename, 'file://', 7 ) ) { + $given_filename = basename( substr( $given_filename, 7 ) ); // 7 is the strlen of 'file://'. + } elseif ( 1 === preg_match( '~^https?://~i', $this->file ) ) { + /* + * For URLs, it will be the final path segment. + * + * Example: + * + * https://wordpress.org/i/happy.png?size=40px + * ╰───────╯ + * this is the given filename + * + * If the stream returns a `Content-Disposition` header it would + * provide an alternative name, but this is used as a reasonable + * proxy to avoid adding the additional complexity of reading and + * parsing the returned HTTP headers. + */ + $url_path = wp_parse_url( $this->file, PHP_URL_PATH ); + + // This URL can not be parsed, so it is not a valid image resource. + if ( false === $url_path ) { + return new WP_Error( 'error_loading_image', __( 'File is not an image.' ), $this->file ); + } + + /** + * The URL has an empty path, so continue with an empty string. + * + * This is the case with a URL such as `https://example.com?file_id=123` + */ + if ( null === $url_path ) { + $url_path = ''; + } + + $last_path_at = strrpos( $url_path, '/' ); + $given_filename = is_int( $last_path_at ) ? substr( $url_path, $last_path_at + 1 ) : $url_path; + $given_filename = rawurldecode( $given_filename ); + } + + /* + * Strip off any potential `Imagick` format specifiers. + * + * If a real file exists with the identified format specifier, then + * `Imagick` may not treat it as a format, but WordPress will reject + * it anyway to avoid adding more complexity into this detection. + * + * `Imagick` reads only the first `FORMAT:` specifier on a name, but + * stripping a segment would promote a second specifier to the front + * of the name handed to `Imagick`, which would then honor it. + * + * Loop to capture all format specifiers for comparison. + * + * Exclude Windows drive-letter prefixes from here. + */ + $imagick_formats = array(); + while ( + false !== ( $format_ends_at = strpos( $given_filename, ':' ) ) && + 1 !== preg_match( '~^[a-z]:~i', $given_filename ) + ) { + $imagick_formats[] = strtoupper( substr( $given_filename, 0, $format_ends_at ) ); + $given_filename = substr( $given_filename, $format_ends_at + 1 ); + } + + $file_extension = strtolower( pathinfo( $given_filename, PATHINFO_EXTENSION ) ); + /* * Even though Imagick uses less PHP memory than GD, set higher limit * for users that have low PHP.ini limits. */ wp_raise_memory_limit( 'image' ); + /** + * Read the resource header for MIME sniffing. + * + * For files, which will be passed into Imagick by their file names, avoid + * eagerly loading the entire contents into PHP memory. For streams, however, + * it’s more important to avoid validating a separate copy of the file data + * than is later fetched by Imagick, so go ahead and load the entire payload, + * then pass it to Imagick as the data blob itself. + * + * @link https://mimesniff.spec.whatwg.org/#reading-the-resource-header + */ try { - $this->image = new Imagick(); - $file_extension = strtolower( pathinfo( $this->file, PATHINFO_EXTENSION ) ); + if ( $is_file ) { + $file_data = file_get_contents( $this->file, false, null, 0, 1445 ); + } else { + $file_data = file_get_contents( $this->file ); + } + } catch ( Exception $e ) { + $file_data = false; + } + if ( false === $file_data ) { + return new WP_Error( 'error_loading_image', __( 'File does not exist?' ), $this->file ); + } + + $pdf_extensions = array( + 'ai', + 'epdf', + 'pdf', + 'pdfa', + 'pocketmod', + ); + + // Reject files claiming to be PDFs which lack the required signature. + $has_pdf_extension = in_array( $file_extension, $pdf_extensions, true ); + $has_pdf_signature = str_starts_with( $file_data, '%PDF-' ); + if ( $has_pdf_extension && ! $has_pdf_signature ) { + return new WP_Error( 'invalid_image', __( 'File is not an image.' ), $this->file ); + } + + $ps_formats = array( + 'DPS', + 'EPI', + 'EPS', + 'EPSF', + 'EPSI', + 'PS', + 'WPG', + ); + + $ps_extensions = array( + 'dps', + 'epi', + 'eps', + 'eps2', + 'eps3', + 'epsf', + 'epsi', + 'ept', + 'ept2', + 'ept3', + 'ps', + 'ps2', + 'ps3', + 'wpg', + ); + + // Reject files which Imagick will parse as PostScript. + if ( + array() !== array_intersect( $imagick_formats, $ps_formats ) || + in_array( $file_extension, $ps_extensions, true ) || + str_starts_with( $file_data, '%!' ) || + str_starts_with( $file_data, "\x04%!" ) || + str_starts_with( $file_data, "\xC5\xD0\xD3\xC6" ) || + str_starts_with( $file_data, "\xFFWPC" ) + ) { + return new WP_Error( 'invalid_image', __( 'File is not an image.' ), $this->file ); + } + + $compressed_extensions = array( + 'gz', + 'bz2', + 'svgz', + 'z', + 'wmz', + ); + + /* + * Reject compressed archives that Imagick will transparently decompress. + * Unfortunately this rejects `.svgz` because there’s no intermediate step + * in the loading process. `Imagick` would decompress the file, then look + * to see what kind of content was decompressed instead of asserting SVG. + */ + if ( + in_array( $file_extension, $compressed_extensions, true ) || + str_starts_with( $file_data, "\x1F\x8B\x08" ) || // gzip + str_starts_with( $file_data, 'BZh' ) || // bzip2 + str_starts_with( $file_data, "\x1F\x9D" ) // compress + ) { + return new WP_Error( 'invalid_image', __( 'File is not an image.' ), $this->file ); + } + + try { + $this->image = new Imagick(); - if ( 'pdf' === $file_extension ) { - $pdf_loaded = $this->pdf_load_source(); + if ( $has_pdf_signature ) { + /* + * Load these values for use in the helper method without forcing a change + * of its expected arguments, but then free them after calling to prevent + * keeping them around in memory and bloating the app. + */ + $this->stream_file_data = $is_stream ? $file_data : null; + $this->image_given_name = $given_filename; + $pdf_loaded = $this->pdf_load_source(); + $this->stream_file_data = null; + $this->image_given_name = null; if ( is_wp_error( $pdf_loaded ) ) { return $pdf_loaded; } } else { - if ( wp_is_stream( $this->file ) ) { - // Due to reports of issues with streams with `Imagick::readImageFile()`, uses `Imagick::readImageBlob()` instead. - $this->image->readImageBlob( file_get_contents( $this->file ), $this->file ); + if ( $is_stream ) { + $this->image->readImageBlob( $file_data, $given_filename ); } else { $this->image->readImage( $this->file ); } @@ -168,7 +368,7 @@ public function load() { $this->image->setIteratorIndex( 0 ); } - if ( 'pdf' === $file_extension ) { + if ( $has_pdf_signature ) { $this->remove_pdf_alpha_channel(); } @@ -1159,25 +1359,35 @@ protected function pdf_load_source() { return $filename; } - try { - /* - * When generating thumbnails from cropped PDF pages, Imagemagick uses the uncropped - * area (resulting in unnecessary whitespace) unless the following option is set. - */ - $this->image->setOption( 'pdf:use-cropbox', true ); + foreach ( array( 'true', 'false' ) as $use_cropbox ) { + try { + /** + * When generating thumbnails from cropped PDF pages, Imagemagick uses the uncropped + * area (resulting in unnecessary whitespace) unless the following option is set. + * + * However, it sometimes fails, so if that happens, run it without the option. + * + * @ticket 48853 + */ + $this->image->setOption( 'pdf:use-cropbox', $use_cropbox ); - /* - * Reading image after Imagick instantiation because `setResolution` - * only applies correctly before the image is read. - */ - $this->image->readImage( $filename ); - } catch ( Exception $e ) { - // Attempt to run `gs` without the `use-cropbox` option. See #48853. - $this->image->setOption( 'pdf:use-cropbox', false ); + /* + * Reading image after Imagick instantiation because `setResolution` + * only applies correctly before the image is read. + */ + if ( is_string( $this->stream_file_data ) ) { + $this->image->setFilename( 'PDF:unknown.pdf[0]' ); + $this->image->readImageBlob( $this->stream_file_data, $this->image_given_name ); + } else { + $this->image->readImage( $filename ); + } - $this->image->readImage( $filename ); + return true; + } catch ( Exception $e ) { + continue; + } } - return true; + return new WP_Error( 'invalid_image', __( 'File is not an image.' ), $this->file ); } } diff --git a/tests/phpstan/baselines/argument.type.neon b/tests/phpstan/baselines/argument.type.neon index 7618b79a4c615..675559b0e3f9b 100644 --- a/tests/phpstan/baselines/argument.type.neon +++ b/tests/phpstan/baselines/argument.type.neon @@ -1128,21 +1128,11 @@ parameters: identifier: argument.type count: 1 path: ../../../src/wp-includes/class-wp-image-editor-imagick.php - - - message: '#^Parameter \#2 \$value of method Imagick\:\:setOption\(\) expects string, false given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-includes/class-wp-image-editor-imagick.php - message: '#^Parameter \#2 \$value of method Imagick\:\:setOption\(\) expects string, int given\.$#' identifier: argument.type count: 1 path: ../../../src/wp-includes/class-wp-image-editor-imagick.php - - - message: '#^Parameter \#2 \$value of method Imagick\:\:setOption\(\) expects string, true given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-includes/class-wp-image-editor-imagick.php - message: '#^Parameter \#1 \$ids of function _prime_post_caches expects array\, list\ given\.$#' identifier: argument.type From 4d48e14abb351f7306947f602b88d31c8b8339a9 Mon Sep 17 00:00:00 2001 From: Aki Hamano Date: Wed, 12 Aug 2026 12:04:56 +0000 Subject: [PATCH 228/634] Bundled themes: Version bumps for version 7.1. This bumps the version for the upcoming release WordPress 7.1. Twenty Ten: 4.7. Twenty Eleven: 5.2. Twenty Twelve: 4.9. Twenty Thirteen: 4.7. Twenty Fourteen: 4.6. Twenty Fifteen: 4.3. Twenty Sixteen: 3.9. Twenty Seventeen: 4.2. Twenty Nineteen: 3.4. Twenty Twenty: 3.2. Twenty Twenty-One: 2.9. Twenty Twenty-Two: 2.2. Twenty Twenty-Three: 1.7. Twenty Twenty-Four: 1.6. Twenty Twenty-Five: 1.5. Props khokansardar, mukesh27, rcorrales, sabernhardt, shailu25, wildworks. Fixes #65322. git-svn-id: https://develop.svn.wordpress.org/trunk@63211 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-content/themes/twentyeleven/header.php | 2 +- src/wp-content/themes/twentyeleven/readme.txt | 9 +++++++-- src/wp-content/themes/twentyeleven/style.css | 4 ++-- src/wp-content/themes/twentyfifteen/functions.php | 2 +- src/wp-content/themes/twentyfifteen/readme.txt | 9 +++++++-- src/wp-content/themes/twentyfifteen/style.css | 4 ++-- src/wp-content/themes/twentyfourteen/functions.php | 2 +- src/wp-content/themes/twentyfourteen/readme.txt | 9 +++++++-- src/wp-content/themes/twentyfourteen/style.css | 4 ++-- src/wp-content/themes/twentynineteen/package-lock.json | 4 ++-- src/wp-content/themes/twentynineteen/package.json | 2 +- src/wp-content/themes/twentynineteen/readme.txt | 9 +++++++-- src/wp-content/themes/twentynineteen/style-rtl.css | 4 ++-- src/wp-content/themes/twentynineteen/style.css | 4 ++-- src/wp-content/themes/twentynineteen/style.scss | 4 ++-- src/wp-content/themes/twentyseventeen/functions.php | 2 +- src/wp-content/themes/twentyseventeen/readme.txt | 9 +++++++-- src/wp-content/themes/twentyseventeen/style.css | 4 ++-- src/wp-content/themes/twentysixteen/functions.php | 4 ++-- src/wp-content/themes/twentysixteen/readme.txt | 9 +++++++-- src/wp-content/themes/twentysixteen/style.css | 4 ++-- src/wp-content/themes/twentyten/header.php | 2 +- src/wp-content/themes/twentyten/readme.txt | 9 +++++++-- src/wp-content/themes/twentyten/style.css | 4 ++-- src/wp-content/themes/twentythirteen/functions.php | 2 +- src/wp-content/themes/twentythirteen/readme.txt | 9 +++++++-- src/wp-content/themes/twentythirteen/style.css | 4 ++-- src/wp-content/themes/twentytwelve/functions.php | 2 +- src/wp-content/themes/twentytwelve/readme.txt | 9 +++++++-- src/wp-content/themes/twentytwelve/style.css | 4 ++-- src/wp-content/themes/twentytwenty/package-lock.json | 4 ++-- src/wp-content/themes/twentytwenty/package.json | 2 +- src/wp-content/themes/twentytwenty/readme.txt | 9 +++++++-- src/wp-content/themes/twentytwenty/style-rtl.css | 4 ++-- src/wp-content/themes/twentytwenty/style.css | 4 ++-- src/wp-content/themes/twentytwentyfive/readme.txt | 2 +- src/wp-content/themes/twentytwentyfive/style.css | 2 +- src/wp-content/themes/twentytwentyfour/readme.txt | 9 +++++++-- src/wp-content/themes/twentytwentyfour/style.css | 4 ++-- .../assets/sass/01-settings/file-header.scss | 4 ++-- src/wp-content/themes/twentytwentyone/package-lock.json | 4 ++-- src/wp-content/themes/twentytwentyone/package.json | 2 +- src/wp-content/themes/twentytwentyone/readme.txt | 9 +++++++-- src/wp-content/themes/twentytwentyone/style-rtl.css | 4 ++-- src/wp-content/themes/twentytwentyone/style.css | 4 ++-- src/wp-content/themes/twentytwentythree/readme.txt | 9 +++++++-- src/wp-content/themes/twentytwentythree/style.css | 4 ++-- src/wp-content/themes/twentytwentytwo/package-lock.json | 4 ++-- src/wp-content/themes/twentytwentytwo/package.json | 2 +- src/wp-content/themes/twentytwentytwo/readme.txt | 9 +++++++-- src/wp-content/themes/twentytwentytwo/style.css | 4 ++-- 51 files changed, 159 insertions(+), 89 deletions(-) diff --git a/src/wp-content/themes/twentyeleven/header.php b/src/wp-content/themes/twentyeleven/header.php index 3798e6862d0a8..2fb3093edfec9 100644 --- a/src/wp-content/themes/twentyeleven/header.php +++ b/src/wp-content/themes/twentyeleven/header.php @@ -43,7 +43,7 @@ ?> - + - + Date: Wed, 12 Aug 2026 12:17:30 +0000 Subject: [PATCH 229/634] Coding Standards: Lint the About page CSS. Linting the About page styles with Stylelint reported a number of CSS coding standards violations, and this changeset addresses most of them. Discussed in: https://github.com/WordPress/wordpress-develop/pull/13014 Follow-up to [63182]. Props afercia, mukesh27, wildworks. See #65856. git-svn-id: https://develop.svn.wordpress.org/trunk@63212 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/css/about.css | 55 +++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/src/wp-admin/css/about.css b/src/wp-admin/css/about.css index 871d819ce905a..bb17f4f8d2006 100644 --- a/src/wp-admin/css/about.css +++ b/src/wp-admin/css/about.css @@ -34,7 +34,7 @@ --accent-3: #ececec; /* hr background */ /* Header background on small screens */ - --accent-gradient: linear-gradient(90deg, #000000 4.7%, var(--accent-1) 83.84%)/*rtl:linear-gradient(-90deg, #000000 4.7%, var(--accent-1) 83.84%)*/; + --accent-gradient: linear-gradient(90deg, #000 4.7%, var(--accent-1) 83.84%)/*rtl:linear-gradient(-90deg, #000 4.7%, var(--accent-1) 83.84%)*/; /* Navigation colors. */ --nav-background: #fff; @@ -293,13 +293,11 @@ margin-bottom: calc(var(--gap) * 2); } - .about__section.has-2-columns.has-gutters .column, .about__section.has-2-columns.has-gutters .column, .about__section.has-3-columns.has-gutters .column { margin-bottom: var(--gap); } - .about__section.has-2-columns.has-gutters .column:last-child, .about__section.has-2-columns.has-gutters .column:last-child, .about__section.has-3-columns.has-gutters .column:last-child { margin-bottom: 0; @@ -359,12 +357,12 @@ } .about__section .column.is-left-padding-zero { - padding-right: 0; - } + padding-right: 0; + } - .about__section .column.is-right-padding-zero { - padding-left: 0; - } + .about__section .column.is-right-padding-zero { + padding-left: 0; + } } @media screen and (max-width: 480px) { @@ -445,9 +443,6 @@ .about__container p { text-wrap: pretty; -} - -.about__container p { font-size: inherit; line-height: inherit; } @@ -457,7 +452,7 @@ margin-bottom: 1rem; font-size: 1.5rem; font-weight: 300; - line-height: 160%; + line-height: 1.6; } .about__section a { @@ -608,49 +603,49 @@ padding-right: 26rem; /* Space for the background image. */ min-height: clamp(10rem, 25vw, 18.75rem); border-radius: var(--border-radius); - background-image: url( "https://s.w.org/images/core/7.1/about-header-default.webp?ver=20260804" ); + background-image: url(https://s.w.org/images/core/7.1/about-header-default.webp?ver=20260804); background-repeat: no-repeat; background-position: right center; background-size: cover; background-color: var(--background); color: var(--text-light); - margin-bottom: .25rem; + margin-bottom: 0.25rem; } -.credits-php .about__header { - background-image: url( "https://s.w.org/images/core/7.1/about-header-credits.webp?ver=20260804" ); +.credits-php .about__header { + background-image: url(https://s.w.org/images/core/7.1/about-header-credits.webp?ver=20260804); } -.freedoms-php .about__header { - background-image: url( "https://s.w.org/images/core/7.1/about-header-freedoms.webp?ver=20260804" ); +.freedoms-php .about__header { + background-image: url(https://s.w.org/images/core/7.1/about-header-freedoms.webp?ver=20260804); } -.privacy-php .about__header { - background-image: url( "https://s.w.org/images/core/7.1/about-header-privacy.webp?ver=20260804" ); +.privacy-php .about__header { + background-image: url(https://s.w.org/images/core/7.1/about-header-privacy.webp?ver=20260804); } .contribute-php .about__header { - background-image: url( "https://s.w.org/images/core/7.1/about-header-get-involved.webp?ver=20260804" ); + background-image: url(https://s.w.org/images/core/7.1/about-header-get-involved.webp?ver=20260804); } [dir="rtl"] .about__header { - background-image: url( "https://s.w.org/images/core/7.1/about-header-default-rtl.webp?ver=20260804" ); + background-image: url(https://s.w.org/images/core/7.1/about-header-default-rtl.webp?ver=20260804); } -[dir="rtl"] .credits-php .about__header { - background-image: url( "https://s.w.org/images/core/7.1/about-header-credits-rtl.webp?ver=20260804" ); +[dir="rtl"] .credits-php .about__header { + background-image: url(https://s.w.org/images/core/7.1/about-header-credits-rtl.webp?ver=20260804); } -[dir="rtl"] .freedoms-php .about__header { - background-image: url( "https://s.w.org/images/core/7.1/about-header-freedoms-rtl.webp?ver=20260804" ); +[dir="rtl"] .freedoms-php .about__header { + background-image: url(https://s.w.org/images/core/7.1/about-header-freedoms-rtl.webp?ver=20260804); } -[dir="rtl"] .privacy-php .about__header { - background-image: url( "https://s.w.org/images/core/7.1/about-header-privacy-rtl.webp?ver=20260804" ); +[dir="rtl"] .privacy-php .about__header { + background-image: url(https://s.w.org/images/core/7.1/about-header-privacy-rtl.webp?ver=20260804); } [dir="rtl"] .contribute-php .about__header { - background-image: url( "https://s.w.org/images/core/7.1/about-header-get-involved-rtl.webp?ver=20260804" ); + background-image: url(https://s.w.org/images/core/7.1/about-header-get-involved-rtl.webp?ver=20260804); } .about__header-image { @@ -1082,7 +1077,7 @@ .about-wrap figcaption { font-size: 13px; text-align: center; - color: white; + color: #fff; text-overflow: ellipsis; } From c90e0c03ca1c23c92937d573b17d975b7d922181 Mon Sep 17 00:00:00 2001 From: Jonathan Desrosiers Date: Wed, 12 Aug 2026 14:43:28 +0000 Subject: [PATCH 230/634] Build/Test Tools: Change workflow file references back to local ones. [63167] made several required post-branching changes to `trunk`, but also included the results of `grunt replace:workflow-references-local-to-remote` which is run as part of `grunt post-branching`. All reusable workflow files in `trunk` should be called using local references so that changes to these files are automatically tested within pull requests without having to push the changes to a fork and change the references. Props joedolson, wildworks. Fixes #65844. See #62416. git-svn-id: https://develop.svn.wordpress.org/trunk@63230 602fd350-edb4-49c9-b593-d223f7449a82 --- .github/workflows/check-built-files.yml | 2 +- .github/workflows/cleanup-pull-requests.yml | 2 +- .github/workflows/coding-standards.yml | 6 +++--- .github/workflows/end-to-end-tests.yml | 4 ++-- .github/workflows/javascript-tests.yml | 4 ++-- .github/workflows/javascript-type-checking.yml | 4 ++-- .github/workflows/local-docker-environment.yml | 6 +++--- .github/workflows/performance.yml | 6 +++--- .github/workflows/php-compatibility.yml | 4 ++-- .github/workflows/phpstan-static-analysis.yml | 4 ++-- .github/workflows/phpunit-tests.yml | 14 +++++++------- .github/workflows/test-build-processes.yml | 6 +++--- .github/workflows/upgrade-develop-testing.yml | 4 ++-- .github/workflows/workflow-lint.yml | 2 +- 14 files changed, 34 insertions(+), 34 deletions(-) diff --git a/.github/workflows/check-built-files.yml b/.github/workflows/check-built-files.yml index 3f9ae477c2b3d..01a239c4eb3b0 100644 --- a/.github/workflows/check-built-files.yml +++ b/.github/workflows/check-built-files.yml @@ -49,6 +49,6 @@ jobs: check-for-built-file-changes: name: Check built files if: ${{ github.repository == 'wordpress/wordpress-develop' }} - uses: WordPress/wordpress-develop/.github/workflows/reusable-check-built-files.yml@trunk + uses: ./.github/workflows/reusable-check-built-files.yml permissions: contents: read diff --git a/.github/workflows/cleanup-pull-requests.yml b/.github/workflows/cleanup-pull-requests.yml index 6c8d38e67b0b7..578710dcf56ac 100644 --- a/.github/workflows/cleanup-pull-requests.yml +++ b/.github/workflows/cleanup-pull-requests.yml @@ -25,4 +25,4 @@ jobs: permissions: pull-requests: write if: ${{ github.repository == 'WordPress/wordpress-develop' }} - uses: WordPress/wordpress-develop/.github/workflows/reusable-cleanup-pull-requests.yml@trunk + uses: ./.github/workflows/reusable-cleanup-pull-requests.yml diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 9342f2abc7f94..8f1e9fe701330 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -47,7 +47,7 @@ jobs: # Runs the PHP coding standards checks. phpcs: name: Coding standards - uses: WordPress/wordpress-develop/.github/workflows/reusable-coding-standards-php.yml@trunk + uses: ./.github/workflows/reusable-coding-standards-php.yml permissions: contents: read if: | @@ -62,7 +62,7 @@ jobs: # Runs the JavaScript coding standards checks. jshint: name: Coding standards - uses: WordPress/wordpress-develop/.github/workflows/reusable-coding-standards-javascript.yml@trunk + uses: ./.github/workflows/reusable-coding-standards-javascript.yml permissions: contents: read if: | @@ -76,7 +76,7 @@ jobs: slack-notifications: name: Slack Notifications - uses: WordPress/wordpress-develop/.github/workflows/slack-notifications.yml@trunk + uses: ./.github/workflows/slack-notifications.yml permissions: actions: read contents: read diff --git a/.github/workflows/end-to-end-tests.yml b/.github/workflows/end-to-end-tests.yml index a7f6be21989f5..d91b6512f4b49 100644 --- a/.github/workflows/end-to-end-tests.yml +++ b/.github/workflows/end-to-end-tests.yml @@ -54,7 +54,7 @@ jobs: # Runs the end-to-end test suite. e2e-tests: name: ${{ matrix.label }} - uses: WordPress/wordpress-develop/.github/workflows/reusable-end-to-end-tests.yml@trunk + uses: ./.github/workflows/reusable-end-to-end-tests.yml permissions: contents: read if: | @@ -76,7 +76,7 @@ jobs: slack-notifications: name: Slack Notifications - uses: WordPress/wordpress-develop/.github/workflows/slack-notifications.yml@trunk + uses: ./.github/workflows/slack-notifications.yml permissions: actions: read contents: read diff --git a/.github/workflows/javascript-tests.yml b/.github/workflows/javascript-tests.yml index ec97fa07c45bd..8b1241038773d 100644 --- a/.github/workflows/javascript-tests.yml +++ b/.github/workflows/javascript-tests.yml @@ -50,7 +50,7 @@ jobs: # Runs the WordPress Core JavaScript tests. test-js: name: QUnit Tests - uses: WordPress/wordpress-develop/.github/workflows/reusable-javascript-tests.yml@trunk + uses: ./.github/workflows/reusable-javascript-tests.yml permissions: contents: read if: | @@ -64,7 +64,7 @@ jobs: slack-notifications: name: Slack Notifications - uses: WordPress/wordpress-develop/.github/workflows/slack-notifications.yml@trunk + uses: ./.github/workflows/slack-notifications.yml permissions: actions: read contents: read diff --git a/.github/workflows/javascript-type-checking.yml b/.github/workflows/javascript-type-checking.yml index b926821c1facc..65561cabbb1e1 100644 --- a/.github/workflows/javascript-type-checking.yml +++ b/.github/workflows/javascript-type-checking.yml @@ -43,7 +43,7 @@ jobs: # Runs JavaScript type checking. typecheck: name: JavaScript type checking - uses: WordPress/wordpress-develop/.github/workflows/reusable-javascript-type-checking-v1.yml@trunk + uses: ./.github/workflows/reusable-javascript-type-checking-v1.yml permissions: contents: read if: | @@ -57,7 +57,7 @@ jobs: slack-notifications: name: Slack Notifications - uses: WordPress/wordpress-develop/.github/workflows/slack-notifications.yml@trunk + uses: ./.github/workflows/slack-notifications.yml permissions: actions: read contents: read diff --git a/.github/workflows/local-docker-environment.yml b/.github/workflows/local-docker-environment.yml index a6aa2bae00803..856db171726b6 100644 --- a/.github/workflows/local-docker-environment.yml +++ b/.github/workflows/local-docker-environment.yml @@ -76,7 +76,7 @@ jobs: # build-test-matrix: name: Build Test Matrix - uses: WordPress/wordpress-develop/.github/workflows/reusable-support-json-reader-v1.yml@trunk + uses: ./.github/workflows/reusable-support-json-reader-v1.yml permissions: contents: read if: ${{ github.repository == 'WordPress/wordpress-develop' }} @@ -86,7 +86,7 @@ jobs: # Tests the local Docker environment. environment-tests-mysql: name: PHP ${{ matrix.php }} - uses: WordPress/wordpress-develop/.github/workflows/reusable-test-local-docker-environment-v1.yml@trunk + uses: ./.github/workflows/reusable-test-local-docker-environment-v1.yml permissions: contents: read needs: [ build-test-matrix ] @@ -122,7 +122,7 @@ jobs: slack-notifications: name: Slack Notifications - uses: WordPress/wordpress-develop/.github/workflows/slack-notifications.yml@trunk + uses: ./.github/workflows/slack-notifications.yml permissions: actions: read contents: read diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml index ca94c45487305..ef02c51101557 100644 --- a/.github/workflows/performance.yml +++ b/.github/workflows/performance.yml @@ -101,7 +101,7 @@ jobs: # Runs the performance test suite. performance: name: ${{ matrix.multisite && 'Multisite' || 'Single Site' }} ${{ matrix.memcached && 'Memcached' || 'Default' }} - uses: WordPress/wordpress-develop/.github/workflows/reusable-performance-test-v2.yml@trunk + uses: ./.github/workflows/reusable-performance-test-v2.yml needs: [ determine-matrix ] permissions: contents: read @@ -119,7 +119,7 @@ jobs: compare: name: ${{ matrix.label }} - uses: WordPress/wordpress-develop/.github/workflows/reusable-performance-report-v2.yml@trunk + uses: ./.github/workflows/reusable-performance-report-v2.yml needs: [ determine-matrix, performance ] permissions: contents: read @@ -140,7 +140,7 @@ jobs: slack-notifications: name: Slack Notifications - uses: WordPress/wordpress-develop/.github/workflows/slack-notifications.yml@trunk + uses: ./.github/workflows/slack-notifications.yml permissions: actions: read contents: read diff --git a/.github/workflows/php-compatibility.yml b/.github/workflows/php-compatibility.yml index c91a1652cbc55..4bae7e0a381b0 100644 --- a/.github/workflows/php-compatibility.yml +++ b/.github/workflows/php-compatibility.yml @@ -39,7 +39,7 @@ jobs: # Runs PHP compatibility testing. php-compatibility: name: Check PHP compatibility - uses: WordPress/wordpress-develop/.github/workflows/reusable-php-compatibility.yml@trunk + uses: ./.github/workflows/reusable-php-compatibility.yml permissions: contents: read if: | @@ -53,7 +53,7 @@ jobs: slack-notifications: name: Slack Notifications - uses: WordPress/wordpress-develop/.github/workflows/slack-notifications.yml@trunk + uses: ./.github/workflows/slack-notifications.yml permissions: actions: read contents: read diff --git a/.github/workflows/phpstan-static-analysis.yml b/.github/workflows/phpstan-static-analysis.yml index e1ab13c68a37d..6a26c75b16525 100644 --- a/.github/workflows/phpstan-static-analysis.yml +++ b/.github/workflows/phpstan-static-analysis.yml @@ -39,7 +39,7 @@ jobs: # Runs PHPStan Static Analysis. phpstan: name: PHP static analysis - uses: WordPress/wordpress-develop/.github/workflows/reusable-phpstan-static-analysis-v1.yml@trunk + uses: ./.github/workflows/reusable-phpstan-static-analysis-v1.yml permissions: contents: read if: | @@ -53,7 +53,7 @@ jobs: slack-notifications: name: Slack Notifications - uses: WordPress/wordpress-develop/.github/workflows/slack-notifications.yml@trunk + uses: ./.github/workflows/slack-notifications.yml permissions: actions: read contents: read diff --git a/.github/workflows/phpunit-tests.yml b/.github/workflows/phpunit-tests.yml index 99b2025e7c52a..f0f1282f73a93 100644 --- a/.github/workflows/phpunit-tests.yml +++ b/.github/workflows/phpunit-tests.yml @@ -55,7 +55,7 @@ jobs: # Downloads and verifies the Gutenberg build once for all PHPUnit jobs. prepare-gutenberg: name: Prepare Gutenberg Assets - uses: WordPress/wordpress-develop/.github/workflows/reusable-prepare-gutenberg.yml@trunk + uses: ./.github/workflows/reusable-prepare-gutenberg.yml permissions: contents: read if: | @@ -76,7 +76,7 @@ jobs: # test-with-mysql: name: PHP ${{ matrix.php }} - uses: WordPress/wordpress-develop/.github/workflows/reusable-phpunit-tests-v3.yml@trunk + uses: ./.github/workflows/reusable-phpunit-tests-v3.yml needs: prepare-gutenberg permissions: contents: read @@ -168,7 +168,7 @@ jobs: # test-with-mariadb: name: PHP ${{ matrix.php }} - uses: WordPress/wordpress-develop/.github/workflows/reusable-phpunit-tests-v3.yml@trunk + uses: ./.github/workflows/reusable-phpunit-tests-v3.yml needs: prepare-gutenberg permissions: contents: read @@ -235,7 +235,7 @@ jobs: # test-innovation-releases: name: PHP ${{ matrix.php }} - uses: WordPress/wordpress-develop/.github/workflows/reusable-phpunit-tests-v3.yml@trunk + uses: ./.github/workflows/reusable-phpunit-tests-v3.yml needs: prepare-gutenberg permissions: contents: read @@ -291,7 +291,7 @@ jobs: # html-api-test-groups: name: ${{ matrix.label }} - uses: WordPress/wordpress-develop/.github/workflows/reusable-phpunit-tests-v3.yml@trunk + uses: ./.github/workflows/reusable-phpunit-tests-v3.yml needs: prepare-gutenberg permissions: contents: read @@ -334,7 +334,7 @@ jobs: # limited-matrix-for-forks: name: PHP ${{ matrix.php }} - uses: WordPress/wordpress-develop/.github/workflows/reusable-phpunit-tests-v3.yml@trunk + uses: ./.github/workflows/reusable-phpunit-tests-v3.yml needs: prepare-gutenberg permissions: contents: read @@ -398,7 +398,7 @@ jobs: slack-notifications: name: Slack Notifications - uses: WordPress/wordpress-develop/.github/workflows/slack-notifications.yml@trunk + uses: ./.github/workflows/slack-notifications.yml permissions: actions: read contents: read diff --git a/.github/workflows/test-build-processes.yml b/.github/workflows/test-build-processes.yml index be54536d7c6d3..cd32d99cacb1f 100644 --- a/.github/workflows/test-build-processes.yml +++ b/.github/workflows/test-build-processes.yml @@ -48,7 +48,7 @@ jobs: # Tests the WordPress Core build process. test-core-build-process: name: Core running from ${{ matrix.directory }} - uses: WordPress/wordpress-develop/.github/workflows/reusable-test-core-build-process.yml@trunk + uses: ./.github/workflows/reusable-test-core-build-process.yml permissions: contents: read if: | @@ -90,7 +90,7 @@ jobs: # See https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability. test-core-build-process-additional-os: name: Core running from ${{ matrix.directory }} - uses: WordPress/wordpress-develop/.github/workflows/reusable-test-core-build-process.yml@trunk + uses: ./.github/workflows/reusable-test-core-build-process.yml permissions: contents: read if: ${{ github.repository == 'WordPress/wordpress-develop' }} @@ -105,7 +105,7 @@ jobs: slack-notifications: name: Slack Notifications - uses: WordPress/wordpress-develop/.github/workflows/slack-notifications.yml@trunk + uses: ./.github/workflows/slack-notifications.yml permissions: actions: read contents: read diff --git a/.github/workflows/upgrade-develop-testing.yml b/.github/workflows/upgrade-develop-testing.yml index bc920a115321e..f14736af874a1 100644 --- a/.github/workflows/upgrade-develop-testing.yml +++ b/.github/workflows/upgrade-develop-testing.yml @@ -68,7 +68,7 @@ jobs: # being updated to keep the matrix as small as is reasonable. upgrade-tests-develop: name: Upgrade from ${{ matrix.wp }} - uses: WordPress/wordpress-develop/.github/workflows/reusable-upgrade-testing.yml@trunk + uses: ./.github/workflows/reusable-upgrade-testing.yml if: ${{ github.repository == 'WordPress/wordpress-develop' }} needs: [ build ] permissions: @@ -127,7 +127,7 @@ jobs: slack-notifications: name: Slack Notifications - uses: WordPress/wordpress-develop/.github/workflows/slack-notifications.yml@trunk + uses: ./.github/workflows/slack-notifications.yml permissions: actions: read contents: read diff --git a/.github/workflows/workflow-lint.yml b/.github/workflows/workflow-lint.yml index f04417964d6aa..b2d5c2638e7b4 100644 --- a/.github/workflows/workflow-lint.yml +++ b/.github/workflows/workflow-lint.yml @@ -48,7 +48,7 @@ jobs: slack-notifications: name: Slack Notifications - uses: WordPress/wordpress-develop/.github/workflows/slack-notifications.yml@trunk + uses: ./.github/workflows/slack-notifications.yml permissions: actions: read contents: read From 6c4a263256c10e7716ad1aa0d65f0e5b8fa726f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Zieli=C5=84ski?= Date: Thu, 13 Aug 2026 14:29:46 +0000 Subject: [PATCH 231/634] HTML API: Make `class_list()` examples interactive. Converts the `WP_HTML_Processor::class_list()` and `WP_HTML_Tag_Processor::class_list()` examples to runnable WordPress Playground snippets. Corrects the encoded closing angle bracket so the expected output matches the parsed class name. Developed in https://github.com/WordPress/wordpress-develop/pull/13034. Props jonsurrell. See #64896. git-svn-id: https://develop.svn.wordpress.org/trunk@63293 602fd350-edb4-49c9-b593-d223f7449a82 --- .../html-api/class-wp-html-processor.php | 22 ++++++++++++------- .../html-api/class-wp-html-tag-processor.php | 22 ++++++++++++------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index b2a597b938495..b4c590ef5141a 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -5431,14 +5431,20 @@ public function has_class( $wanted_class ): ?bool { * * This generator function is designed to be used inside a "foreach" loop. * - * Example: - * - * $p = WP_HTML_Processor::create_fragment( "
" ); - * $p->next_tag(); - * foreach ( $p->class_list() as $class_name ) { - * echo "{$class_name} "; - * } - * // Outputs: "free lang-en " + * ```php interactive + * " ); + * $p->next_tag(); + * foreach ( $p->class_list() as $class_name ) { + * var_dump( $class_name ); + * } + * ``` + * ```expected-output + * string(4) "free" + * string(5) "" + * string(7) "lang-en" + * ``` * * @since 6.6.0 Subclassed for the HTML Processor. */ diff --git a/src/wp-includes/html-api/class-wp-html-tag-processor.php b/src/wp-includes/html-api/class-wp-html-tag-processor.php index 5745207f38fc4..41788ba102a67 100644 --- a/src/wp-includes/html-api/class-wp-html-tag-processor.php +++ b/src/wp-includes/html-api/class-wp-html-tag-processor.php @@ -1178,14 +1178,20 @@ public function paused_at_incomplete_token(): bool { * * This generator function is designed to be used inside a "foreach" loop. * - * Example: - * - * $p = new WP_HTML_Tag_Processor( "
" ); - * $p->next_tag(); - * foreach ( $p->class_list() as $class_name ) { - * echo "{$class_name} "; - * } - * // Outputs: "free lang-en " + * ```php interactive + * " ); + * $p->next_tag(); + * foreach ( $p->class_list() as $class_name ) { + * var_dump( $class_name ); + * } + * ``` + * ```expected-output + * string(4) "free" + * string(5) "" + * string(7) "lang-en" + * ``` * * @since 6.4.0 * From 3bbb42ee9e98e591c04ab6a6236c4ad79db60113 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 13 Aug 2026 18:01:51 +0000 Subject: [PATCH 232/634] Build/Test Tools: Suppress every PHPStan baseline when regenerating. The `strip_baseline_includes()` function in `generate-baselines.php` dropped an `includes` entry only when it resolved inside the output directory. With the default output directory, that test covers the managed region exactly, so nothing appeared amiss. When `--output-dir` was used to point the output elsewhere, however, every baseline already in force stayed active for the analysis, which then reported only the errors those baselines did not already cover: a differential baseline where a complete one was requested. Strip the region between the `# phpstan:baselines` markers whatever it points at, since that region is generated and lists every baseline in force. The output directory test is kept as well, so a baseline listed by hand outside the markers is still suppressed when it is about to be rewritten. Found while generating a baseline from the 7.0.0 source tree to identify which errors have been introduced since: with the managed region left in place, PHPStan refused to start at all, as two of the entries named files which do not exist in 7.0.0. Follow-up to r63019. See #64680, #65817. git-svn-id: https://develop.svn.wordpress.org/trunk@63294 602fd350-edb4-49c9-b593-d223f7449a82 --- tests/phpstan/generate-baselines.php | 46 +++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/tests/phpstan/generate-baselines.php b/tests/phpstan/generate-baselines.php index de0073e83cc54..eef8a02ae5f7e 100644 --- a/tests/phpstan/generate-baselines.php +++ b/tests/phpstan/generate-baselines.php @@ -35,6 +35,19 @@ namespace WordPress\PHPStan; +/** + * Opening marker of the region of the configuration's `includes` this script owns. + * + * Everything between this and the closing marker is generated: it is rewritten to + * match the baselines on disk, and suppressed while the analysis runs. + */ +const BASELINES_START_MARKER = '# phpstan:baselines start'; + +/** + * Closing marker of the region of the configuration's `includes` this script owns. + */ +const BASELINES_END_MARKER = '# phpstan:baselines end'; + if ( 'cli' !== PHP_SAPI ) { fwrite( STDERR, "This script must be run from the command line.\n" ); exit( 1 ); @@ -362,11 +375,22 @@ function read_baseline( string $path ): array { } /** - * Returns the configuration with any `includes` of the baseline directory removed. + * Returns the configuration with the baseline `includes` removed. * * Those files suppress the very errors being regenerated, so they have to be out * of the way for the analysis to report anything. * + * Two kinds of include are dropped. Everything between the `# phpstan:baselines` + * markers goes, whatever it points at, because that region is generated and every + * baseline in force is listed there. Any other include resolving inside the output + * directory goes as well, so that a baseline listed by hand outside the markers is + * still suppressed when it is about to be rewritten. + * + * The distinction matters to `--output-dir`. Were only the output directory + * considered, writing somewhere other than the default would leave the baselines + * already in force active, and the analysis would report just the errors they do + * not cover: a differential baseline rather than a complete one. + * * @param non-falsy-string $config_path Absolute path to the configuration file. * @param non-falsy-string $output_dir Absolute path to the baseline directory. * @return string Configuration contents. @@ -374,6 +398,7 @@ function read_baseline( string $path ): array { function strip_baseline_includes( string $config_path, string $output_dir ): string { $config_dir = dirname( $config_path ); $in_block = false; + $in_managed = false; $kept = array(); foreach ( explode( "\n", read_file( $config_path ) ) as $line ) { @@ -385,10 +410,23 @@ function strip_baseline_includes( string $config_path, string $output_dir ): str // A non-indented, non-blank line ends the block. if ( $in_block && '' !== trim( $line ) && 1 !== preg_match( '/^\s/', $line ) ) { - $in_block = false; + $in_block = false; + $in_managed = false; + } + + if ( $in_block ) { + if ( BASELINES_START_MARKER === trim( $line ) ) { + $in_managed = true; + } elseif ( BASELINES_END_MARKER === trim( $line ) ) { + $in_managed = false; + } } if ( $in_block && 1 === preg_match( '/^\s*-\s*(\S+)\s*$/', $line, $matches ) ) { + if ( $in_managed ) { + continue; + } + $included = $matches[1]; $absolute = ( '/' === $included[0] ) ? $included : $config_dir . '/' . $included; @@ -441,8 +479,8 @@ function find_baselines( string $output_dir ): array { * @param non-empty-string $output_dir Absolute path to the baseline directory. */ function update_config_includes( string $config_path, string $config_option, string $output_dir ): void { - $start_marker = '# phpstan:baselines start'; - $end_marker = '# phpstan:baselines end'; + $start_marker = BASELINES_START_MARKER; + $end_marker = BASELINES_END_MARKER; $before = read_file( $config_path ); $lines = explode( "\n", $before ); From 5a96e2aa643fe20218267026ebfa2ea6cc63e161 Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Thu, 13 Aug 2026 23:46:25 +0000 Subject: [PATCH 233/634] Tests: Clean up the `wp_delete_post()` unit tests. Four independent clean-ups in the test file: - **Remove the unused `$user_ids` fixture.** The property and its `wpSetUpBeforeClass()` method were copied over from the `wp_insert_post()` tests. Nothing in this class references `self::$user_ids`, so the only effect was creating three users for every test in the class. - **Rename `test_wp_delete_post_returns_false_for_invalid_post()`** to `test_wp_delete_post_returns_null_for_already_deleted_post()`. The test asserts `assertNull()`, and that is the correct expectation: for an ID with no matching row, `wp_delete_post()` returns the `null` coming out of `$wpdb->get_row()`, whereas `false` is only returned by the `$post_id <= 0` guard. The old name described the opposite of what the test covers. - **Reuse the `$actions` array** in the assertion loop of `test_wp_delete_post_actions()`. The same six action names were spelled out a second time inline, so the registration loop and the assertion loop could drift apart. - **Fix the `@ticket @63975` annotation.** The stray `@` made the tag invalid, so the test was not associated with the ticket. No assertion was added, removed or changed, and no test behavior changes. Developed in https://github.com/WordPress/wordpress-develop/pull/13036. Follow-up to [60906]. Props Soean. See #65819. git-svn-id: https://develop.svn.wordpress.org/trunk@63295 602fd350-edb4-49c9-b593-d223f7449a82 --- tests/phpunit/tests/post/wpDeletePost.php | 40 +++-------------------- 1 file changed, 4 insertions(+), 36 deletions(-) diff --git a/tests/phpunit/tests/post/wpDeletePost.php b/tests/phpunit/tests/post/wpDeletePost.php index 5382e496b7049..3c2a40fa92bec 100644 --- a/tests/phpunit/tests/post/wpDeletePost.php +++ b/tests/phpunit/tests/post/wpDeletePost.php @@ -16,38 +16,6 @@ */ class Tests_Post_WpDeletePost extends WP_UnitTestCase { - /** - * User IDs for the test. - * - * @var array{administrator: int, editor: int, contributor: int} - */ - protected static $user_ids; - - /** - * Set up before class. - * - * @param WP_UnitTest_Factory $factory The Unit Test Factory. - */ - public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) { - self::$user_ids = array( - 'administrator' => $factory->user->create( - array( - 'role' => 'administrator', - ) - ), - 'editor' => $factory->user->create( - array( - 'role' => 'editor', - ) - ), - 'contributor' => $factory->user->create( - array( - 'role' => 'contributor', - ) - ), - ); - } - /** * Tests wp_delete_post reassign hierarchical post type. */ @@ -120,9 +88,9 @@ public function test_wp_delete_post_short_circuit_on_post_id_zero() { } /** - * Tests wp_delete_post() when the post for the post_id has been already deleted. + * Tests that wp_delete_post() returns null when the post has already been deleted. */ - public function test_wp_delete_post_returns_false_for_invalid_post() { + public function test_wp_delete_post_returns_null_for_already_deleted_post() { $post_id = self::factory()->post->create(); $deleted_post = wp_delete_post( $post_id, true ); $this->assertInstanceOf( WP_Post::class, $deleted_post ); @@ -163,7 +131,7 @@ static function () use ( $action, &$captured_action_args ) { $deleted_post = wp_delete_post( (string) $post_id, true ); $this->assertInstanceOf( WP_Post::class, $deleted_post ); - foreach ( array( 'before_delete_post', 'delete_post_post', 'delete_post', 'deleted_post_post', 'deleted_post', 'after_delete_post' ) as $action ) { + foreach ( $actions as $action ) { $this->assertSame( $initial_action_counts[ $action ] + 1, did_action( $action ), "Expected $action action count to increment by 1." ); $this->assertCount( 2, $captured_action_args[ $action ], "Expected count for $action action" ); $this->assertSame( $post_id, $captured_action_args[ $action ][0], "Expected post ID for $action action" ); @@ -175,7 +143,7 @@ static function () use ( $action, &$captured_action_args ) { /** * Tests short-circuiting wp_delete_post() with pre_delete_post filter. * - * @ticket @63975 + * @ticket 63975 */ public function test_wp_delete_post_can_be_short_circuited() { $post_id = self::factory()->post->create(); From abc50fe6f82b2c64cb7b1555567cc9db73e7eb17 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Fri, 14 Aug 2026 03:25:31 +0000 Subject: [PATCH 234/634] Formatting: Document that escaping functions can take numbers. The `esc_attr()`, `esc_html()`, `esc_js()`, `esc_textarea()`, and `esc_xml()` functions were each annotated `@param string $text`, but none of them has ever required a string at runtime. Both `wp_check_invalid_utf8()` and `_wp_specialchars()` open by casting to string, and that coercion dates to r10298 and r11380, the same year `esc_attr()` and `esc_html()` were introduced in 2.8.0. Only the annotation ever claimed otherwise, which is why passing an integer, overwhelmingly a post ID, a term ID, or a count, has always worked while still registering as a static analysis error. Widen the annotation to `string|int|float` and cast at the top of each function. That cast is not redundant with the ones downstream: it is what makes the `$text` argument handed to the `attribute_escape`, `esc_html`, and `js_escape` filters match its documented `string` type, where callbacks previously received the raw integer or float. For `esc_textarea()` it also affects the output, since that function passed `$text` straight to `htmlspecialchars()`, so `esc_textarea( null )` emitted a deprecation notice on PHP 8.1 and later. The `bool` type is deliberately excluded. Casting `true` yields `'1'` while `false` yields the empty string, and an empty string is indistinguishable from a missing value in any output context. The two call sites in core which pass one stay baselined rather than being permitted by the signature; one of the two is an a11y defect being addressed separately. Regenerating the baselines drops 54 entries covering 101 errors from `tests/phpstan/baselines/argument.type.neon`, where `esc_attr()` was the largest single cluster. Developed in https://github.com/WordPress/wordpress-develop/pull/13044. Follow-up to r11380, r63024. See #65817. git-svn-id: https://develop.svn.wordpress.org/trunk@63296 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/formatting.php | 20 +- tests/phpstan/baselines/argument.type.neon | 274 +-------------------- 2 files changed, 17 insertions(+), 277 deletions(-) diff --git a/src/wp-includes/formatting.php b/src/wp-includes/formatting.php index 74a28109b6536..94f8b3da849cb 100644 --- a/src/wp-includes/formatting.php +++ b/src/wp-includes/formatting.php @@ -4716,11 +4716,13 @@ function htmlentities2( $text ) { * be in single quotes. The {@see 'js_escape'} filter is also applied here. * * @since 2.8.0 + * @since 7.2.0 Non-string scalars are cast to string before escaping. * - * @param string $text The text to be escaped. + * @param string|int|float $text The text to be escaped. * @return string Escaped text. */ function esc_js( $text ) { + $text = (string) $text; $safe_text = wp_check_invalid_utf8( $text ); $safe_text = _wp_specialchars( $safe_text, ENT_COMPAT ); $safe_text = preg_replace( '/&#(x)?0*(?(1)27|39);?/i', "'", stripslashes( $safe_text ) ); @@ -4744,11 +4746,13 @@ function esc_js( $text ) { * Escaping for HTML blocks. * * @since 2.8.0 + * @since 7.2.0 Non-string scalars are cast to string before escaping. * - * @param string $text + * @param string|int|float $text The text to be escaped. * @return string Escaped text. */ function esc_html( $text ) { + $text = (string) $text; $safe_text = wp_check_invalid_utf8( $text ); $safe_text = _wp_specialchars( $safe_text, ENT_QUOTES ); /** @@ -4769,11 +4773,13 @@ function esc_html( $text ) { * Escaping for HTML attributes. * * @since 2.8.0 + * @since 7.2.0 Non-string scalars are cast to string before escaping. * - * @param string $text + * @param string|int|float $text The text to be escaped. * @return string Escaped text. */ function esc_attr( $text ) { + $text = (string) $text; $safe_text = wp_check_invalid_utf8( $text ); $safe_text = _wp_specialchars( $safe_text, ENT_QUOTES ); /** @@ -4794,11 +4800,13 @@ function esc_attr( $text ) { * Escaping for textarea values. * * @since 3.1.0 + * @since 7.2.0 Non-string scalars are cast to string before escaping. * - * @param string $text + * @param string|int|float $text The text to be escaped. * @return string Escaped text. */ function esc_textarea( $text ) { + $text = (string) $text; $safe_text = htmlspecialchars( $text, ENT_QUOTES, get_option( 'blog_charset' ) ); /** * Filters a string cleaned and escaped for output in a textarea element. @@ -4815,11 +4823,13 @@ function esc_textarea( $text ) { * Escaping for XML blocks. * * @since 5.5.0 + * @since 7.2.0 Non-string scalars are cast to string before escaping. * - * @param string $text Text to escape. + * @param string|int|float $text The text to be escaped. * @return string Escaped text. */ function esc_xml( $text ) { + $text = (string) $text; $safe_text = wp_check_invalid_utf8( $text ); $cdata_regex = '\<\!\[CDATA\[.*?\]\]\>'; diff --git a/tests/phpstan/baselines/argument.type.neon b/tests/phpstan/baselines/argument.type.neon index 675559b0e3f9b..da71134bcaf34 100644 --- a/tests/phpstan/baselines/argument.type.neon +++ b/tests/phpstan/baselines/argument.type.neon @@ -44,7 +44,7 @@ parameters: count: 2 path: ../../../src/wp-admin/comment.php - - message: '#^Parameter \#1 \$text of function esc_attr expects string, bool given\.$#' + message: '#^Parameter \#1 \$text of function esc_attr expects float\|int\|string, bool given\.$#' identifier: argument.type count: 1 path: ../../../src/wp-admin/customize.php @@ -53,26 +53,11 @@ parameters: identifier: argument.type count: 1 path: ../../../src/wp-admin/edit-comments.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int given\.$#' - identifier: argument.type - count: 4 - path: ../../../src/wp-admin/edit-comments.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int\\|int\<1, max\> given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-admin/edit-comments.php - message: '#^Parameter \#1 \$screen of function do_meta_boxes expects string\|WP_Screen, null given\.$#' identifier: argument.type count: 2 path: ../../../src/wp-admin/edit-form-advanced.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int\<0, max\> given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-admin/edit-form-advanced.php - message: '#^Parameter \#1 \$post of function get_edit_post_link expects int\|WP_Post, string given\.$#' identifier: argument.type @@ -118,16 +103,6 @@ parameters: identifier: argument.type count: 2 path: ../../../src/wp-admin/includes/ajax-actions.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-admin/includes/ajax-actions.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int\<0, max\> given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-admin/includes/ajax-actions.php - message: '#^Parameter \#2 \$compare_from of function wp_get_revision_ui_diff expects int, string given\.$#' identifier: argument.type @@ -148,31 +123,11 @@ parameters: identifier: argument.type count: 1 path: ../../../src/wp-admin/includes/class-automatic-upgrader-skin.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int given\.$#' - identifier: argument.type - count: 2 - path: ../../../src/wp-admin/includes/class-bulk-upgrader-skin.php - - - message: '#^Parameter \#1 \$text of function esc_js expects string, int given\.$#' - identifier: argument.type - count: 4 - path: ../../../src/wp-admin/includes/class-bulk-upgrader-skin.php - message: '#^Parameter \#1 \$text of function submit_button expects string, null given\.$#' identifier: argument.type count: 1 path: ../../../src/wp-admin/includes/class-custom-background.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, \(float\|int\) given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-admin/includes/class-custom-image-header.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, float\|int given\.$#' - identifier: argument.type - count: 4 - path: ../../../src/wp-admin/includes/class-custom-image-header.php - message: '#^Parameter \#1 \$text of function submit_button expects string, null given\.$#' identifier: argument.type @@ -183,16 +138,6 @@ parameters: identifier: argument.type count: 1 path: ../../../src/wp-admin/includes/class-language-pack-upgrader.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-admin/includes/class-walker-nav-menu-edit.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int\<0, max\> given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-admin/includes/class-walker-nav-menu-edit.php - message: '#^Parameter \#1 \$str of function md5 expects string, int given\.$#' identifier: argument.type @@ -208,56 +153,11 @@ parameters: identifier: argument.type count: 1 path: ../../../src/wp-admin/includes/class-wp-comments-list-table.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-admin/includes/class-wp-ms-users-list-table.php - message: '#^Parameter \#3 \$number of function _nx expects int, float given\.$#' identifier: argument.type count: 1 path: ../../../src/wp-admin/includes/class-wp-plugin-install-list-table.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-admin/includes/class-wp-plugins-list-table.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int given\.$#' - identifier: argument.type - count: 2 - path: ../../../src/wp-admin/includes/class-wp-privacy-data-export-requests-list-table.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int\<0, max\> given\.$#' - identifier: argument.type - count: 2 - path: ../../../src/wp-admin/includes/class-wp-privacy-data-export-requests-list-table.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int given\.$#' - identifier: argument.type - count: 2 - path: ../../../src/wp-admin/includes/class-wp-privacy-data-removal-requests-list-table.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int\<0, max\> given\.$#' - identifier: argument.type - count: 2 - path: ../../../src/wp-admin/includes/class-wp-privacy-data-removal-requests-list-table.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int given\.$#' - identifier: argument.type - count: 2 - path: ../../../src/wp-admin/includes/class-wp-privacy-requests-table.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-admin/includes/class-wp-screen.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int\<1, max\> given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-admin/includes/class-wp-screen.php - message: '#^Parameter \#1 \$version of function get_core_checksums expects string, float given\.$#' identifier: argument.type @@ -328,11 +228,6 @@ parameters: identifier: argument.type count: 1 path: ../../../src/wp-admin/includes/image-edit.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int given\.$#' - identifier: argument.type - count: 2 - path: ../../../src/wp-admin/includes/image-edit.php - message: '#^Parameter \#1 \$width of function wp_imagecreatetruecolor expects int, float given\.$#' identifier: argument.type @@ -378,36 +273,11 @@ parameters: identifier: argument.type count: 1 path: ../../../src/wp-admin/includes/media.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int given\.$#' - identifier: argument.type - count: 2 - path: ../../../src/wp-admin/includes/media.php - message: '#^Parameter \#2 \$result of function wp_parse_str expects array, \(string\|false\) given\.$#' identifier: argument.type count: 1 path: ../../../src/wp-admin/includes/menu.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-admin/includes/meta-boxes.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int given\.$#' - identifier: argument.type - count: 8 - path: ../../../src/wp-admin/includes/misc.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int\<0, max\> given\.$#' - identifier: argument.type - count: 2 - path: ../../../src/wp-admin/includes/misc.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int\<1, max\> given\.$#' - identifier: argument.type - count: 2 - path: ../../../src/wp-admin/includes/misc.php - message: '#^Parameter \#1 \$link_id of function wp_delete_link expects int, string\|null given\.$#' identifier: argument.type @@ -463,11 +333,6 @@ parameters: identifier: argument.type count: 4 path: ../../../src/wp-admin/includes/plugin.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int\<0, max\> given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-admin/includes/post.php - message: '#^Parameter \#2 \$fallback_title of function sanitize_title expects string, int\<0, max\> given\.$#' identifier: argument.type @@ -513,11 +378,6 @@ parameters: identifier: argument.type count: 1 path: ../../../src/wp-admin/includes/update-core.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-admin/includes/update.php - message: '#^Parameter \#1 \$timestamp of function wp_schedule_event expects int, float given\.$#' identifier: argument.type @@ -563,11 +423,6 @@ parameters: identifier: argument.type count: 1 path: ../../../src/wp-admin/install.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int given\.$#' - identifier: argument.type - count: 5 - path: ../../../src/wp-admin/nav-menus.php - message: '#^Parameter \#2 \$menu_data of function wp_save_nav_menu_items expects array\, int given\.$#' identifier: argument.type @@ -578,58 +433,23 @@ parameters: identifier: argument.type count: 1 path: ../../../src/wp-admin/network/site-info.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int\\|int\<1, max\> given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-admin/network/site-info.php - message: '#^Parameter \#1 \$network_id of function can_edit_network expects int, string given\.$#' identifier: argument.type count: 1 path: ../../../src/wp-admin/network/site-settings.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int\\|int\<1, max\> given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-admin/network/site-settings.php - message: '#^Parameter \#1 \$network_id of function can_edit_network expects int, string given\.$#' identifier: argument.type count: 1 path: ../../../src/wp-admin/network/site-themes.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int\\|int\<1, max\> given\.$#' - identifier: argument.type - count: 2 - path: ../../../src/wp-admin/network/site-themes.php - message: '#^Parameter \#1 \$network_id of function can_edit_network expects int, string given\.$#' identifier: argument.type count: 1 path: ../../../src/wp-admin/network/site-users.php - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int\\|int\<1, max\> given\.$#' - identifier: argument.type - count: 4 - path: ../../../src/wp-admin/network/site-users.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int given\.$#' - identifier: argument.type - count: 2 - path: ../../../src/wp-admin/network/sites.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int\<2, max\> given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-admin/options-discussion.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, bool given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-admin/options-general.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int\<0, 6\> given\.$#' + message: '#^Parameter \#1 \$text of function esc_attr expects float\|int\|string, bool given\.$#' identifier: argument.type count: 1 path: ../../../src/wp-admin/options-general.php @@ -648,16 +468,6 @@ parameters: identifier: argument.type count: 1 path: ../../../src/wp-admin/update.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-admin/user-edit.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int given\.$#' - identifier: argument.type - count: 10 - path: ../../../src/wp-admin/users.php - message: '#^Parameter \#1 \$author_id of function get_author_posts_url expects int, string given\.$#' identifier: argument.type @@ -708,16 +518,6 @@ parameters: identifier: argument.type count: 1 path: ../../../src/wp-content/themes/twentyeleven/inc/theme-options.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-content/themes/twentyeleven/inc/widgets.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int\<1, max\> given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-content/themes/twentyeleven/showcase.php - message: '#^Parameter \#2 \$instance of function the_widget expects array, string given\.$#' identifier: argument.type @@ -758,11 +558,6 @@ parameters: identifier: argument.type count: 1 path: ../../../src/wp-content/themes/twentyfourteen/image.php - - - message: '#^Parameter \#1 \$text of function esc_html expects string, int\<1, max\> given\.$#' - identifier: argument.type - count: 2 - path: ../../../src/wp-content/themes/twentyfourteen/image.php - message: '#^Parameter \#1 \$author_id of function get_author_posts_url expects int, string given\.$#' identifier: argument.type @@ -773,11 +568,6 @@ parameters: identifier: argument.type count: 1 path: ../../../src/wp-content/themes/twentyfourteen/inc/widgets.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-content/themes/twentyfourteen/inc/widgets.php - message: '#^Parameter \#3 \$deps of function wp_enqueue_style expects array\, false given\.$#' identifier: argument.type @@ -803,26 +593,11 @@ parameters: identifier: argument.type count: 1 path: ../../../src/wp-content/themes/twentynineteen/template-parts/post/author-bio.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-content/themes/twentyseventeen/inc/color-patterns.php - message: '#^Parameter \#1 \$author_id of function get_author_posts_url expects int, string given\.$#' identifier: argument.type count: 1 path: ../../../src/wp-content/themes/twentyseventeen/inc/template-tags.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, \(float\|int\) given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-content/themes/twentyseventeen/template-parts/page/content-front-page-panels.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, \(float\|int\) given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-content/themes/twentyseventeen/template-parts/page/content-front-page.php - message: '#^Parameter \#1 \$size of function next_image_link expects array\\|string, false given\.$#' identifier: argument.type @@ -948,11 +723,6 @@ parameters: identifier: argument.type count: 1 path: ../../../src/wp-content/themes/twentytwenty/classes/class-twentytwenty-non-latin-languages.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int given\.$#' - identifier: argument.type - count: 2 - path: ../../../src/wp-content/themes/twentytwenty/functions.php - message: '#^Parameter \#3 \$deps of function wp_enqueue_style expects array\, null given\.$#' identifier: argument.type @@ -968,11 +738,6 @@ parameters: identifier: argument.type count: 1 path: ../../../src/wp-content/themes/twentytwenty/template-parts/entry-author-bio.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int\|false given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-content/themes/twentytwentyone/inc/template-functions.php - message: '#^Parameter \#1 \$author_id of function get_author_posts_url expects int, string given\.$#' identifier: argument.type @@ -1043,11 +808,6 @@ parameters: identifier: argument.type count: 1 path: ../../../src/wp-includes/class-wp-comment-query.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int\<0, max\> given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-includes/class-wp-customize-control.php - message: '#^Parameter \#1 \$ajax_message of method WP_Customize_Manager\:\:wp_die\(\) expects string\|WP_Error, int given\.$#' identifier: argument.type @@ -1068,11 +828,6 @@ parameters: identifier: argument.type count: 1 path: ../../../src/wp-includes/class-wp-customize-manager.php - - - message: '#^Parameter \#1 \$text of function esc_html expects string, int given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-includes/class-wp-date-query.php - message: '#^Parameter \#2 \$parent_query of method WP_Date_Query\:\:get_sql_for_clause\(\) expects array, string given\.$#' identifier: argument.type @@ -1383,11 +1138,6 @@ parameters: identifier: argument.type count: 2 path: ../../../src/wp-includes/general-template.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, float given\.$#' - identifier: argument.type - count: 2 - path: ../../../src/wp-includes/general-template.php - message: '#^Parameter \#2 \$replace of function str_replace expects array\\|string, int\<1, max\> given\.$#' identifier: argument.type @@ -1438,16 +1188,6 @@ parameters: identifier: argument.type count: 1 path: ../../../src/wp-includes/load.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int\<1, 9\> given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-includes/media-template.php - - - message: '#^Parameter \#1 \$text of function esc_html expects string, int\<1, 9\> given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-includes/media-template.php - message: '#^Parameter \#5 \$text of function wp_get_attachment_link expects string\|false, bool given\.$#' identifier: argument.type @@ -1853,18 +1593,8 @@ parameters: identifier: argument.type count: 1 path: ../../../src/wp-includes/widgets.php - - - message: '#^Parameter \#1 \$text of function esc_attr expects string, int given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-includes/widgets/class-wp-nav-menu-widget.php - message: '#^Parameter \#1 \$post of function get_the_title expects int\|WP_Post, string given\.$#' identifier: argument.type count: 1 path: ../../../src/wp-includes/widgets/class-wp-widget-recent-comments.php - - - message: '#^Parameter \#1 \$text of function esc_html expects string, int given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-mail.php From c8e049bbf27f11bc67c510370822689cb4071368 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Fri, 14 Aug 2026 07:47:01 +0000 Subject: [PATCH 235/634] Code Modernization: Use `array_key_first()` for an array's first key. `current( array_keys( $array ) )` builds a complete array of every key only to read the first one and discard the rest, whereas `array_key_first()` reads the first bucket directly. The function has been native since PHP 7.3, below the current minimum supported version, and core already uses it in `wp_replace_in_html_tags()`. Behavior is unchanged: the toolbar's `$actions` cannot be empty at that point, and in the privacy tools `absint()` normalizes `null` and `false` alike. Developed in https://github.com/WordPress/wordpress-develop/pull/12785. Follow-up to r18788, r42986. Props mukesh27, soean. Fixes #65773. git-svn-id: https://develop.svn.wordpress.org/trunk@63297 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/includes/privacy-tools.php | 2 +- src/wp-includes/admin-bar.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp-admin/includes/privacy-tools.php b/src/wp-admin/includes/privacy-tools.php index e7b949842ffd1..17e660c8c0d0e 100644 --- a/src/wp-admin/includes/privacy-tools.php +++ b/src/wp-admin/includes/privacy-tools.php @@ -74,7 +74,7 @@ function _wp_personal_data_handle_actions() { if ( isset( $_POST['privacy_action_email_retry'] ) ) { check_admin_referer( 'bulk-privacy_requests' ); - $request_id = absint( current( array_keys( (array) wp_unslash( $_POST['privacy_action_email_retry'] ) ) ) ); + $request_id = absint( array_key_first( (array) wp_unslash( $_POST['privacy_action_email_retry'] ) ) ); $result = _wp_privacy_resend_request( $request_id ); if ( is_wp_error( $result ) ) { diff --git a/src/wp-includes/admin-bar.php b/src/wp-includes/admin-bar.php index 99bb122ec4c36..5ba568792209c 100644 --- a/src/wp-includes/admin-bar.php +++ b/src/wp-includes/admin-bar.php @@ -1080,7 +1080,7 @@ function wp_admin_bar_new_content_menu( $wp_admin_bar ) { array( 'id' => 'new-content', 'title' => $title, - 'href' => admin_url( current( array_keys( $actions ) ) ), + 'href' => admin_url( array_key_first( $actions ) ), 'meta' => array( 'menu_title' => _x( 'New', 'admin bar menu group label' ), ), From 9120bb6a1dcdd38d80066125fd512dd672cbc565 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Zi=C3=B3=C5=82kowski?= Date: Fri, 14 Aug 2026 11:11:11 +0000 Subject: [PATCH 236/634] Return false from WP AI client support checks when the wrapped builder throws `WP_AI_Client_Prompt_Builder::__call()` stored a caught exception as the error state, but only special-cased generating methods before falling through to the fluent return. The eight support check methods therefore handed back the builder instance, which is truthy, so a failed support check read as a success. Return `false` from support check methods in the `catch` block, matching what they already return when the builder is in a pre-existing error state or when the prompt is prevented by a filter. The error is still recorded, so a later generating call still receives the `WP_Error`. Props bejignesh, irozum, gziolo. Fixes #65781. git-svn-id: https://develop.svn.wordpress.org/trunk@63298 602fd350-edb4-49c9-b593-d223f7449a82 --- .../class-wp-ai-client-prompt-builder.php | 11 ++- .../ai-client/wpAiClientPromptBuilder.php | 80 +++++++++++++++++++ 2 files changed, 88 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/ai-client/class-wp-ai-client-prompt-builder.php b/src/wp-includes/ai-client/class-wp-ai-client-prompt-builder.php index a64957fe73157..81297aced2571 100644 --- a/src/wp-includes/ai-client/class-wp-ai-client-prompt-builder.php +++ b/src/wp-includes/ai-client/class-wp-ai-client-prompt-builder.php @@ -43,7 +43,9 @@ * interface. As soon as any exception is caught in a chain of method calls, * the returned instance will be in an error state, and all subsequent method * calls will be no-ops that just return the same error state instance. Only - * when a generating method is called, the WP_Error will be returned. + * when a generating method is called, the WP_Error will be returned. The + * support check methods are the exception to the no-op behavior: they return + * false rather than the error state instance. * * @since 7.0.0 * @@ -79,7 +81,7 @@ * @method self as_output_media_aspect_ratio(string $aspectRatio) Sets the output media aspect ratio. * @method self as_output_speech_voice(string $voice) Sets the output speech voice. * @method self as_json_response(?array $schema = null) Configures the prompt for JSON response output. - * @method bool|WP_Error is_supported(?CapabilityEnum $capability = null) Checks if the prompt is supported for the given capability. + * @method bool is_supported(?CapabilityEnum $capability = null) Checks if the prompt is supported for the given capability. * @method bool is_supported_for_text_generation() Checks if the prompt is supported for text generation. * @method bool is_supported_for_image_generation() Checks if the prompt is supported for image generation. * @method bool is_supported_for_text_to_speech_conversion() Checks if the prompt is supported for text to speech conversion. @@ -282,7 +284,7 @@ public function using_abilities( ...$abilities ): self { * * This allows WordPress developers to use snake_case naming conventions. It catches * any exceptions thrown, stores them, and returns a WP_Error when a terminate method - * is called. + * is called, or false when a support check method is called. * * @since 7.0.0 * @@ -364,6 +366,9 @@ public function __call( string $name, array $arguments ) { if ( self::is_generating_method( $name ) ) { return $this->error; } + if ( self::is_support_check_method( $name ) ) { + return false; + } return $this; } } diff --git a/tests/phpunit/tests/ai-client/wpAiClientPromptBuilder.php b/tests/phpunit/tests/ai-client/wpAiClientPromptBuilder.php index 0669be8cc7bb4..bf96e12a6d4cf 100644 --- a/tests/phpunit/tests/ai-client/wpAiClientPromptBuilder.php +++ b/tests/phpunit/tests/ai-client/wpAiClientPromptBuilder.php @@ -2648,6 +2648,86 @@ public function test_support_check_methods_return_false_in_error_state() { $this->assertFalse( $prompt_builder->is_supported_for_text_generation(), 'is_supported_for_text_generation should return false when in error state' ); } + /** + * Tests that support check methods return false when the wrapped builder throws. + * + * @ticket 65781 + * + * @dataProvider data_support_check_methods + * + * @param string $method The support check method on the wrapper. + * @param string $wrapped_method The matching method on the wrapped builder. + */ + public function test_support_check_methods_return_false_when_builder_throws( $method, $wrapped_method ) { + $registry = AiClient::defaultRegistry(); + $prompt_builder = new WP_AI_Client_Prompt_Builder( $registry, 'Test text' ); + + $wrapped_builder = $this->createMock( PromptBuilder::class ); + $wrapped_builder->method( $wrapped_method ) + ->willThrowException( new RuntimeException( 'Thrown by the wrapped builder.' ) ); + + $builder_property = new ReflectionProperty( WP_AI_Client_Prompt_Builder::class, 'builder' ); + self::set_accessible( $builder_property ); + $builder_property->setValue( $prompt_builder, $wrapped_builder ); + + $result = $prompt_builder->{$method}(); + + $this->assertFalse( $result, $method . ' should return false when the wrapped builder throws' ); + + // The error is still recorded, so a generating method returns it. + $error = $prompt_builder->generate_text(); + $this->assertWPError( $error, 'The caught error should still be returned by generating methods' ); + $this->assertSame( + 'prompt_builder_error', + $error->get_error_code(), + 'The recorded error should be the one thrown by the wrapped builder' + ); + } + + /** + * Data provider. + * + * @return array Support check method names, keyed by the method on the wrapper. + */ + public static function data_support_check_methods(): array { + return array( + 'is_supported' => array( 'is_supported', 'isSupported' ), + 'is_supported_for_text_generation' => array( 'is_supported_for_text_generation', 'isSupportedForTextGeneration' ), + 'is_supported_for_image_generation' => array( 'is_supported_for_image_generation', 'isSupportedForImageGeneration' ), + 'is_supported_for_text_to_speech_conversion' => array( 'is_supported_for_text_to_speech_conversion', 'isSupportedForTextToSpeechConversion' ), + 'is_supported_for_video_generation' => array( 'is_supported_for_video_generation', 'isSupportedForVideoGeneration' ), + 'is_supported_for_speech_generation' => array( 'is_supported_for_speech_generation', 'isSupportedForSpeechGeneration' ), + 'is_supported_for_music_generation' => array( 'is_supported_for_music_generation', 'isSupportedForMusicGeneration' ), + 'is_supported_for_embedding_generation' => array( 'is_supported_for_embedding_generation', 'isSupportedForEmbeddingGeneration' ), + ); + } + + /** + * Tests that a throw from the bundled client during a support check is handled. + * + * This covers the route reported on the ticket. The document modality has no + * capability to infer, so the wrapped builder throws while determining whether + * the prompt is supported. + * + * @ticket 65781 + */ + public function test_is_supported_returns_false_when_the_bundled_builder_throws() { + $registry = AiClient::defaultRegistry(); + $prompt_builder = new WP_AI_Client_Prompt_Builder( $registry, 'Test text' ); + + $result = $prompt_builder->as_output_modalities( ModalityEnum::document() )->is_supported(); + + $this->assertFalse( $result, 'is_supported should return false when the wrapped builder throws' ); + + $error = $prompt_builder->generate_text(); + $this->assertWPError( $error, 'The caught error should still be returned by generating methods' ); + $this->assertSame( + 'prompt_builder_error', + $error->get_error_code(), + 'The document modality should still throw from the wrapped builder. If it no longer does, this test needs another route to a throw' + ); + } + /** * Tests that generating methods return WP_Error when in error state. * From 57b8740a0a9b0f65333ff0b6aaa9c5ff66232f89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Zi=C3=B3=C5=82kowski?= Date: Fri, 14 Aug 2026 11:17:51 +0000 Subject: [PATCH 237/634] Clone the wrapped builder when cloning WP_AI_Client_Prompt_Builder `WP_AI_Client_Prompt_Builder` had no `__clone()`, so cloning it copied the reference to the wrapped `PromptBuilder` instead of the builder itself. That builder mutates its own state, so the clone handed to the `wp_ai_client_prevent_prompt` filter shared its messages and configuration with the original, and a filter could change the prompt that was then sent to the provider, despite the clone being documented as read-only. Add `__clone()` so the wrapped builder, and any stored error, are copied too. The bundled client already implements `PromptBuilder::__clone()` to deep clone messages, model config and request options, it just never ran because only the wrapper was being cloned. Props bejignesh, gziolo. Fixes #65782. git-svn-id: https://develop.svn.wordpress.org/trunk@63299 602fd350-edb4-49c9-b593-d223f7449a82 --- .../class-wp-ai-client-prompt-builder.php | 17 +++++ .../ai-client/wpAiClientPromptBuilder.php | 69 +++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/src/wp-includes/ai-client/class-wp-ai-client-prompt-builder.php b/src/wp-includes/ai-client/class-wp-ai-client-prompt-builder.php index 81297aced2571..e9d529005c676 100644 --- a/src/wp-includes/ai-client/class-wp-ai-client-prompt-builder.php +++ b/src/wp-includes/ai-client/class-wp-ai-client-prompt-builder.php @@ -225,6 +225,23 @@ public function __construct( ProviderRegistry $registry, $prompt = null ) { ); } + /** + * Clones the wrapped prompt builder alongside this instance. + * + * The wrapped builder mutates its own state, so without this a clone would + * share that state with the original and any change made to one would be + * visible in the other. + * + * @since 7.2.0 + */ + public function __clone() { + $this->builder = clone $this->builder; + + if ( null !== $this->error ) { + $this->error = clone $this->error; + } + } + /** * Registers WordPress abilities as function declarations for the AI model. * diff --git a/tests/phpunit/tests/ai-client/wpAiClientPromptBuilder.php b/tests/phpunit/tests/ai-client/wpAiClientPromptBuilder.php index bf96e12a6d4cf..59944327e9d8d 100644 --- a/tests/phpunit/tests/ai-client/wpAiClientPromptBuilder.php +++ b/tests/phpunit/tests/ai-client/wpAiClientPromptBuilder.php @@ -2613,6 +2613,75 @@ static function ( $prevent, $builder ) use ( &$captured_builder ) { $this->assertInstanceOf( WP_AI_Client_Prompt_Builder::class, $captured_builder ); } + /** + * Returns the text of every message part held by a prompt builder. + * + * @param WP_AI_Client_Prompt_Builder $builder The prompt builder to read. + * @return string[] The text of each message part, in order. + */ + private function get_prompt_parts( WP_AI_Client_Prompt_Builder $builder ): array { + $wrapped = new ReflectionProperty( WP_AI_Client_Prompt_Builder::class, 'builder' ); + self::set_accessible( $wrapped ); + $inner = $wrapped->getValue( $builder ); + + $messages = new ReflectionProperty( $inner, 'messages' ); + self::set_accessible( $messages ); + + $parts = array(); + foreach ( $messages->getValue( $inner ) as $message ) { + foreach ( $message->getParts() as $part ) { + $parts[] = (string) $part->getText(); + } + } + + return $parts; + } + + /** + * Tests that a clone does not share the wrapped builder with the original. + * + * @ticket 65782 + */ + public function test_clone_does_not_share_the_wrapped_builder() { + $builder = new WP_AI_Client_Prompt_Builder( AiClient::defaultRegistry(), 'Original prompt' ); + $clone = clone $builder; + + $wrapped = new ReflectionProperty( WP_AI_Client_Prompt_Builder::class, 'builder' ); + self::set_accessible( $wrapped ); + + $this->assertNotSame( + $wrapped->getValue( $builder ), + $wrapped->getValue( $clone ), + 'A clone should wrap its own builder instance' + ); + + $clone->with_text( 'Added to the clone' ); + + $this->assertSame( array( 'Original prompt' ), $this->get_prompt_parts( $builder ), 'Changing the clone should not change the original' ); + } + + /** + * Tests that the clone passed to the prevent prompt filter cannot change the prompt. + * + * @ticket 65782 + */ + public function test_prevent_prompt_filter_cannot_mutate_the_original_prompt() { + add_filter( + 'wp_ai_client_prevent_prompt', + static function ( $prevent, $builder ) { + $builder->with_text( 'Added by the filter' ); + return $prevent; + }, + 10, + 2 + ); + + $builder = new WP_AI_Client_Prompt_Builder( AiClient::defaultRegistry(), 'Original prompt' ); + $builder->is_supported(); + + $this->assertSame( array( 'Original prompt' ), $this->get_prompt_parts( $builder ), 'A filter should not be able to change the prompt' ); + } + /** * Tests that once in error state, subsequent fluent calls return the same instance. * From 36af6b1177535fbbbdbb7cf8be5aa3949c606822 Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Fri, 14 Aug 2026 15:34:26 +0000 Subject: [PATCH 238/634] Coding Standards: Add missing semicolon for error message output in PHPUnit bootstrap. Developed in https://github.com/WordPress/wordpress-develop/pull/13048. Follow-up to r49535, r51581. Props mukesh27. See #65818. git-svn-id: https://develop.svn.wordpress.org/trunk@63300 602fd350-edb4-49c9-b593-d223f7449a82 --- tests/phpunit/includes/bootstrap.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/includes/bootstrap.php b/tests/phpunit/includes/bootstrap.php index e308dcb5a6e1c..b3835a1ce415b 100644 --- a/tests/phpunit/includes/bootstrap.php +++ b/tests/phpunit/includes/bootstrap.php @@ -181,7 +181,7 @@ 'Error: The following required PHP extensions are missing from the testing environment: %s.' . PHP_EOL, implode( ', ', $missing_extensions ) ); - echo 'Please make sure they are installed and enabled.' . PHP_EOL, + echo 'Please make sure they are installed and enabled.' . PHP_EOL; exit( 1 ); } } @@ -205,7 +205,7 @@ 'Error: The following required constants are not defined: %s.' . PHP_EOL, implode( ', ', $missing_constants ) ); - echo 'Please check out `wp-tests-config-sample.php` for an example.' . PHP_EOL, + echo 'Please check out `wp-tests-config-sample.php` for an example.' . PHP_EOL; exit( 1 ); } From 3ecb39249d104a919981498772bd83c5a09dcecf Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Fri, 14 Aug 2026 18:22:35 +0000 Subject: [PATCH 239/634] Code Quality: Annotate HTML API's `parse_next_tag()` as "impure" for PHPStan. PHPStan infers the `WP_HTML_Tag_Processor::parse_next_tag()` method as pure, so the `STATE_READY` value narrowed onto `$parser_state` before the call survives across it, even though the method reassigns that property throughout its body. Every state comparison that follows in the `base_class_next_token()` method is then decided at analysis time rather than at runtime: both `&&` operands resolve to `true`, the early `return true` is treated as unconditional, and the remainder of the method is analyzed as unreachable. This in turn leaves `skip_rawtext()` and `skip_script_data()` reported as uncalled and `$skip_newline_at` as never assigned an `int`. Adding `@phpstan-impure`, the annotation PHPStan's own tip recommends, resolves ten baselined errors across six identifiers; `next_tag()` in the same class already carries it. This empties the `booleanAnd.alwaysTrue` and `property.unusedType` baselines, so both files are removed along with their `includes` entries in `phpstan.neon.dist`. Developed in https://github.com/WordPress/wordpress-develop/pull/13057. Follow-up to r61934, r63023. Props tstokes8040. See #65817. git-svn-id: https://develop.svn.wordpress.org/trunk@63301 602fd350-edb4-49c9-b593-d223f7449a82 --- phpstan.neon.dist | 2 -- .../html-api/class-wp-html-tag-processor.php | 2 ++ .../baselines/booleanAnd.alwaysTrue.neon | 25 ------------------- .../baselines/deadCode.unreachable.neon | 5 ---- .../baselines/identical.alwaysFalse.neon | 5 ---- tests/phpstan/baselines/method.unused.neon | 10 -------- .../baselines/notIdentical.alwaysTrue.neon | 15 ----------- .../baselines/property.unusedType.neon | 25 ------------------- 8 files changed, 2 insertions(+), 87 deletions(-) delete mode 100644 tests/phpstan/baselines/booleanAnd.alwaysTrue.neon delete mode 100644 tests/phpstan/baselines/property.unusedType.neon diff --git a/phpstan.neon.dist b/phpstan.neon.dist index fa1e3f209c322..e2e72fb367482 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -29,7 +29,6 @@ includes: - tests/phpstan/baselines/assign.propertyType.neon - tests/phpstan/baselines/binaryOp.invalid.neon - tests/phpstan/baselines/booleanAnd.alwaysFalse.neon - - tests/phpstan/baselines/booleanAnd.alwaysTrue.neon - tests/phpstan/baselines/booleanAnd.leftAlwaysTrue.neon - tests/phpstan/baselines/booleanAnd.rightAlwaysTrue.neon - tests/phpstan/baselines/booleanNot.alwaysFalse.neon @@ -80,7 +79,6 @@ includes: - tests/phpstan/baselines/property.phpDocType.neon - tests/phpstan/baselines/property.private.neon - tests/phpstan/baselines/property.protected.neon - - tests/phpstan/baselines/property.unusedType.neon - tests/phpstan/baselines/return.empty.neon - tests/phpstan/baselines/return.missing.neon - tests/phpstan/baselines/return.type.neon diff --git a/src/wp-includes/html-api/class-wp-html-tag-processor.php b/src/wp-includes/html-api/class-wp-html-tag-processor.php index 41788ba102a67..dd99a8324b5c6 100644 --- a/src/wp-includes/html-api/class-wp-html-tag-processor.php +++ b/src/wp-includes/html-api/class-wp-html-tag-processor.php @@ -1728,6 +1728,8 @@ private function skip_script_data(): bool { * @ignore * * @return bool Whether a tag was found before the end of the document. + * + * @phpstan-impure */ private function parse_next_tag(): bool { $this->after_tag(); diff --git a/tests/phpstan/baselines/booleanAnd.alwaysTrue.neon b/tests/phpstan/baselines/booleanAnd.alwaysTrue.neon deleted file mode 100644 index 52bae4992b186..0000000000000 --- a/tests/phpstan/baselines/booleanAnd.alwaysTrue.neon +++ /dev/null @@ -1,25 +0,0 @@ -# PHPStan baseline for the `booleanAnd.alwaysTrue` errors in WordPress core. -# -# https://phpstan.org/error-identifiers/booleanAnd.alwaysTrue -# -# Each entry is scoped to a single file and carries an exact occurrence count, -# so that a new instance is reported as a new error rather than being absorbed -# silently. Fixing an occurrence therefore means decrementing or removing its -# entry here as part of the same change. -# -# The goal is to empty this file and delete it, along with the `includes` entry -# for it in phpstan.neon.dist. -# -# Generated by `composer phpstan:baselines`. Do not edit by hand; regenerate with -# -# composer phpstan:baselines -- --identifier=booleanAnd.alwaysTrue -# -# which reruns the analysis with this file suppressed so the errors surface again. - -parameters: - ignoreErrors: - - - message: '#^Result of && is always true\.$#' - identifier: booleanAnd.alwaysTrue - count: 2 - path: ../../../src/wp-includes/html-api/class-wp-html-tag-processor.php diff --git a/tests/phpstan/baselines/deadCode.unreachable.neon b/tests/phpstan/baselines/deadCode.unreachable.neon index f8a2c6671a783..0bd31fe524a9a 100644 --- a/tests/phpstan/baselines/deadCode.unreachable.neon +++ b/tests/phpstan/baselines/deadCode.unreachable.neon @@ -288,11 +288,6 @@ parameters: identifier: deadCode.unreachable count: 31 path: ../../../src/wp-includes/html-api/class-wp-html-processor.php - - - message: '#^Unreachable statement \- code above always terminates\.$#' - identifier: deadCode.unreachable - count: 1 - path: ../../../src/wp-includes/html-api/class-wp-html-tag-processor.php - message: '#^Unreachable statement \- code above always terminates\.$#' identifier: deadCode.unreachable diff --git a/tests/phpstan/baselines/identical.alwaysFalse.neon b/tests/phpstan/baselines/identical.alwaysFalse.neon index 47e10c0e67b9a..53a42542a0410 100644 --- a/tests/phpstan/baselines/identical.alwaysFalse.neon +++ b/tests/phpstan/baselines/identical.alwaysFalse.neon @@ -28,11 +28,6 @@ parameters: identifier: identical.alwaysFalse count: 1 path: ../../../src/wp-includes/html-api/class-wp-html-processor.php - - - message: '#^Strict comparison using \=\=\= between ''STATE_INCOMPLETE…'' and ''STATE_READY'' will always evaluate to false\.$#' - identifier: identical.alwaysFalse - count: 1 - path: ../../../src/wp-includes/html-api/class-wp-html-tag-processor.php - message: '#^Strict comparison using \=\=\= between 3000000000 and 2147483647 will always evaluate to false\.$#' identifier: identical.alwaysFalse diff --git a/tests/phpstan/baselines/method.unused.neon b/tests/phpstan/baselines/method.unused.neon index f4314a8b42a5c..bf95fbb71715c 100644 --- a/tests/phpstan/baselines/method.unused.neon +++ b/tests/phpstan/baselines/method.unused.neon @@ -33,13 +33,3 @@ parameters: identifier: method.unused count: 1 path: ../../../src/wp-includes/class-wp-script-modules.php - - - message: '#^Method WP_HTML_Tag_Processor\:\:skip_rawtext\(\) is unused\.$#' - identifier: method.unused - count: 1 - path: ../../../src/wp-includes/html-api/class-wp-html-tag-processor.php - - - message: '#^Method WP_HTML_Tag_Processor\:\:skip_script_data\(\) is unused\.$#' - identifier: method.unused - count: 1 - path: ../../../src/wp-includes/html-api/class-wp-html-tag-processor.php diff --git a/tests/phpstan/baselines/notIdentical.alwaysTrue.neon b/tests/phpstan/baselines/notIdentical.alwaysTrue.neon index 631833a87c3ee..99fe5295c9d55 100644 --- a/tests/phpstan/baselines/notIdentical.alwaysTrue.neon +++ b/tests/phpstan/baselines/notIdentical.alwaysTrue.neon @@ -38,21 +38,6 @@ parameters: identifier: notIdentical.alwaysTrue count: 1 path: ../../../src/wp-includes/functions.php - - - message: '#^Strict comparison using \!\=\= between ''STATE_COMPLETE'' and ''STATE_READY'' will always evaluate to true\.$#' - identifier: notIdentical.alwaysTrue - count: 1 - path: ../../../src/wp-includes/html-api/class-wp-html-tag-processor.php - - - message: '#^Strict comparison using \!\=\= between ''STATE_INCOMPLETE…'' and ''STATE_READY'' will always evaluate to true\.$#' - identifier: notIdentical.alwaysTrue - count: 1 - path: ../../../src/wp-includes/html-api/class-wp-html-tag-processor.php - - - message: '#^Strict comparison using \!\=\= between ''STATE_MATCHED_TAG'' and ''STATE_READY'' will always evaluate to true\.$#' - identifier: notIdentical.alwaysTrue - count: 1 - path: ../../../src/wp-includes/html-api/class-wp-html-tag-processor.php - message: '#^Strict comparison using \!\=\= between 0 and int\\|int\<1, max\> will always evaluate to true\.$#' identifier: notIdentical.alwaysTrue diff --git a/tests/phpstan/baselines/property.unusedType.neon b/tests/phpstan/baselines/property.unusedType.neon deleted file mode 100644 index 9f1bd06e86c8f..0000000000000 --- a/tests/phpstan/baselines/property.unusedType.neon +++ /dev/null @@ -1,25 +0,0 @@ -# PHPStan baseline for the `property.unusedType` errors in WordPress core. -# -# https://phpstan.org/error-identifiers/property.unusedType -# -# Each entry is scoped to a single file and carries an exact occurrence count, -# so that a new instance is reported as a new error rather than being absorbed -# silently. Fixing an occurrence therefore means decrementing or removing its -# entry here as part of the same change. -# -# The goal is to empty this file and delete it, along with the `includes` entry -# for it in phpstan.neon.dist. -# -# Generated by `composer phpstan:baselines`. Do not edit by hand; regenerate with -# -# composer phpstan:baselines -- --identifier=property.unusedType -# -# which reruns the analysis with this file suppressed so the errors surface again. - -parameters: - ignoreErrors: - - - message: '#^Property WP_HTML_Tag_Processor\:\:\$skip_newline_at \(int\|null\) is never assigned int so it can be removed from the property type\.$#' - identifier: property.unusedType - count: 1 - path: ../../../src/wp-includes/html-api/class-wp-html-tag-processor.php From 21eb291bc1b48a5c9c6053a146f8ba4fe5ca1316 Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Sat, 15 Aug 2026 23:40:37 +0000 Subject: [PATCH 240/634] Tests: Use the modern PHPUnit stubbing and matcher shorthands. Two test cases still used the legacy PHPUnit stub API. This replaces them with the modern shorthands, which are what the rest of the suite already uses. `tests/phpunit/tests/pomo/pluralForms.php` {{{ // Before ->will( $this->returnValue( 1 ) ); // After ->willReturn( 1 ); }}} `tests/phpunit/tests/rest-api/rest-server.php` {{{ // Before ->with( $this->equalTo( 400 ) ); // After ->with( 400 ); }}} **Why this is safe** `willReturn()` is a direct shorthand for `will( $this->returnValue() )` and has been available since PHPUnit 5.4. The test suite enforces a minimum of PHPUnit 5.7.21 in `tests/phpunit/includes/bootstrap.php`, so it is safe on every supported version, and the suite already contains 83 `willReturn()` calls. `with()` wraps any non-`Constraint` argument in an `equalTo()` constraint itself, so passing `400` directly is identical in behaviour. The suite already has 43 `with()` calls that pass values directly. Note on the first change: that line was originally written as `willReturn( 1 )` and switched to the long form in r41725 because of the PHPUnit versions supported back then. That constraint no longer applies, so this effectively reverts an obsolete workaround. Developed in https://github.com/WordPress/wordpress-develop/pull/13052. Follow-up to r34928, r41725. Props Soean. See #65819. git-svn-id: https://develop.svn.wordpress.org/trunk@63303 602fd350-edb4-49c9-b593-d223f7449a82 --- tests/phpunit/tests/pomo/pluralForms.php | 2 +- tests/phpunit/tests/rest-api/rest-server.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/tests/pomo/pluralForms.php b/tests/phpunit/tests/pomo/pluralForms.php index 0329374e94df8..8813336e37069 100644 --- a/tests/phpunit/tests/pomo/pluralForms.php +++ b/tests/phpunit/tests/pomo/pluralForms.php @@ -233,7 +233,7 @@ public function test_cache() { $mock->expects( $this->once() ) ->method( 'execute' ) ->with( $this->identicalTo( 2 ) ) - ->will( $this->returnValue( 1 ) ); + ->willReturn( 1 ); $first = $mock->get( 2 ); $second = $mock->get( 2 ); diff --git a/tests/phpunit/tests/rest-api/rest-server.php b/tests/phpunit/tests/rest-api/rest-server.php index b8e8cc6f5adcb..dce5a045f73db 100644 --- a/tests/phpunit/tests/rest-api/rest-server.php +++ b/tests/phpunit/tests/rest-api/rest-server.php @@ -652,7 +652,7 @@ public function test_json_error_with_status() { $stub->expects( $this->once() ) ->method( 'set_status' ) - ->with( $this->equalTo( 400 ) ); + ->with( 400 ); $data = array( 'code' => 'wp-api-test-error', From 6c0f205fd6bff5fe4b3eca0f2bfe69b1ec5b6a94 Mon Sep 17 00:00:00 2001 From: Aki Hamano Date: Sun, 16 Aug 2026 01:19:41 +0000 Subject: [PATCH 241/634] Help/About: Optimize the About page images. The header backgrounds now ship with WordPress as SVG files instead of being fetched from the CDN, the feature images have been recompressed, and those below the fold are lazy loaded. Follow-up to [63182]. Props iamchitti, joedolson, markoserb, mukesh27, peterwilsoncc, wildworks. Fixes #65854. git-svn-id: https://develop.svn.wordpress.org/trunk@63304 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/about.php | 8 ++++---- src/wp-admin/css/about.css | 20 +++++++++---------- .../images/about-header-credits-rtl.svg | 1 + src/wp-admin/images/about-header-credits.svg | 1 + .../images/about-header-default-rtl.svg | 1 + src/wp-admin/images/about-header-default.svg | 1 + .../images/about-header-freedoms-rtl.svg | 1 + src/wp-admin/images/about-header-freedoms.svg | 1 + .../images/about-header-get-involved-rtl.svg | 1 + .../images/about-header-get-involved.svg | 1 + .../images/about-header-privacy-rtl.svg | 1 + src/wp-admin/images/about-header-privacy.svg | 1 + src/wp-admin/images/about-release-badge.svg | 19 +----------------- src/wp-admin/includes/update-core.php | 11 +++++++--- 14 files changed, 33 insertions(+), 35 deletions(-) create mode 100644 src/wp-admin/images/about-header-credits-rtl.svg create mode 100644 src/wp-admin/images/about-header-credits.svg create mode 100644 src/wp-admin/images/about-header-default-rtl.svg create mode 100644 src/wp-admin/images/about-header-default.svg create mode 100644 src/wp-admin/images/about-header-freedoms-rtl.svg create mode 100644 src/wp-admin/images/about-header-freedoms.svg create mode 100644 src/wp-admin/images/about-header-get-involved-rtl.svg create mode 100644 src/wp-admin/images/about-header-get-involved.svg create mode 100644 src/wp-admin/images/about-header-privacy-rtl.svg create mode 100644 src/wp-admin/images/about-header-privacy.svg diff --git a/src/wp-admin/about.php b/src/wp-admin/about.php index 4a421ac00cfba..9091ca6ec958c 100644 --- a/src/wp-admin/about.php +++ b/src/wp-admin/about.php @@ -75,7 +75,7 @@
- +
@@ -83,7 +83,7 @@
- +
@@ -105,7 +105,7 @@
- +
@@ -113,7 +113,7 @@
- +
diff --git a/src/wp-admin/css/about.css b/src/wp-admin/css/about.css index bb17f4f8d2006..9d6d8adff4a34 100644 --- a/src/wp-admin/css/about.css +++ b/src/wp-admin/css/about.css @@ -603,7 +603,7 @@ padding-right: 26rem; /* Space for the background image. */ min-height: clamp(10rem, 25vw, 18.75rem); border-radius: var(--border-radius); - background-image: url(https://s.w.org/images/core/7.1/about-header-default.webp?ver=20260804); + background-image: url(../images/about-header-default.svg?ver=7.1); background-repeat: no-repeat; background-position: right center; background-size: cover; @@ -613,39 +613,39 @@ } .credits-php .about__header { - background-image: url(https://s.w.org/images/core/7.1/about-header-credits.webp?ver=20260804); + background-image: url(../images/about-header-credits.svg?ver=7.1); } .freedoms-php .about__header { - background-image: url(https://s.w.org/images/core/7.1/about-header-freedoms.webp?ver=20260804); + background-image: url(../images/about-header-freedoms.svg?ver=7.1); } .privacy-php .about__header { - background-image: url(https://s.w.org/images/core/7.1/about-header-privacy.webp?ver=20260804); + background-image: url(../images/about-header-privacy.svg?ver=7.1); } .contribute-php .about__header { - background-image: url(https://s.w.org/images/core/7.1/about-header-get-involved.webp?ver=20260804); + background-image: url(../images/about-header-get-involved.svg?ver=7.1); } [dir="rtl"] .about__header { - background-image: url(https://s.w.org/images/core/7.1/about-header-default-rtl.webp?ver=20260804); + background-image: url(../images/about-header-default-rtl.svg?ver=7.1); } [dir="rtl"] .credits-php .about__header { - background-image: url(https://s.w.org/images/core/7.1/about-header-credits-rtl.webp?ver=20260804); + background-image: url(../images/about-header-credits-rtl.svg?ver=7.1); } [dir="rtl"] .freedoms-php .about__header { - background-image: url(https://s.w.org/images/core/7.1/about-header-freedoms-rtl.webp?ver=20260804); + background-image: url(../images/about-header-freedoms-rtl.svg?ver=7.1); } [dir="rtl"] .privacy-php .about__header { - background-image: url(https://s.w.org/images/core/7.1/about-header-privacy-rtl.webp?ver=20260804); + background-image: url(../images/about-header-privacy-rtl.svg?ver=7.1); } [dir="rtl"] .contribute-php .about__header { - background-image: url(https://s.w.org/images/core/7.1/about-header-get-involved-rtl.webp?ver=20260804); + background-image: url(../images/about-header-get-involved-rtl.svg?ver=7.1); } .about__header-image { diff --git a/src/wp-admin/images/about-header-credits-rtl.svg b/src/wp-admin/images/about-header-credits-rtl.svg new file mode 100644 index 0000000000000..001e47d6949f8 --- /dev/null +++ b/src/wp-admin/images/about-header-credits-rtl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/wp-admin/images/about-header-credits.svg b/src/wp-admin/images/about-header-credits.svg new file mode 100644 index 0000000000000..ac6dfef6883ea --- /dev/null +++ b/src/wp-admin/images/about-header-credits.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/wp-admin/images/about-header-default-rtl.svg b/src/wp-admin/images/about-header-default-rtl.svg new file mode 100644 index 0000000000000..d8574fc4c3b75 --- /dev/null +++ b/src/wp-admin/images/about-header-default-rtl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/wp-admin/images/about-header-default.svg b/src/wp-admin/images/about-header-default.svg new file mode 100644 index 0000000000000..ca71da7d8a2be --- /dev/null +++ b/src/wp-admin/images/about-header-default.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/wp-admin/images/about-header-freedoms-rtl.svg b/src/wp-admin/images/about-header-freedoms-rtl.svg new file mode 100644 index 0000000000000..5eb445f4b8a4a --- /dev/null +++ b/src/wp-admin/images/about-header-freedoms-rtl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/wp-admin/images/about-header-freedoms.svg b/src/wp-admin/images/about-header-freedoms.svg new file mode 100644 index 0000000000000..e996bcc373802 --- /dev/null +++ b/src/wp-admin/images/about-header-freedoms.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/wp-admin/images/about-header-get-involved-rtl.svg b/src/wp-admin/images/about-header-get-involved-rtl.svg new file mode 100644 index 0000000000000..3db4448e465af --- /dev/null +++ b/src/wp-admin/images/about-header-get-involved-rtl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/wp-admin/images/about-header-get-involved.svg b/src/wp-admin/images/about-header-get-involved.svg new file mode 100644 index 0000000000000..17b2717ddf63b --- /dev/null +++ b/src/wp-admin/images/about-header-get-involved.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/wp-admin/images/about-header-privacy-rtl.svg b/src/wp-admin/images/about-header-privacy-rtl.svg new file mode 100644 index 0000000000000..e2b3084e14b55 --- /dev/null +++ b/src/wp-admin/images/about-header-privacy-rtl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/wp-admin/images/about-header-privacy.svg b/src/wp-admin/images/about-header-privacy.svg new file mode 100644 index 0000000000000..ed37fb636362b --- /dev/null +++ b/src/wp-admin/images/about-header-privacy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/wp-admin/images/about-release-badge.svg b/src/wp-admin/images/about-release-badge.svg index 8380db37771cf..845f4817a441f 100644 --- a/src/wp-admin/images/about-release-badge.svg +++ b/src/wp-admin/images/about-release-badge.svg @@ -1,18 +1 @@ - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/src/wp-admin/includes/update-core.php b/src/wp-admin/includes/update-core.php index 01dba5e25a22f..e34716f0c8b24 100644 --- a/src/wp-admin/includes/update-core.php +++ b/src/wp-admin/includes/update-core.php @@ -767,12 +767,17 @@ 'wp-includes/blocks/query/style.min.css', 'wp-includes/blocks/query/style-rtl.css', 'wp-includes/blocks/query/style.css', - 'wp-admin/images/about-header-privacy.svg', 'wp-admin/images/about-header-about.svg', - 'wp-admin/images/about-header-credits.svg', - 'wp-admin/images/about-header-freedoms.svg', 'wp-admin/images/about-header-contribute.svg', 'wp-admin/images/about-header-background.svg', + /* + * Restored in WordPress 7.1 + * + * 'wp-admin/images/about-header-privacy.svg', + * 'wp-admin/images/about-header-credits.svg', + * 'wp-admin/images/about-header-freedoms.svg', + */ + // 6.6 'wp-includes/blocks/block/editor.css', 'wp-includes/blocks/block/editor.min.css', From 2b0b3b8bc6c68a62f1eb2cfb9b296c5dcd7a9799 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Sun, 16 Aug 2026 16:10:24 +0000 Subject: [PATCH 242/634] Toolbar: Revert focus and hover style changes. Reverts the focus and hover style changes in the admin toolbar. Reverts [63190], [63009], and [63188], restoring the appearance in WordPress 7.0. Props fushar, wildworks, ravichudasama01, afercia, joen, keoshi, cbusquets1989, annezazu. Fixes #65849. See #65445. git-svn-id: https://develop.svn.wordpress.org/trunk@63306 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/css/admin-menu.css | 17 +++++++--- src/wp-admin/css/colors/_admin.scss | 32 +++++++++--------- src/wp-includes/css/admin-bar.css | 50 ++++++++++++++--------------- 3 files changed, 51 insertions(+), 48 deletions(-) diff --git a/src/wp-admin/css/admin-menu.css b/src/wp-admin/css/admin-menu.css index aa6a8bc1414aa..3747613282be1 100644 --- a/src/wp-admin/css/admin-menu.css +++ b/src/wp-admin/css/admin-menu.css @@ -800,10 +800,12 @@ li#wp-admin-bar-menu-toggle { display: block; padding: 0; overflow: hidden; + outline: none; text-decoration: none; + border: 1px solid transparent; background: none; - height: 46px; - box-sizing: border-box; + height: 44px; + margin-left: -1px; } .wp-responsive-open #wpadminbar #wp-admin-bar-menu-toggle a { @@ -814,17 +816,22 @@ li#wp-admin-bar-menu-toggle { display: block; } + #wpadminbar #wp-admin-bar-menu-toggle a:hover { + border: 1px solid transparent; + } + #wpadminbar #wp-admin-bar-menu-toggle .ab-icon:before { content: "\f228"; display: inline-block; float: left; - font: normal 40px/46px dashicons; + font: normal 40px/45px dashicons; vertical-align: middle; + outline: none; margin: 0; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; - height: 46px; - width: 52px; + height: 44px; + width: 50px; padding: 0; border: none; text-align: center; diff --git a/src/wp-admin/css/colors/_admin.scss b/src/wp-admin/css/colors/_admin.scss index 91d6a4b66bc8c..366f1b86b4f16 100644 --- a/src/wp-admin/css/colors/_admin.scss +++ b/src/wp-admin/css/colors/_admin.scss @@ -416,11 +416,9 @@ ul#adminmenu > li.current > a.current:after { background: variables.$menu-submenu-background; } -#wpadminbar > #wp-toolbar li:hover span.ab-label, -#wpadminbar > #wp-toolbar li.hover span.ab-label, -/* The adminbar menu may output either links or focusable div elements. */ -/* As such, we target the focus state without specifying the element type. */ -#wpadminbar > #wp-toolbar :focus span.ab-label { +#wpadminbar:not(.mobile) > #wp-toolbar li:hover span.ab-label, +#wpadminbar:not(.mobile) > #wp-toolbar li.hover span.ab-label, +#wpadminbar:not(.mobile) > #wp-toolbar a:focus span.ab-label { color: variables.$menu-submenu-focus-text; } @@ -451,9 +449,7 @@ ul#adminmenu > li.current > a.current:after { } #wpadminbar .quicklinks li .blavatar, -#wpadminbar .menupop .menupop > .ab-item:before, -#wpadminbar.mobile .quicklinks .ab-icon:before, -#wpadminbar.mobile .quicklinks .ab-item:before { +#wpadminbar .menupop .menupop > .ab-item:before { color: variables.$menu-icon; } @@ -478,17 +474,21 @@ ul#adminmenu > li.current > a.current:after { color: variables.$menu-submenu-focus-text; } -// Note that the icon of the site-name item is not wrapped within a span with class ab-icon like other items. #wpadminbar .quicklinks li a:hover .blavatar, #wpadminbar .quicklinks li a:focus .blavatar, #wpadminbar .quicklinks .ab-sub-wrapper .menupop.hover > a .blavatar, #wpadminbar .menupop .menupop > .ab-item:hover:before, #wpadminbar.mobile .quicklinks .hover .ab-icon:before, -#wpadminbar.mobile .quicklinks .hover .ab-item:before, -#wpadminbar.mobile .quicklinks .ab-item:focus:before { +#wpadminbar.mobile .quicklinks .hover .ab-item:before { color: variables.$menu-submenu-focus-text; } +#wpadminbar.mobile .quicklinks .ab-icon:before, +#wpadminbar.mobile .quicklinks .ab-item:before { + color: variables.$menu-icon; +} + + /* Admin Bar: search */ #wpadminbar #adminbarsearch:before { @@ -531,16 +531,14 @@ ul#adminmenu > li.current > a.current:after { color: variables.$menu-text; } +#wpadminbar #wp-admin-bar-user-info a:hover .display-name { + color: variables.$menu-submenu-focus-text; +} + #wpadminbar #wp-admin-bar-user-info .username { color: variables.$menu-submenu-text; } -#wpadminbar #wp-admin-bar-user-info a:hover .display-name, -#wpadminbar #wp-admin-bar-user-info a:focus .display-name, -#wpadminbar #wp-admin-bar-user-info a:hover .username, -#wpadminbar #wp-admin-bar-user-info a:focus .username { - color: variables.$menu-submenu-focus-text; -} /* Pointers */ diff --git a/src/wp-includes/css/admin-bar.css b/src/wp-includes/css/admin-bar.css index e0411701a28e8..77e196525657a 100644 --- a/src/wp-includes/css/admin-bar.css +++ b/src/wp-includes/css/admin-bar.css @@ -77,28 +77,12 @@ html:lang(he-il) .rtl #wpadminbar * { box-shadow: none; } -#wpadminbar a:focus, -#wpadminbar .ab-item[tabindex="0"]:focus { - outline-offset: -2px; +#wpadminbar a:focus { + outline-offset: -1px; /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; } -#wpadminbar a:hover, -#wpadminbar a:focus, -#wpadminbar .ab-item[tabindex="0"]:hover, -#wpadminbar .ab-item[tabindex="0"]:focus { - box-shadow: inset 0 -4px 0 0 currentColor; - transition: box-shadow 0.1s linear; -} - -#wpadminbar .ab-submenu a:hover, -#wpadminbar .ab-submenu a:focus, -#wpadminbar .ab-submenu .ab-item[tabindex="0"]:hover, -#wpadminbar .ab-submenu .ab-item[tabindex="0"]:focus { - box-shadow: inset 4px 0 0 0 currentColor; -} - #wpadminbar { direction: ltr; color: #c3c4c7; @@ -239,11 +223,9 @@ html:lang(he-il) .rtl #wpadminbar * { color: #72aee6; } -#wpadminbar > #wp-toolbar li:hover span.ab-label, +#wpadminbar:not(.mobile) > #wp-toolbar li:hover span.ab-label, #wpadminbar > #wp-toolbar li.hover span.ab-label, -/* The adminbar menu may output either links or focusable div elements. */ -/* As such, we target the focus state without specifying the element type. */ -#wpadminbar > #wp-toolbar :focus span.ab-label { +#wpadminbar:not(.mobile) > #wp-toolbar a:focus span.ab-label { color: #72aee6; } @@ -312,8 +294,7 @@ html:lang(he-il) .rtl #wpadminbar * { #wpadminbar li.hover .ab-icon:before, #wpadminbar li.hover .ab-item:before, #wpadminbar li:hover #adminbarsearch:before, -#wpadminbar li #adminbarsearch.adminbar-focused:before, -#wpadminbar.mobile .quicklinks .ab-item:focus:before { +#wpadminbar li #adminbarsearch.adminbar-focused:before { color: #72aee6; } @@ -398,6 +379,11 @@ html:lang(he-il) .rtl #wpadminbar * { float: right; } +#wpadminbar ul li:last-child, +#wpadminbar ul li:last-child .ab-item { + box-shadow: none; +} + /** * Recovery Mode */ @@ -466,7 +452,7 @@ html:lang(he-il) .rtl #wpadminbar * { #wp-admin-bar-user-info .avatar { position: absolute; left: -72px; - top: 0; + top: 4px; width: 64px; height: 64px; border-radius: 50%; @@ -480,7 +466,7 @@ html:lang(he-il) .rtl #wpadminbar * { #wpadminbar #wp-admin-bar-user-info span { background: none; padding: 0; - line-height: 1.38461538; + height: 18px; } #wpadminbar #wp-admin-bar-user-info .display-name, @@ -489,6 +475,7 @@ html:lang(he-il) .rtl #wpadminbar * { } #wpadminbar #wp-admin-bar-user-info .username { + color: #a7aaad; font-size: 11px; } @@ -924,6 +911,7 @@ html:lang(he-il) .rtl #wpadminbar * { overflow: hidden; width: 52px; padding: 0; + color: #a7aaad; /* @todo not needed? this text is hidden */ position: relative; } @@ -1043,6 +1031,16 @@ html:lang(he-il) .rtl #wpadminbar * { height: auto; font-size: 16px; line-height: 1.5; + color: #f0f0f1; + } + + #wpadminbar #wp-admin-bar-user-info a { + padding-top: 4px; + } + + #wpadminbar #wp-admin-bar-user-info .username { + line-height: 0.8 !important; + margin-bottom: -2px; } /* Show only default top level items */ From e7739d54141679d2b07bb0a3143677fc4b5a1fff Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Sun, 16 Aug 2026 16:55:59 +0000 Subject: [PATCH 243/634] Rewrite Rules: Only a leading `www.` is optional in `url_to_postid()`. Fixes the behavior of `url_to_postid()`, which treated a `www.` string anywhere in the URL as optional, breaking some URLs. Anchor the string so that is only considered optional when at the beginning of a URL string. Follow up to [63207]. Props youknowriad, johnbillion, wildworks, irozum, joedolson. Fixes #65016. git-svn-id: https://develop.svn.wordpress.org/trunk@63307 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/rewrite.php | 5 ++-- tests/phpunit/tests/rewrite.php | 42 +++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/rewrite.php b/src/wp-includes/rewrite.php index 0a6b84b75e534..976d2a014b9db 100644 --- a/src/wp-includes/rewrite.php +++ b/src/wp-includes/rewrite.php @@ -502,7 +502,8 @@ function url_to_postid( $url ) { $url_host = parse_url( $url, PHP_URL_HOST ); if ( is_string( $url_host ) ) { - $url_host = str_replace( 'www.', '', $url_host ); + // Only a leading 'www.' is optional. Removing it anywhere else would match a different host. + $url_host = preg_replace( '|^www\.|', '', $url_host ); } else { $url_host = ''; } @@ -510,7 +511,7 @@ function url_to_postid( $url ) { $home_url_host = parse_url( home_url(), PHP_URL_HOST ); if ( is_string( $home_url_host ) ) { - $home_url_host = str_replace( 'www.', '', $home_url_host ); + $home_url_host = preg_replace( '|^www\.|', '', $home_url_host ); } else { $home_url_host = ''; } diff --git a/tests/phpunit/tests/rewrite.php b/tests/phpunit/tests/rewrite.php index 24c7e4e1459fc..085998e4b7eec 100644 --- a/tests/phpunit/tests/rewrite.php +++ b/tests/phpunit/tests/rewrite.php @@ -262,6 +262,48 @@ public function test_url_to_postid_url_has_only_path() { $this->assertSame( 0, url_to_postid( '/example/' ) ); } + /** + * Only a leading 'www.' is optional when comparing the URL's host to the site's. + * + * A 'www.' elsewhere in the host belongs to a different domain, which an attacker + * can register: stripping it everywhere makes 'exwww.ample.com' match 'example.com'. + * + * @ticket 65016 + * + * @covers ::url_to_postid + * + * @dataProvider data_url_to_postid_host_matching + * + * @param string $host Host of the URL to resolve. + * @param bool $is_local Whether the host should be treated as this site. + */ + public function test_url_to_postid_matches_www_prefix_only( $host, $is_local ) { + update_option( 'home', 'https://example.com' ); + update_option( 'siteurl', 'https://example.com' ); + + $post_id = self::factory()->post->create(); + + $expected = $is_local ? $post_id : 0; + + $this->assertSame( $expected, url_to_postid( "https://$host/?p=$post_id" ) ); + } + + /** + * Data provider. + * + * @return array[] + */ + public function data_url_to_postid_host_matching() { + return array( + 'the site host' => array( 'example.com', true ), + 'the site host with www' => array( 'www.example.com', true ), + 'www inside the domain' => array( 'exwww.ample.com', false ), + 'www inside the TLD' => array( 'example.cwww.om', false ), + 'an unrelated host' => array( 'evil.com', false ), + 'the site host as subdomain' => array( 'example.com.evil.com', false ), + ); + } + /** * @covers ::url_to_postid */ From 1fcc5c04cb8055087ee5b414cd10d1ce0c0e6b9f Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sun, 16 Aug 2026 18:46:59 +0000 Subject: [PATCH 244/634] Build/Test Tools: Allow text compression in the local environment. Add gzip directives to the nginx config template used by the local Docker environment so that HTML, JavaScript, CSS, JSON, XML, and SVG responses can be served compressed, matching normal production behavior. Without compression, frontend performance analysis against the local environment is not representative of a real user's experience. Compression is controlled by a new `LOCAL_NGINX_COMPRESSION` option, and it defaults to `off` so that it is opt-in. Since this changes `docker-compose.yml` in addition to the nginx template, existing checkouts need to recreate the web server container to pick up the change. Developed in https://github.com/WordPress/wordpress-develop/pull/12529. Follow-up to r45745, r45783. Props westonruter, jblz. Fixes #65634. git-svn-id: https://develop.svn.wordpress.org/trunk@63308 602fd350-edb4-49c9-b593-d223f7449a82 --- .env.example | 4 ++++ docker-compose.yml | 3 ++- tools/local-env/default.template | 15 +++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/.env.example b/.env.example index 6974d8554611a..dddbb4be4c260 100644 --- a/.env.example +++ b/.env.example @@ -14,6 +14,10 @@ LOCAL_PORT=8889 # Where to run WordPress from. Valid options are 'src' and 'build'. LOCAL_DIR=src +# Whether or not to enable text compression (gzip) in the web server. +# Valid options are 'on' and 'off'. +LOCAL_NGINX_COMPRESSION=off + # The PHP version to use. Valid options are 'latest', and '{version}-fpm'. LOCAL_PHP=latest diff --git a/docker-compose.yml b/docker-compose.yml index 7ab6ae8c9b4d5..02cd542c245db 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -14,13 +14,14 @@ services: environment: LOCAL_DIR: ${LOCAL_DIR-src} + LOCAL_NGINX_COMPRESSION: ${LOCAL_NGINX_COMPRESSION:-off} volumes: - ./tools/local-env/default.template:/etc/nginx/conf.d/default.template - ./:/var/www # Load our config file, substituting environment variables into the config. - command: /bin/sh -c "envsubst '$$LOCAL_DIR' < /etc/nginx/conf.d/default.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'" + command: /bin/sh -c "envsubst '$$LOCAL_DIR $$LOCAL_NGINX_COMPRESSION' < /etc/nginx/conf.d/default.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'" depends_on: php: diff --git a/tools/local-env/default.template b/tools/local-env/default.template index 995913fb453a2..4d8dec3c131fc 100644 --- a/tools/local-env/default.template +++ b/tools/local-env/default.template @@ -15,6 +15,21 @@ server { absolute_redirect off; + gzip ${LOCAL_NGINX_COMPRESSION}; + gzip_vary on; + gzip_proxied any; + gzip_comp_level 5; + gzip_min_length 256; + gzip_types + application/javascript + text/javascript + application/json + application/xml + application/rss+xml + text/css + text/plain + image/svg+xml; + if (!-e $request_filename) { rewrite /wp-admin$ $scheme://$host$request_uri/ permanent; rewrite ^(/[^/]+)?(/wp-.*) $2 last; From 3150f656e219b587e4014f8d3b10c68981d48222 Mon Sep 17 00:00:00 2001 From: Jonathan Desrosiers Date: Sun, 16 Aug 2026 20:24:05 +0000 Subject: [PATCH 245/634] Build/Test Tools: Remove all `npx` commands. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When an `npx` command is run, the specified package will be downloaded and installed when it does not exist locally. This will also install all of the package’s direct and transitive dependencies, and any installation scripts present for every installed package are run. This is potentially dangerous because a compromised package would be able to run code on a local machine or within a GitHub Actions workflow runner. This replaces every `npx` call with `npm exec --no`, which runs an installed binary only and will fail when the package is missing. Additionally, `update-browserslist-db` is now defined as a direct `devDependency`. Props adrianmoldovanwp, desrosj, lancewillett, johnbillion. Fixes #65864. git-svn-id: https://develop.svn.wordpress.org/trunk@63309 602fd350-edb4-49c9-b593-d223f7449a82 --- .github/workflows/reusable-end-to-end-tests.yml | 2 +- .github/workflows/reusable-performance-test-v2.yml | 2 +- Gruntfile.js | 10 +++++----- package-lock.json | 7 ++++--- package.json | 1 + tests/qunit/playwright.config.js | 2 +- 6 files changed, 13 insertions(+), 11 deletions(-) diff --git a/.github/workflows/reusable-end-to-end-tests.yml b/.github/workflows/reusable-end-to-end-tests.yml index 36a71d1711d2f..9b5586973aacf 100644 --- a/.github/workflows/reusable-end-to-end-tests.yml +++ b/.github/workflows/reusable-end-to-end-tests.yml @@ -100,7 +100,7 @@ jobs: - name: Install Playwright browsers if: ${{ inputs.install-playwright }} - run: npx playwright install --with-deps chromium + run: npm exec --no -- playwright install --with-deps chromium - name: Build WordPress run: npm run build diff --git a/.github/workflows/reusable-performance-test-v2.yml b/.github/workflows/reusable-performance-test-v2.yml index a9b911e718cba..b92893f52f7f1 100644 --- a/.github/workflows/reusable-performance-test-v2.yml +++ b/.github/workflows/reusable-performance-test-v2.yml @@ -148,7 +148,7 @@ jobs: run: npm ci - name: Install Playwright browsers - run: npx playwright install --with-deps chromium + run: npm exec --no -- playwright install --with-deps chromium - name: Start Docker environment run: npm run env:start diff --git a/Gruntfile.js b/Gruntfile.js index 61f18481e23a8..ab40643d05a80 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -2279,8 +2279,8 @@ module.exports = function(grunt) { grunt.registerTask( 'qunit', 'Runs QUnit tests.', function() { var done = this.async(); grunt.util.spawn( { - cmd: 'npx', - args: [ 'playwright', 'test', '--config', 'tests/qunit/playwright.config.js' ], + cmd: 'npm', + args: [ 'exec', '--no', '--', 'playwright', 'test', '--config', 'tests/qunit/playwright.config.js' ], opts: { stdio: 'inherit' } }, function( error, result, code ) { if ( code !== 0 ) { @@ -2363,15 +2363,15 @@ module.exports = function(grunt) { grunt.registerTask( 'wp-packages:update', 'Update WordPress packages', function() { const distTag = grunt.option('dist-tag') || 'latest'; grunt.log.writeln( `Updating WordPress packages (--dist-tag=${distTag})` ); - spawn( 'npx', [ 'wp-scripts', 'packages-update', `--dist-tag=${distTag}` ], { + spawn( 'npm', [ 'exec', '--no', '--', 'wp-scripts', 'packages-update', `--dist-tag=${distTag}` ], { cwd: __dirname, stdio: 'inherit', } ); } ); grunt.registerTask( 'browserslist:update', 'Update the local database of browser supports', function() { - grunt.log.writeln( `Updating browsers list` ); - spawn( 'npx', [ 'update-browserslist-db@latest' ], { + grunt.log.writeln( 'Updating browsers list' ); + spawn( 'npm', [ 'exec', '--no', '--', 'update-browserslist-db' ], { cwd: __dirname, stdio: 'inherit', } ); diff --git a/package-lock.json b/package-lock.json index fe92d5381d923..f1d7ebd89b2c4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -89,6 +89,7 @@ "sinon-test": "~3.1.6", "source-map-loader": "5.0.0", "typescript": "6.0.3", + "update-browserslist-db": "1.3.1", "uuid": "14.0.1", "wait-on": "9.0.10", "webpack": "5.108.4" @@ -32266,9 +32267,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.1.tgz", + "integrity": "sha512-ZZ61DsRsOnakl74HAmp3oSN4aXUmEWXf+i/yv0h7tIBfICc3VdrFErQKUUKPgu3AMsTUMbcongALEN4l6GSUrQ==", "dev": true, "funding": [ { diff --git a/package.json b/package.json index e87e95546a204..9bb1fd5d0af5b 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,7 @@ "sinon-test": "~3.1.6", "source-map-loader": "5.0.0", "typescript": "6.0.3", + "update-browserslist-db": "1.3.1", "uuid": "14.0.1", "wait-on": "9.0.10", "webpack": "5.108.4" diff --git a/tests/qunit/playwright.config.js b/tests/qunit/playwright.config.js index fc6651e0917ac..9e49301727a6a 100644 --- a/tests/qunit/playwright.config.js +++ b/tests/qunit/playwright.config.js @@ -12,7 +12,7 @@ module.exports = defineConfig( { workers: 1, use: { headless: true, - /* This avoids the need to run `npx playwright install` in CI. */ + /* The system Chrome channel avoids a browser download in CI. */ channel: process.env.CI ? 'chrome' : undefined, }, reporter: process.env.CI ? 'github' : 'list', From b2e9a22e684fc5d9438b2dbb659823e95bec80c4 Mon Sep 17 00:00:00 2001 From: Jonathan Desrosiers Date: Sun, 16 Aug 2026 22:27:51 +0000 Subject: [PATCH 246/634] Build/Test Tools: Distinguish between cancelled and timed out workflow runs. GitHub Actions expressions and contexts do not currently expose the details about a workflow run necessary to determine whether a workflow has timed out. Instead, all timed out runs are considered `cancelled`. However, the REST API does return a `timed_out` conclusion in this scenario. This creates a new job for the `timed_out` conlclusion and adjusts the logic for cancelled Slack notifications to provide more useful notifications. Props lancewillett. See #65845. git-svn-id: https://develop.svn.wordpress.org/trunk@63310 602fd350-edb4-49c9-b593-d223f7449a82 --- .github/workflows/coding-standards.yml | 1 + .github/workflows/end-to-end-tests.yml | 1 + .github/workflows/install-testing.yml | 1 + .github/workflows/javascript-tests.yml | 1 + .../workflows/javascript-type-checking.yml | 1 + .../workflows/local-docker-environment.yml | 1 + .github/workflows/performance.yml | 1 + .github/workflows/php-compatibility.yml | 1 + .github/workflows/phpstan-static-analysis.yml | 1 + .github/workflows/phpunit-tests.yml | 1 + .github/workflows/slack-notifications.yml | 42 ++++++++++++++++++- .../workflows/test-and-zip-default-themes.yml | 1 + .github/workflows/test-build-processes.yml | 1 + .github/workflows/test-coverage.yml | 1 + .github/workflows/test-old-branches.yml | 1 + .github/workflows/upgrade-develop-testing.yml | 1 + .github/workflows/upgrade-testing.yml | 1 + .github/workflows/workflow-lint.yml | 1 + 18 files changed, 57 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 8f1e9fe701330..d579368eeb079 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -89,6 +89,7 @@ jobs: SLACK_GHA_CANCELLED_WEBHOOK: ${{ secrets.SLACK_GHA_CANCELLED_WEBHOOK }} SLACK_GHA_FIXED_WEBHOOK: ${{ secrets.SLACK_GHA_FIXED_WEBHOOK }} SLACK_GHA_FAILURE_WEBHOOK: ${{ secrets.SLACK_GHA_FAILURE_WEBHOOK }} + SLACK_GHA_TIMEOUT_WEBHOOK: ${{ secrets.SLACK_GHA_TIMEOUT_WEBHOOK }} failed-workflow: name: Failed workflow tasks diff --git a/.github/workflows/end-to-end-tests.yml b/.github/workflows/end-to-end-tests.yml index d91b6512f4b49..f2eb5abb83ddb 100644 --- a/.github/workflows/end-to-end-tests.yml +++ b/.github/workflows/end-to-end-tests.yml @@ -89,6 +89,7 @@ jobs: SLACK_GHA_CANCELLED_WEBHOOK: ${{ secrets.SLACK_GHA_CANCELLED_WEBHOOK }} SLACK_GHA_FIXED_WEBHOOK: ${{ secrets.SLACK_GHA_FIXED_WEBHOOK }} SLACK_GHA_FAILURE_WEBHOOK: ${{ secrets.SLACK_GHA_FAILURE_WEBHOOK }} + SLACK_GHA_TIMEOUT_WEBHOOK: ${{ secrets.SLACK_GHA_TIMEOUT_WEBHOOK }} failed-workflow: name: Failed workflow tasks diff --git a/.github/workflows/install-testing.yml b/.github/workflows/install-testing.yml index 140e5f679701a..d69dc103d2d3a 100644 --- a/.github/workflows/install-testing.yml +++ b/.github/workflows/install-testing.yml @@ -152,6 +152,7 @@ jobs: SLACK_GHA_CANCELLED_WEBHOOK: ${{ secrets.SLACK_GHA_CANCELLED_WEBHOOK }} SLACK_GHA_FIXED_WEBHOOK: ${{ secrets.SLACK_GHA_FIXED_WEBHOOK }} SLACK_GHA_FAILURE_WEBHOOK: ${{ secrets.SLACK_GHA_FAILURE_WEBHOOK }} + SLACK_GHA_TIMEOUT_WEBHOOK: ${{ secrets.SLACK_GHA_TIMEOUT_WEBHOOK }} failed-workflow: name: Failed workflow tasks diff --git a/.github/workflows/javascript-tests.yml b/.github/workflows/javascript-tests.yml index 8b1241038773d..08a118e4a4056 100644 --- a/.github/workflows/javascript-tests.yml +++ b/.github/workflows/javascript-tests.yml @@ -77,6 +77,7 @@ jobs: SLACK_GHA_CANCELLED_WEBHOOK: ${{ secrets.SLACK_GHA_CANCELLED_WEBHOOK }} SLACK_GHA_FIXED_WEBHOOK: ${{ secrets.SLACK_GHA_FIXED_WEBHOOK }} SLACK_GHA_FAILURE_WEBHOOK: ${{ secrets.SLACK_GHA_FAILURE_WEBHOOK }} + SLACK_GHA_TIMEOUT_WEBHOOK: ${{ secrets.SLACK_GHA_TIMEOUT_WEBHOOK }} failed-workflow: name: Failed workflow tasks diff --git a/.github/workflows/javascript-type-checking.yml b/.github/workflows/javascript-type-checking.yml index 65561cabbb1e1..4983e0c619ec8 100644 --- a/.github/workflows/javascript-type-checking.yml +++ b/.github/workflows/javascript-type-checking.yml @@ -70,6 +70,7 @@ jobs: SLACK_GHA_CANCELLED_WEBHOOK: ${{ secrets.SLACK_GHA_CANCELLED_WEBHOOK }} SLACK_GHA_FIXED_WEBHOOK: ${{ secrets.SLACK_GHA_FIXED_WEBHOOK }} SLACK_GHA_FAILURE_WEBHOOK: ${{ secrets.SLACK_GHA_FAILURE_WEBHOOK }} + SLACK_GHA_TIMEOUT_WEBHOOK: ${{ secrets.SLACK_GHA_TIMEOUT_WEBHOOK }} failed-workflow: name: Failed workflow tasks diff --git a/.github/workflows/local-docker-environment.yml b/.github/workflows/local-docker-environment.yml index 856db171726b6..0f88d54ff4eb8 100644 --- a/.github/workflows/local-docker-environment.yml +++ b/.github/workflows/local-docker-environment.yml @@ -135,6 +135,7 @@ jobs: SLACK_GHA_CANCELLED_WEBHOOK: ${{ secrets.SLACK_GHA_CANCELLED_WEBHOOK }} SLACK_GHA_FIXED_WEBHOOK: ${{ secrets.SLACK_GHA_FIXED_WEBHOOK }} SLACK_GHA_FAILURE_WEBHOOK: ${{ secrets.SLACK_GHA_FAILURE_WEBHOOK }} + SLACK_GHA_TIMEOUT_WEBHOOK: ${{ secrets.SLACK_GHA_TIMEOUT_WEBHOOK }} failed-workflow: name: Failed workflow tasks diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml index ef02c51101557..22a3a27392859 100644 --- a/.github/workflows/performance.yml +++ b/.github/workflows/performance.yml @@ -153,6 +153,7 @@ jobs: SLACK_GHA_CANCELLED_WEBHOOK: ${{ secrets.SLACK_GHA_CANCELLED_WEBHOOK }} SLACK_GHA_FIXED_WEBHOOK: ${{ secrets.SLACK_GHA_FIXED_WEBHOOK }} SLACK_GHA_FAILURE_WEBHOOK: ${{ secrets.SLACK_GHA_FAILURE_WEBHOOK }} + SLACK_GHA_TIMEOUT_WEBHOOK: ${{ secrets.SLACK_GHA_TIMEOUT_WEBHOOK }} failed-workflow: name: Failed workflow tasks diff --git a/.github/workflows/php-compatibility.yml b/.github/workflows/php-compatibility.yml index 4bae7e0a381b0..37de91a73b24b 100644 --- a/.github/workflows/php-compatibility.yml +++ b/.github/workflows/php-compatibility.yml @@ -66,6 +66,7 @@ jobs: SLACK_GHA_CANCELLED_WEBHOOK: ${{ secrets.SLACK_GHA_CANCELLED_WEBHOOK }} SLACK_GHA_FIXED_WEBHOOK: ${{ secrets.SLACK_GHA_FIXED_WEBHOOK }} SLACK_GHA_FAILURE_WEBHOOK: ${{ secrets.SLACK_GHA_FAILURE_WEBHOOK }} + SLACK_GHA_TIMEOUT_WEBHOOK: ${{ secrets.SLACK_GHA_TIMEOUT_WEBHOOK }} failed-workflow: name: Failed workflow tasks diff --git a/.github/workflows/phpstan-static-analysis.yml b/.github/workflows/phpstan-static-analysis.yml index 6a26c75b16525..a07ee13e16467 100644 --- a/.github/workflows/phpstan-static-analysis.yml +++ b/.github/workflows/phpstan-static-analysis.yml @@ -66,6 +66,7 @@ jobs: SLACK_GHA_CANCELLED_WEBHOOK: ${{ secrets.SLACK_GHA_CANCELLED_WEBHOOK }} SLACK_GHA_FIXED_WEBHOOK: ${{ secrets.SLACK_GHA_FIXED_WEBHOOK }} SLACK_GHA_FAILURE_WEBHOOK: ${{ secrets.SLACK_GHA_FAILURE_WEBHOOK }} + SLACK_GHA_TIMEOUT_WEBHOOK: ${{ secrets.SLACK_GHA_TIMEOUT_WEBHOOK }} failed-workflow: name: Failed workflow tasks diff --git a/.github/workflows/phpunit-tests.yml b/.github/workflows/phpunit-tests.yml index f0f1282f73a93..30cf72bc606ae 100644 --- a/.github/workflows/phpunit-tests.yml +++ b/.github/workflows/phpunit-tests.yml @@ -411,6 +411,7 @@ jobs: SLACK_GHA_CANCELLED_WEBHOOK: ${{ secrets.SLACK_GHA_CANCELLED_WEBHOOK }} SLACK_GHA_FIXED_WEBHOOK: ${{ secrets.SLACK_GHA_FIXED_WEBHOOK }} SLACK_GHA_FAILURE_WEBHOOK: ${{ secrets.SLACK_GHA_FAILURE_WEBHOOK }} + SLACK_GHA_TIMEOUT_WEBHOOK: ${{ secrets.SLACK_GHA_TIMEOUT_WEBHOOK }} failed-workflow: name: Failed workflow tasks diff --git a/.github/workflows/slack-notifications.yml b/.github/workflows/slack-notifications.yml index 0877405409e83..4b4dfc831aaeb 100644 --- a/.github/workflows/slack-notifications.yml +++ b/.github/workflows/slack-notifications.yml @@ -25,6 +25,9 @@ on: SLACK_GHA_FAILURE_WEBHOOK: description: 'The Slack webhook URL for a failed build.' required: true + SLACK_GHA_TIMEOUT_WEBHOOK: + description: 'The Slack webhook URL for a timed out build.' + required: true # Disable permissions for all available scopes by default. # Any needed permissions should be configured at the job level. @@ -55,6 +58,7 @@ jobs: if: ${{ github.repository == 'WordPress/wordpress-develop' && github.event.workflow_run.event != 'pull_request' }} outputs: previous_conclusion: ${{ steps.previous-attempt-result.outputs.result }} + timed_out: ${{ steps.timeout-check.outputs.result }} payload: ${{ steps.create-payload.outputs.payload }} steps: @@ -128,6 +132,25 @@ jobs: env: CALLING_STATUS: ${{ inputs.calling_status }} + # The REST API exposes a distinct `timed_out` job conclusion that is unavailable through workflow contexts. + - name: Determine whether the workflow timed out + id: timeout-check + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + if: ${{ inputs.calling_status == 'cancelled' }} + with: + retries: 2 + retry-exempt-status-codes: 418 + result-encoding: string + script: | + const jobs = await github.paginate( github.rest.actions.listJobsForWorkflowRunAttempt, { + owner: context.repo.owner, + repo: context.repo.repo, + run_id: `${context.runId}`, + attempt_number: Number( process.env.GITHUB_RUN_ATTEMPT ), + }, ( response ) => response.data.jobs ); + + return jobs.some( ( job ) => job.conclusion === 'timed_out' ) ? 'true' : 'false'; + - name: Get the commit message id: current-commit-message uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -211,14 +234,13 @@ jobs: webhook: ${{ secrets.SLACK_GHA_SUCCESS_WEBHOOK }} payload: ${{ needs.prepare.outputs.payload }} - # Posts notifications when a workflow is cancelled. cancelled: name: Cancelled notifications permissions: {} runs-on: ubuntu-24.04 timeout-minutes: 20 needs: [ prepare ] - if: ${{ inputs.calling_status == 'cancelled' && github.run_attempt == 2 || cancelled() }} + if: ${{ ( inputs.calling_status == 'cancelled' && github.run_attempt == 2 && needs.prepare.outputs.timed_out != 'true' ) || cancelled() }} steps: - name: Post cancelled notifications to Slack @@ -227,3 +249,19 @@ jobs: webhook-type: webhook-trigger webhook: ${{ secrets.SLACK_GHA_CANCELLED_WEBHOOK }} payload: ${{ needs.prepare.outputs.payload }} + + timeout: + name: Timeout notifications + permissions: {} + runs-on: ubuntu-24.04 + timeout-minutes: 20 + needs: [ prepare ] + if: ${{ inputs.calling_status == 'cancelled' && github.run_attempt == 2 && needs.prepare.outputs.timed_out == 'true' }} + + steps: + - name: Post timeout notifications to Slack + uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 + with: + webhook-type: webhook-trigger + webhook: ${{ secrets.SLACK_GHA_TIMEOUT_WEBHOOK }} + payload: ${{ needs.prepare.outputs.payload }} diff --git a/.github/workflows/test-and-zip-default-themes.yml b/.github/workflows/test-and-zip-default-themes.yml index 30c15408f9736..0464a1652d36b 100644 --- a/.github/workflows/test-and-zip-default-themes.yml +++ b/.github/workflows/test-and-zip-default-themes.yml @@ -284,6 +284,7 @@ jobs: SLACK_GHA_CANCELLED_WEBHOOK: ${{ secrets.SLACK_GHA_CANCELLED_WEBHOOK }} SLACK_GHA_FIXED_WEBHOOK: ${{ secrets.SLACK_GHA_FIXED_WEBHOOK }} SLACK_GHA_FAILURE_WEBHOOK: ${{ secrets.SLACK_GHA_FAILURE_WEBHOOK }} + SLACK_GHA_TIMEOUT_WEBHOOK: ${{ secrets.SLACK_GHA_TIMEOUT_WEBHOOK }} failed-workflow: name: Failed workflow tasks diff --git a/.github/workflows/test-build-processes.yml b/.github/workflows/test-build-processes.yml index cd32d99cacb1f..ab3bea392cef8 100644 --- a/.github/workflows/test-build-processes.yml +++ b/.github/workflows/test-build-processes.yml @@ -118,6 +118,7 @@ jobs: SLACK_GHA_CANCELLED_WEBHOOK: ${{ secrets.SLACK_GHA_CANCELLED_WEBHOOK }} SLACK_GHA_FIXED_WEBHOOK: ${{ secrets.SLACK_GHA_FIXED_WEBHOOK }} SLACK_GHA_FAILURE_WEBHOOK: ${{ secrets.SLACK_GHA_FAILURE_WEBHOOK }} + SLACK_GHA_TIMEOUT_WEBHOOK: ${{ secrets.SLACK_GHA_TIMEOUT_WEBHOOK }} failed-workflow: name: Failed workflow tasks diff --git a/.github/workflows/test-coverage.yml b/.github/workflows/test-coverage.yml index 191445ba7167c..94f57628254c3 100644 --- a/.github/workflows/test-coverage.yml +++ b/.github/workflows/test-coverage.yml @@ -97,6 +97,7 @@ jobs: SLACK_GHA_CANCELLED_WEBHOOK: ${{ secrets.SLACK_GHA_CANCELLED_WEBHOOK }} SLACK_GHA_FIXED_WEBHOOK: ${{ secrets.SLACK_GHA_FIXED_WEBHOOK }} SLACK_GHA_FAILURE_WEBHOOK: ${{ secrets.SLACK_GHA_FAILURE_WEBHOOK }} + SLACK_GHA_TIMEOUT_WEBHOOK: ${{ secrets.SLACK_GHA_TIMEOUT_WEBHOOK }} failed-workflow: name: Failed workflow tasks diff --git a/.github/workflows/test-old-branches.yml b/.github/workflows/test-old-branches.yml index b5bef1b88c0bc..7094550485c4f 100644 --- a/.github/workflows/test-old-branches.yml +++ b/.github/workflows/test-old-branches.yml @@ -158,3 +158,4 @@ jobs: SLACK_GHA_CANCELLED_WEBHOOK: ${{ secrets.SLACK_GHA_CANCELLED_WEBHOOK }} SLACK_GHA_FIXED_WEBHOOK: ${{ secrets.SLACK_GHA_FIXED_WEBHOOK }} SLACK_GHA_FAILURE_WEBHOOK: ${{ secrets.SLACK_GHA_FAILURE_WEBHOOK }} + SLACK_GHA_TIMEOUT_WEBHOOK: ${{ secrets.SLACK_GHA_TIMEOUT_WEBHOOK }} diff --git a/.github/workflows/upgrade-develop-testing.yml b/.github/workflows/upgrade-develop-testing.yml index f14736af874a1..4147d3f054b8b 100644 --- a/.github/workflows/upgrade-develop-testing.yml +++ b/.github/workflows/upgrade-develop-testing.yml @@ -140,6 +140,7 @@ jobs: SLACK_GHA_CANCELLED_WEBHOOK: ${{ secrets.SLACK_GHA_CANCELLED_WEBHOOK }} SLACK_GHA_FIXED_WEBHOOK: ${{ secrets.SLACK_GHA_FIXED_WEBHOOK }} SLACK_GHA_FAILURE_WEBHOOK: ${{ secrets.SLACK_GHA_FAILURE_WEBHOOK }} + SLACK_GHA_TIMEOUT_WEBHOOK: ${{ secrets.SLACK_GHA_TIMEOUT_WEBHOOK }} failed-workflow: name: Failed workflow tasks diff --git a/.github/workflows/upgrade-testing.yml b/.github/workflows/upgrade-testing.yml index 9a9c239e3093d..0d89c062f3b3b 100644 --- a/.github/workflows/upgrade-testing.yml +++ b/.github/workflows/upgrade-testing.yml @@ -206,6 +206,7 @@ jobs: SLACK_GHA_CANCELLED_WEBHOOK: ${{ secrets.SLACK_GHA_CANCELLED_WEBHOOK }} SLACK_GHA_FIXED_WEBHOOK: ${{ secrets.SLACK_GHA_FIXED_WEBHOOK }} SLACK_GHA_FAILURE_WEBHOOK: ${{ secrets.SLACK_GHA_FAILURE_WEBHOOK }} + SLACK_GHA_TIMEOUT_WEBHOOK: ${{ secrets.SLACK_GHA_TIMEOUT_WEBHOOK }} failed-workflow: name: Failed workflow tasks diff --git a/.github/workflows/workflow-lint.yml b/.github/workflows/workflow-lint.yml index b2d5c2638e7b4..1ef050f1b9b92 100644 --- a/.github/workflows/workflow-lint.yml +++ b/.github/workflows/workflow-lint.yml @@ -61,6 +61,7 @@ jobs: SLACK_GHA_CANCELLED_WEBHOOK: ${{ secrets.SLACK_GHA_CANCELLED_WEBHOOK }} SLACK_GHA_FIXED_WEBHOOK: ${{ secrets.SLACK_GHA_FIXED_WEBHOOK }} SLACK_GHA_FAILURE_WEBHOOK: ${{ secrets.SLACK_GHA_FAILURE_WEBHOOK }} + SLACK_GHA_TIMEOUT_WEBHOOK: ${{ secrets.SLACK_GHA_TIMEOUT_WEBHOOK }} failed-workflow: name: Failed workflow tasks From 582236f30b73a9de268da3df117d590174ce108d Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Sun, 16 Aug 2026 22:28:40 +0000 Subject: [PATCH 247/634] Tests: Use `assertIsCallable()` for callable assertions. Replaces eight generic `assertTrue( is_callable() )` assertions with PHPUnit's dedicated `assertIsCallable()` assertion. Developed in https://github.com/WordPress/wordpress-develop/pull/13017. Follow-up to r50996, r61760. Props raulsalvat, Soean. See #65819. git-svn-id: https://develop.svn.wordpress.org/trunk@63311 602fd350-edb4-49c9-b593-d223f7449a82 --- tests/phpunit/tests/customize/widgets.php | 12 ++++++------ .../tests/multisite/wpCacheSwitchToBlogFallback.php | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/phpunit/tests/customize/widgets.php b/tests/phpunit/tests/customize/widgets.php index 5b64f85ce3392..c2ed6dbc661e2 100644 --- a/tests/phpunit/tests/customize/widgets.php +++ b/tests/phpunit/tests/customize/widgets.php @@ -397,8 +397,8 @@ public function test_get_setting_args() { foreach ( $default_args as $key => $default_value ) { $this->assertSame( $default_value, $args[ $key ] ); } - $this->assertTrue( is_callable( $args['sanitize_callback'] ), 'sanitize_callback is callable' ); - $this->asserttrue( is_callable( $args['sanitize_js_callback'] ), 'sanitize_js_callback is callable' ); + $this->assertIsCallable( $args['sanitize_callback'], 'sanitize_callback is callable' ); + $this->assertIsCallable( $args['sanitize_js_callback'], 'sanitize_js_callback is callable' ); $this->assertSame( 'WIDGET_FOO[2]', $args['uppercase_id_set_by_filter'] ); $default_args = array( @@ -411,8 +411,8 @@ public function test_get_setting_args() { foreach ( $default_args as $key => $default_value ) { $this->assertSame( $default_value, $args[ $key ] ); } - $this->assertTrue( is_callable( $args['sanitize_callback'] ), 'sanitize_callback is callable' ); - $this->asserttrue( is_callable( $args['sanitize_js_callback'] ), 'sanitize_js_callback is callable' ); + $this->assertIsCallable( $args['sanitize_callback'], 'sanitize_callback is callable' ); + $this->assertIsCallable( $args['sanitize_js_callback'], 'sanitize_js_callback is callable' ); remove_theme_support( 'customize-selective-refresh-widgets' ); $args = $this->manager->widgets->get_setting_args( 'widget_search[2]' ); @@ -443,8 +443,8 @@ public function test_get_setting_args() { foreach ( $default_args as $key => $default_value ) { $this->assertSame( $default_value, $args[ $key ] ); } - $this->assertTrue( is_callable( $args['sanitize_callback'] ), 'sanitize_callback is callable' ); - $this->asserttrue( is_callable( $args['sanitize_js_callback'] ), 'sanitize_js_callback is callable' ); + $this->assertIsCallable( $args['sanitize_callback'], 'sanitize_callback is callable' ); + $this->assertIsCallable( $args['sanitize_js_callback'], 'sanitize_js_callback is callable' ); $this->assertSame( 'SIDEBARS_WIDGETS[SIDEBAR-1]', $args['uppercase_id_set_by_filter'] ); $override_args = array( diff --git a/tests/phpunit/tests/multisite/wpCacheSwitchToBlogFallback.php b/tests/phpunit/tests/multisite/wpCacheSwitchToBlogFallback.php index 35083088017b0..ffc3e1f263f6d 100644 --- a/tests/phpunit/tests/multisite/wpCacheSwitchToBlogFallback.php +++ b/tests/phpunit/tests/multisite/wpCacheSwitchToBlogFallback.php @@ -121,8 +121,8 @@ public function test_wp_cache_switch_to_blog_function_exists() { $this->assertTrue( function_exists( 'wp_cache_switch_to_blog_fallback' ), 'wp_cache_switch_to_blog_fallback() should always exist' ); // Both should be callable. - $this->assertTrue( is_callable( 'wp_cache_switch_to_blog' ) ); - $this->assertTrue( is_callable( 'wp_cache_switch_to_blog_fallback' ) ); + $this->assertIsCallable( 'wp_cache_switch_to_blog' ); + $this->assertIsCallable( 'wp_cache_switch_to_blog_fallback' ); } /** From 1ae6d6965ee668cb5d23fc5d48b3ea3049a983e1 Mon Sep 17 00:00:00 2001 From: Jake Spurlock Date: Sun, 16 Aug 2026 22:29:34 +0000 Subject: [PATCH 248/634] Filesystem API: Reject UNC and device paths in `validate_file()`. `validate_file()` runs `wp_normalize_path()` before testing for a drive letter at offset 1. That call folds backslashes to forward slashes, but its slash-collapsing regex deliberately spares a leading `//` to allow for network shares. UNC paths such as `//server/share`, and the device namespaces `//./` and `//?/`, therefore arrived with no colon in the second byte and returned `0` rather than `2`. The docblock described a return value of `2` as meaning the path contains a Windows drive path, which reads as a guarantee that Windows absolute paths are screened. Most forms were not. Anchoring a second test to the start of the string closes that gap. Stream wrappers stay at `0` by two separate mechanisms: a registered wrapper keeps its `://` through the scheme split, placing those slashes past the second byte, while an unregistered scheme has its `//` collapsed. Code `2` now fires on strictly more inputs and never fewer, so no existing rejection becomes an acceptance. Absolute POSIX paths such as `/etc/passwd` continue to return `0`; screening those would be a larger change affecting plugins that pass absolute template paths. Paths beginning with two successive slashes are now rejected regardless of platform, which includes the implementation-defined POSIX doubled-slash form, consistent with the assumption `wp_normalize_path()` already makes about a leading `//`. Props zieladam, SergeyBiryukov. Fixes #51368. git-svn-id: https://develop.svn.wordpress.org/trunk@63312 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/functions.php | 28 +++++++- tests/phpunit/tests/functions.php | 115 ++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index f5002a45de1e8..5d84c0eeb32d5 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -6359,11 +6359,20 @@ function iis7_supports_permalinks() { * * A return value of `1` means the file path contains directory traversal. * - * A return value of `2` means the file path contains a Windows drive path. + * A return value of `2` means the file path contains an absolute Windows path. + * This covers drive paths such as `C:/WINDOWS`, UNC network share paths such as + * `//server/share`, and the Windows device namespaces `//./` and `//?/`. * * A return value of `3` means the file is not in the allowed files list. * + * Note that absolute POSIX paths such as `/etc/passwd` are *not* rejected, and + * never have been. Callers that must reject them are responsible for their own + * check. The convention in core is to concatenate the validated value onto a + * trusted base directory and then confirm the result exists, rather than to + * treat this function as an absolute-path guard. + * * @since 1.2.0 + * @since 7.2.0 A return value of `2` also covers UNC and Windows device paths. * * @param string $file File path. * @param string[] $allowed_files Optional. Array of allowed files. Default empty array. @@ -6399,8 +6408,21 @@ function validate_file( $file, $allowed_files = array() ) { return 3; } - // Absolute Windows drive paths are not allowed: - if ( ':' === substr( $file, 1, 1 ) ) { + /* + * Absolute Windows paths are not allowed. + * + * The drive-letter test predates validate_file() itself, arriving from + * b2/cafelog by way of a long series of moves. It only ever matched the + * `X:` form, which left UNC and device paths accepted: wp_normalize_path() + * above has already folded backslashes to forward slashes, and it + * deliberately preserves a leading `//` for network shares, so those + * paths arrive with no colon in the second byte. + * + * Anchoring the second test to the start of the string is what keeps + * stream wrappers working. A registered wrapper keeps its `://` through + * wp_normalize_path(), placing those slashes past the second byte. + */ + if ( ':' === substr( $file, 1, 1 ) || str_starts_with( $file, '//' ) ) { return 2; } diff --git a/tests/phpunit/tests/functions.php b/tests/phpunit/tests/functions.php index 19c721aeaa46a..3c709f3ea7090 100644 --- a/tests/phpunit/tests/functions.php +++ b/tests/phpunit/tests/functions.php @@ -1984,6 +1984,121 @@ public function data_validate_file() { 0, ), + /* + * Windows UNC and device paths. + * + * wp_normalize_path() folds backslashes to forward slashes but + * deliberately preserves a leading '//' for network shares, so + * these arrive with no colon at offset 1 and must be matched on + * the '//' prefix instead. + */ + array( + '//system07/C$/', + array(), + 2, + ), + array( + '//Server2/Share/Test/Foo.txt', + array(), + 2, + ), + array( + '//127.0.0.1/c$/temp/test-file.txt', + array(), + 2, + ), + array( + '//./c:/temp/test-file.txt', + array(), + 2, + ), + array( + '//?/c:/temp/test-file.txt', + array(), + 2, + ), + array( + '//./UNC/LOCALHOST/c$/temp/test-file.txt', + array(), + 2, + ), + // The backslash form a Windows caller actually supplies. + array( + '\\\\system07\\C$\\', + array(), + 2, + ), + // Shortest matching input. + array( + '//', + array(), + 2, + ), + // A UNC path is rejected even when explicitly allowed, matching + // the precedence the drive-letter check already has. + array( + '//system07/C$/foo.php', + array( '//system07/C$/foo.php' ), + 2, + ), + + /* + * Absolute POSIX paths are NOT rejected. validate_file() has never + * screened them and does not begin to here. Callers needing that + * must check separately; core's convention is to concatenate onto + * a trusted base directory and stat the result. + */ + array( + '/etc/passwd', + array(), + 0, + ), + array( + '/Server2/Share/Test/Foo.txt', + array(), + 0, + ), + array( + '/', + array(), + 0, + ), + /* + * A deliberate exception. POSIX.1 leaves a pathname beginning with + * two successive slashes implementation-defined, and Linux resolves + * it as a single slash, so this is a valid POSIX path. It is still + * rejected: after normalization it cannot be told apart from a UNC + * path, and wp_normalize_path() already preserves a leading '//' on + * the assumption that it denotes a network share. + */ + array( + '//home/user/file.php', + array(), + 2, + ), + + /* + * Stream wrappers stay allowed via two different mechanisms. + * A registered wrapper keeps its '://' through wp_normalize_path()'s + * scheme split; an unregistered one has its '//' collapsed. Neither + * ends up with a leading '//'. + */ + array( + 'php://memory', + array(), + 0, + ), + array( + 'file:///tmp/test-file.txt', + array(), + 0, + ), + array( + 'myapp://foo/bar', + array(), + 0, + ), + // Disallowed files: array( 'foo.ext', From 62668dec7bcfbec8d1688f5719f0bbf39054e8f6 Mon Sep 17 00:00:00 2001 From: Jonathan Desrosiers Date: Sun, 16 Aug 2026 22:40:20 +0000 Subject: [PATCH 249/634] Build/Test Tools: Make `SLACK_GHA_TIMEOUT_WEBHOOK` optional. This temporarily marks the `SLACK_GHA_TIMEOUT_WEBHOOK` secret as optional until [63310] can be backported to older branches to avoid workflow failures. Follow-up to [63310]. See #65845. git-svn-id: https://develop.svn.wordpress.org/trunk@63313 602fd350-edb4-49c9-b593-d223f7449a82 --- .github/workflows/slack-notifications.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/slack-notifications.yml b/.github/workflows/slack-notifications.yml index 4b4dfc831aaeb..6a2f23714e291 100644 --- a/.github/workflows/slack-notifications.yml +++ b/.github/workflows/slack-notifications.yml @@ -27,7 +27,7 @@ on: required: true SLACK_GHA_TIMEOUT_WEBHOOK: description: 'The Slack webhook URL for a timed out build.' - required: true + required: false # Disable permissions for all available scopes by default. # Any needed permissions should be configured at the job level. From 32c0322f614d786ec65a3e3fa8e06b81d2e906a1 Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Sun, 16 Aug 2026 22:53:07 +0000 Subject: [PATCH 250/634] Code Quality: Resolve return.empty PHPStan errors in baseline. Fixes a couple of functions with return-type problems. One is resolved by adding the missing `void` type, while the other is resolved by updating the function to conform to the existing `string` return type contract, a likely oversight in the original commit. This change was part of Contributor Day at WordCamp US 2026. Developed in: https://github.com/WordPress/wordpress-develop/pull/13081 Discussed in: https://core.trac.wordpress.org/ticket/65817 Props dmsnell, nomadmystic. See #65817. git-svn-id: https://develop.svn.wordpress.org/trunk@63314 602fd350-edb4-49c9-b593-d223f7449a82 --- phpstan.neon.dist | 1 - .../themes/twentytwenty/inc/custom-css.php | 6 +--- src/wp-includes/l10n.php | 2 +- tests/phpstan/baselines/return.empty.neon | 30 ------------------- 4 files changed, 2 insertions(+), 37 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index e2e72fb367482..248623a5c01d6 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -79,7 +79,6 @@ includes: - tests/phpstan/baselines/property.phpDocType.neon - tests/phpstan/baselines/property.private.neon - tests/phpstan/baselines/property.protected.neon - - tests/phpstan/baselines/return.empty.neon - tests/phpstan/baselines/return.missing.neon - tests/phpstan/baselines/return.type.neon - tests/phpstan/baselines/return.unusedType.neon diff --git a/src/wp-content/themes/twentytwenty/inc/custom-css.php b/src/wp-content/themes/twentytwenty/inc/custom-css.php index 25f8525d8511a..50af2e6e72c0e 100644 --- a/src/wp-content/themes/twentytwenty/inc/custom-css.php +++ b/src/wp-content/themes/twentytwenty/inc/custom-css.php @@ -23,15 +23,11 @@ * @return string Generated CSS. */ function twentytwenty_generate_css( $selector, $style, $value, $prefix = '', $suffix = '', $display = true ) { - - $return = ''; - /* * Bail early if we have no $selector elements or properties and $value. */ if ( ! $value || ! $selector ) { - - return; + return ''; } $return = sprintf( '%s { %s: %s; }', $selector, $style, $prefix . $value . $suffix ); diff --git a/src/wp-includes/l10n.php b/src/wp-includes/l10n.php index 2f27c2180037a..43b32017becac 100644 --- a/src/wp-includes/l10n.php +++ b/src/wp-includes/l10n.php @@ -1735,7 +1735,7 @@ function wp_get_l10n_php_file_data( $php_file ) { * @type bool $explicit_option_en_us Whether the English (United States) option uses an explicit value of en_US * instead of an empty value. Default false. * } - * @return string HTML dropdown list of languages. + * @return string|void HTML dropdown list of languages. */ function wp_dropdown_languages( $args = array() ) { diff --git a/tests/phpstan/baselines/return.empty.neon b/tests/phpstan/baselines/return.empty.neon index 5abf2badb5636..e69de29bb2d1d 100644 --- a/tests/phpstan/baselines/return.empty.neon +++ b/tests/phpstan/baselines/return.empty.neon @@ -1,30 +0,0 @@ -# PHPStan baseline for the `return.empty` errors in WordPress core. -# -# https://phpstan.org/error-identifiers/return.empty -# -# Each entry is scoped to a single file and carries an exact occurrence count, -# so that a new instance is reported as a new error rather than being absorbed -# silently. Fixing an occurrence therefore means decrementing or removing its -# entry here as part of the same change. -# -# The goal is to empty this file and delete it, along with the `includes` entry -# for it in phpstan.neon.dist. -# -# Generated by `composer phpstan:baselines`. Do not edit by hand; regenerate with -# -# composer phpstan:baselines -- --identifier=return.empty -# -# which reruns the analysis with this file suppressed so the errors surface again. - -parameters: - ignoreErrors: - - - message: '#^Function twentytwenty_generate_css\(\) should return string but empty return statement found\.$#' - identifier: return.empty - count: 1 - path: ../../../src/wp-content/themes/twentytwenty/inc/custom-css.php - - - message: '#^Function wp_dropdown_languages\(\) should return string but empty return statement found\.$#' - identifier: return.empty - count: 1 - path: ../../../src/wp-includes/l10n.php From 888f0d9a4a96ecb85453c25f477956e804ee2174 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sun, 16 Aug 2026 23:07:40 +0000 Subject: [PATCH 251/634] Build/Test Tools: Stop committing changes to tracked files in pull requests. This workflow has not proven to be as useful as originally hoped, so it's being removed to reduce maintenance burden. All workflows that run the build script already fail if they result in untracked changes. Developed in https://github.com/WordPress/wordpress-develop/pull/13087 Props desrosj See #65845 git-svn-id: https://develop.svn.wordpress.org/trunk@63315 602fd350-edb4-49c9-b593-d223f7449a82 --- .github/workflows/check-built-files.yml | 54 ------ .../workflows/commit-built-file-changes.yml | 166 ------------------ .../workflows/reusable-check-built-files.yml | 104 ----------- .../reusable-test-core-build-process.yml | 4 + 4 files changed, 4 insertions(+), 324 deletions(-) delete mode 100644 .github/workflows/check-built-files.yml delete mode 100644 .github/workflows/commit-built-file-changes.yml delete mode 100644 .github/workflows/reusable-check-built-files.yml diff --git a/.github/workflows/check-built-files.yml b/.github/workflows/check-built-files.yml deleted file mode 100644 index 01a239c4eb3b0..0000000000000 --- a/.github/workflows/check-built-files.yml +++ /dev/null @@ -1,54 +0,0 @@ -# Checks for uncommitted changes to built files in pull requests. -name: Check Built Files (PRs) - -on: - # Because all commits happen through SVN and should always be manually reviewed by a committer, this workflow only - # runs for pull requests. - # - # Other workflows that run for the push event will detect changes to versioned files and fail. - pull_request: - branches: - - trunk - - '6.[8-9]' - - '[7-9].[0-9]' - paths: - # Any change to a CSS, JavaScript, JSON, or SASS file should run checks. - - '**.css' - - '**.js' - - '**.json' - - '**.sass' - # These files configure npm and the task runner. Changes could affect the outcome. - - 'package*.json' - - '.npmrc' - - '.nvmrc' - - 'Gruntfile.js' - - 'webpack.config.js' - - 'tools/gutenberg/**' - - 'tools/vendors/**' - - 'tools/webpack/**' - # These files configure Composer. Changes could affect the outcome. - - 'composer.*' - # Confirm any changes to relevant workflow files. - - '.github/workflows/check-built-files.yml' - - '.github/workflows/reusable-check-built-files.yml' - # Changes to the default themes should be handled by the themes workflows. - - '!src/wp-content/themes/twenty**' - -# Cancels all previous workflow runs for pull requests that have not completed. -concurrency: - # The concurrency group contains the workflow name and the branch name for pull requests - # or the commit hash for any other events. - group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }} - cancel-in-progress: true - -# Disable permissions for all available scopes by default. -# Any needed permissions should be configured at the job level. -permissions: {} - -jobs: - check-for-built-file-changes: - name: Check built files - if: ${{ github.repository == 'wordpress/wordpress-develop' }} - uses: ./.github/workflows/reusable-check-built-files.yml - permissions: - contents: read diff --git a/.github/workflows/commit-built-file-changes.yml b/.github/workflows/commit-built-file-changes.yml deleted file mode 100644 index 9a959187505c9..0000000000000 --- a/.github/workflows/commit-built-file-changes.yml +++ /dev/null @@ -1,166 +0,0 @@ -# Commits all missed changes to built files back to pull request branches. -name: Commit Built File Changes (PRs) - -on: - workflow_run: - workflows: - - 'Check Built Files (PRs)' - - 'Test Default Themes & Create ZIPs' - types: - - completed - -# Cancels all previous workflow runs for pull requests that have not completed. -concurrency: - # The concurrency group contains the workflow name and the branch name for pull requests - # or the commit hash for any other events. - group: ${{ github.workflow }}-${{ github.event_name == 'workflow_run' && format( '{0}-{1}', github.event.workflow_run.head_branch, github.event.workflow_run.head_repository.name ) || github.sha }} - -# Disable permissions for all available scopes by default. -# Any needed permissions should be configured at the job level. -permissions: {} - -jobs: - # Checks a PR for uncommitted changes to built files. - # - # Performs the following steps: - # - Attempts to download the artifact containing the PR diff. - # - Checks for the existence of an artifact. - # - Unzips the artifact. - # - Generates a token for authenticating with the GitHub App. - # - Checks out the repository. - # - Applies the patch file. - # - Displays the result of git diff. - # - Configures the Git author. - # - Stages changes. - # - Commits changes. - # - Pushes changes. - update-built-files: - name: Check and update built files - runs-on: ubuntu-24.04 - if: ${{ github.repository == 'wordpress/wordpress-develop' }} - timeout-minutes: 10 - permissions: - # The actual `git push` is authenticated via a dedicated GitHub App installation token - # generated below, so `GITHUB_TOKEN` only needs read access to the triggering workflow's artifacts. - actions: read # Required to list and download the artifact uploaded by the triggering workflow run. - steps: - - name: Download artifact - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - with: - script: | - const artifacts = await github.rest.actions.listWorkflowRunArtifacts( { - owner: context.repo.owner, - repo: context.repo.repo, - run_id: process.env.RUN_ID, - } ); - - const matchArtifact = artifacts.data.artifacts.filter( ( artifact ) => { - return artifact.name === 'pr-built-file-changes' - } )[0]; - - if ( ! matchArtifact ) { - core.info( 'No artifact found!' ); - return; - } - - const download = await github.rest.actions.downloadArtifact( { - owner: context.repo.owner, - repo: context.repo.repo, - artifact_id: matchArtifact.id, - archive_format: 'zip', - } ); - - const fs = require( 'fs' ); - fs.writeFileSync( '${{ github.workspace }}/pr-built-file-changes.zip', Buffer.from( download.data ) ) - env: - RUN_ID: ${{ github.event.workflow_run.id }} - - - name: Check for artifact - id: artifact-check - run: | - if [ -f "pr-built-file-changes.zip" ]; then - echo "exists=true" >> "$GITHUB_OUTPUT" - else - echo "exists=false" >> "$GITHUB_OUTPUT" - fi - - - name: Unzip the artifact containing the PR data - if: ${{ steps.artifact-check.outputs.exists == 'true' }} - run: unzip pr-built-file-changes.zip - - - name: Generate Installation Token - id: generate_token - if: ${{ steps.artifact-check.outputs.exists == 'true' }} - env: - GH_APP_ID: ${{ vars.GH_PR_BUILT_FILES_APP_ID }} - GH_APP_PRIVATE_KEY: ${{ secrets.GH_PR_BUILT_FILES_PRIVATE_KEY }} - run: | - # Generate JWT - JWT=$(python3 - <> "$GITHUB_OUTPUT" - - - name: Checkout repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - if: ${{ steps.artifact-check.outputs.exists == 'true' }} - with: - repository: ${{ github.event.workflow_run.head_repository.full_name }} - ref: ${{ github.event.workflow_run.head_branch }} - path: 'pr-repo' - show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} - token: ${{ steps.generate_token.outputs.access-token }} - persist-credentials: true - - - name: Apply patch - if: ${{ steps.artifact-check.outputs.exists == 'true' }} - working-directory: 'pr-repo' - run: git apply "$GITHUB_WORKSPACE/changes.diff" - - - name: Display changes to versioned files - if: ${{ steps.artifact-check.outputs.exists == 'true' }} - working-directory: 'pr-repo' - run: git diff - - - name: Configure git user name and email - if: ${{ steps.artifact-check.outputs.exists == 'true' }} - working-directory: 'pr-repo' - env: - GH_APP_ID: ${{ vars.GH_PR_BUILT_FILES_APP_ID }} - run: | - git config user.name "wordpress-develop-pr-bot[bot]" - git config user.email "${GH_APP_ID}+wordpress-develop-pr-bot[bot]@users.noreply.github.com" - - - name: Stage changes - if: ${{ steps.artifact-check.outputs.exists == 'true' }} - working-directory: 'pr-repo' - run: git add . - - - name: Commit changes - if: ${{ steps.artifact-check.outputs.exists == 'true' }} - working-directory: 'pr-repo' - run: | - git commit -m "Automation: Updating built files with changes." - - - name: Push changes - if: ${{ steps.artifact-check.outputs.exists == 'true' }} - working-directory: 'pr-repo' - run: git push diff --git a/.github/workflows/reusable-check-built-files.yml b/.github/workflows/reusable-check-built-files.yml deleted file mode 100644 index 043c24581cc36..0000000000000 --- a/.github/workflows/reusable-check-built-files.yml +++ /dev/null @@ -1,104 +0,0 @@ -## -# A reusable workflow that checks for uncommitted changes to built files in pull requests. -## -name: Check Built Files (PRs) - -on: - workflow_call: - -permissions: {} - -jobs: - # Checks a PR for uncommitted changes to built files. - # - # When changes are detected, the patch is stored as an artifact for processing by the Commit Built File Changes - # workflow. - # - # Performs the following steps: - # - Checks out the repository. - # - Sets up Node.js. - # - Installs Composer dependencies. - # - Logs general debug information about the runner. - # - Installs npm dependencies. - # - Builds CSS file using SASS. - # - Builds Emoji files. - # - Builds bundled Root Certificate files. - # - Builds WordPress. - # - Checks for changes to versioned files. - # - Displays the result of git diff for debugging purposes. - # - Saves the diff to a patch file. - # - Uploads the patch file as an artifact. - update-built-files: - name: Check and update built files - runs-on: ubuntu-24.04 - timeout-minutes: 10 - permissions: - contents: read - steps: - - name: Checkout repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} - persist-credentials: false - - - name: Set up Node.js - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 - with: - node-version-file: '.nvmrc' - cache: npm - - # Since Composer dependencies are installed using `composer update` and no lock file is in version control, - # passing a custom cache suffix ensures that the cache is flushed at least once per week. - - name: Install Composer dependencies - uses: ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda # 4.0.0 - with: - custom-cache-suffix: $(/bin/date -u --date='last Mon' "+%F") - - - name: Log debug information - run: | - npm --version - node --version - curl --version - git --version - - - name: Install npm Dependencies - run: npm ci - - - name: Run SASS precommit tasks - run: npm run grunt precommit:css - - - name: Run Emoji precommit task - run: npm run grunt precommit:emoji - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Run certificate tasks - run: npm run grunt copy:certificates - - - name: Build WordPress - run: npm run build:dev - - - name: Check for changes to versioned files - id: built-file-check - run: | - if git diff --quiet; then - echo "uncommitted_changes=false" >> "$GITHUB_OUTPUT" - else - echo "uncommitted_changes=true" >> "$GITHUB_OUTPUT" - fi - - - name: Display changes to versioned files - if: ${{ steps.built-file-check.outputs.uncommitted_changes == 'true' }} - run: git diff - - - name: Save diff to a file - if: ${{ steps.built-file-check.outputs.uncommitted_changes == 'true' }} - run: git diff > ./changes.diff - - # Uploads the diff file as an artifact. - - name: Upload diff file as artifact - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - if: ${{ steps.built-file-check.outputs.uncommitted_changes == 'true' }} - with: - name: pr-built-file-changes - path: changes.diff diff --git a/.github/workflows/reusable-test-core-build-process.yml b/.github/workflows/reusable-test-core-build-process.yml index 0fe5dfe6d564b..1a41257418dec 100644 --- a/.github/workflows/reusable-test-core-build-process.yml +++ b/.github/workflows/reusable-test-core-build-process.yml @@ -112,6 +112,10 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Run CSS precommit tasks + if: ${{ inputs.directory == 'src' }} + run: npm run grunt precommit:css + - name: Ensure certificates files are updated if: ${{ inputs.test-certificates }} run: npm run grunt copy:certificates && npm run grunt build:certificates From 728a6053483e9cb7a761eb88ba835f3e4cc0fdcf Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Mon, 17 Aug 2026 13:13:55 +0000 Subject: [PATCH 252/634] Docs: Remove a blank line between `@param` and `@return` in core docblocks. The [https://developer.wordpress.org/coding-standards/inline-documentation-standards/php/ PHP inline documentation standards] place `@return` immediately after the last `@param` tag, with no blank line between them: {{{ /** * Summary. * * @since x.x.x * * @param string $var Description. * @return string Description. */ }}} This corrects 44 docblocks across 33 files in `src/wp-includes` that used a line break between the two tags. Developed in https://github.com/WordPress/wordpress-develop/pull/13063. Props mukesh27, dhruvang21. See #65818, #65860. git-svn-id: https://develop.svn.wordpress.org/trunk@63320 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/block-editor.php | 2 -- src/wp-includes/block-supports/aria-label.php | 1 - src/wp-includes/block-supports/block-style-variations.php | 3 --- src/wp-includes/block-supports/colors.php | 1 - src/wp-includes/block-supports/custom-classname.php | 1 - src/wp-includes/block-supports/settings.php | 1 - src/wp-includes/block-supports/utils.php | 1 - src/wp-includes/block-template-utils.php | 1 - src/wp-includes/block-template.php | 1 - src/wp-includes/blocks.php | 3 --- src/wp-includes/class-wp-block-type.php | 2 -- src/wp-includes/class-wp-term-query.php | 2 -- src/wp-includes/class-wp-textdomain-registry.php | 1 - src/wp-includes/class-wp-theme-json-data.php | 1 - src/wp-includes/class-wp-theme-json-schema.php | 2 -- src/wp-includes/class-wp-token-map.php | 2 -- src/wp-includes/deprecated.php | 1 - src/wp-includes/functions.php | 2 -- src/wp-includes/global-styles-and-settings.php | 1 - src/wp-includes/html-api/class-wp-html-doctype-info.php | 1 - src/wp-includes/html-api/class-wp-html-processor.php | 1 - src/wp-includes/html-api/class-wp-html-tag-processor.php | 1 - src/wp-includes/kses.php | 1 - src/wp-includes/l10n.php | 1 - src/wp-includes/rest-api.php | 1 - src/wp-includes/rest-api/class-wp-rest-server.php | 1 - .../endpoints/class-wp-rest-global-styles-controller.php | 1 - .../rest-api/endpoints/class-wp-rest-menu-items-controller.php | 1 - .../endpoints/class-wp-rest-widget-types-controller.php | 2 -- src/wp-includes/script-loader.php | 1 - src/wp-includes/sitemaps/providers/class-wp-sitemaps-posts.php | 1 - src/wp-includes/theme.php | 1 - src/wp-includes/user.php | 1 - 33 files changed, 44 deletions(-) diff --git a/src/wp-includes/block-editor.php b/src/wp-includes/block-editor.php index f08c934864916..1e6d60f637592 100644 --- a/src/wp-includes/block-editor.php +++ b/src/wp-includes/block-editor.php @@ -109,7 +109,6 @@ function get_block_categories( $post_or_block_editor_context ) { * @since 5.8.0 * * @param WP_Block_Editor_Context $block_editor_context The current block editor context. - * * @return bool|string[] Array of block type slugs, or boolean to enable/disable all. */ function get_allowed_block_types( $block_editor_context ) { @@ -484,7 +483,6 @@ function wp_get_post_content_block_attributes() { * * @param array $custom_settings Custom settings to use with the given editor type. * @param WP_Block_Editor_Context $block_editor_context The current block editor context. - * * @return array The contextualized block editor settings. */ function get_block_editor_settings( array $custom_settings, $block_editor_context ) { diff --git a/src/wp-includes/block-supports/aria-label.php b/src/wp-includes/block-supports/aria-label.php index b51cd3499e0d4..c44333221101a 100644 --- a/src/wp-includes/block-supports/aria-label.php +++ b/src/wp-includes/block-supports/aria-label.php @@ -40,7 +40,6 @@ function wp_register_aria_label_support( $block_type ) { * * @param WP_Block_Type $block_type Block Type. * @param array $block_attributes Block attributes. - * * @return array Block aria-label. */ function wp_apply_aria_label_support( $block_type, $block_attributes ) { diff --git a/src/wp-includes/block-supports/block-style-variations.php b/src/wp-includes/block-supports/block-style-variations.php index 5daccd629c055..a808ea3d74ecf 100644 --- a/src/wp-includes/block-supports/block-style-variations.php +++ b/src/wp-includes/block-supports/block-style-variations.php @@ -13,7 +13,6 @@ * @since 6.6.0 * * @param string $class_string CSS class string to look for a variation in. - * * @return array|null The block style variation name if found. */ function wp_get_block_style_variation_name_from_class( $class_string ) { @@ -75,7 +74,6 @@ function wp_resolve_block_style_variation_ref_values( &$variation_data, $theme_j * @access private * * @param array $parsed_block The parsed block. - * * @return array The parsed block with block style variation classname added. */ function wp_render_block_style_variation_support_styles( $parsed_block ) { @@ -215,7 +213,6 @@ function wp_render_block_style_variation_support_styles( $parsed_block ) { * * @param string $block_content Rendered block content. * @param array $block Block object. - * * @return string Filtered block content. */ function wp_render_block_style_variation_class_name( $block_content, $block ) { diff --git a/src/wp-includes/block-supports/colors.php b/src/wp-includes/block-supports/colors.php index 18da234e55e37..330f32e352b36 100644 --- a/src/wp-includes/block-supports/colors.php +++ b/src/wp-includes/block-supports/colors.php @@ -78,7 +78,6 @@ function wp_register_colors_support( $block_type ) { * * @param WP_Block_Type $block_type Block type. * @param array $block_attributes Block attributes. - * * @return array Colors CSS classes and inline styles. */ function wp_apply_colors_support( $block_type, $block_attributes ) { diff --git a/src/wp-includes/block-supports/custom-classname.php b/src/wp-includes/block-supports/custom-classname.php index 1889918644fc9..3c1215723d30b 100644 --- a/src/wp-includes/block-supports/custom-classname.php +++ b/src/wp-includes/block-supports/custom-classname.php @@ -38,7 +38,6 @@ function wp_register_custom_classname_support( $block_type ) { * * @param WP_Block_Type $block_type Block Type. * @param array $block_attributes Block attributes. - * * @return array Block CSS classes and inline styles. */ function wp_apply_custom_classname_support( $block_type, $block_attributes ) { diff --git a/src/wp-includes/block-supports/settings.php b/src/wp-includes/block-supports/settings.php index 59c3cbd9a28de..2af6f865f76b3 100644 --- a/src/wp-includes/block-supports/settings.php +++ b/src/wp-includes/block-supports/settings.php @@ -71,7 +71,6 @@ function _wp_add_block_level_presets_class( $block_content, $block ) { * * @param string|null $pre_render The pre-rendered content. Default null. * @param array $block The block being rendered. - * * @return null */ function _wp_add_block_level_preset_styles( $pre_render, $block ) { diff --git a/src/wp-includes/block-supports/utils.php b/src/wp-includes/block-supports/utils.php index 7c5d7db48a150..c668586674de4 100644 --- a/src/wp-includes/block-supports/utils.php +++ b/src/wp-includes/block-supports/utils.php @@ -17,7 +17,6 @@ * @param WP_Block_Type $block_type Block type. * @param string $feature_set Name of block support feature set.. * @param string $feature Optional name of individual feature to check. - * * @return bool Whether to serialize block support styles & classes. */ function wp_should_skip_block_supports_serialization( $block_type, $feature_set, $feature = null ) { diff --git a/src/wp-includes/block-template-utils.php b/src/wp-includes/block-template-utils.php index a7d5d4aa1141d..2d23f8545e87f 100644 --- a/src/wp-includes/block-template-utils.php +++ b/src/wp-includes/block-template-utils.php @@ -31,7 +31,6 @@ * @since 5.9.0 * * @param string $theme_stylesheet The stylesheet. Default is to leverage the main theme root. - * * @return string[] { * Folder names used by block themes. * diff --git a/src/wp-includes/block-template.php b/src/wp-includes/block-template.php index 85ad05cfc91ae..8c34b05d016ae 100644 --- a/src/wp-includes/block-template.php +++ b/src/wp-includes/block-template.php @@ -431,7 +431,6 @@ function _strip_template_file_suffix( $template_file ) { * @since 5.8.0 * * @param array $context Default context. - * * @return array Filtered context. */ function _block_template_render_without_post_block_context( $context ) { diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php index f2df7226a6d78..4a048c80baf3e 100644 --- a/src/wp-includes/blocks.php +++ b/src/wp-includes/blocks.php @@ -623,7 +623,6 @@ function register_block_type_from_metadata( $file_or_folder, $args = array() ) { * @param array $attributes Block attributes. * @param string $content Block default content. * @param WP_Block $block Block instance. - * * @return string Returns the block content. */ $settings['render_callback'] = static function ( $attributes, $content, $block ) use ( $template_path ) { @@ -1929,7 +1928,6 @@ function traverse_and_serialize_block( $block, $pre_callback = null, $post_callb * @since 7.0.0 Adds metadata to attributes of single-pattern container blocks. * * @param array $blocks An array blocks. - * * @return array An array of blocks with patterns replaced by their content. */ function resolve_pattern_blocks( $blocks ) { @@ -2814,7 +2812,6 @@ function wp_migrate_old_typography_shape( $metadata ) { * * @param WP_Block $block Block instance. * @param int $page Current query's page. - * * @return array Returns the constructed WP_Query arguments. */ function build_query_vars_from_query_block( $block, $page ) { diff --git a/src/wp-includes/class-wp-block-type.php b/src/wp-includes/class-wp-block-type.php index 86f0ea21a2a3c..d06279879c1f8 100644 --- a/src/wp-includes/class-wp-block-type.php +++ b/src/wp-includes/class-wp-block-type.php @@ -357,7 +357,6 @@ public function __construct( $block_type, $args = array() ) { * @since 6.1.0 * * @param string $name Deprecated property name. - * * @return string|string[]|null The value read from the new property if the first item in the array provided, * null when value not found or when unknown property name provided. */ @@ -393,7 +392,6 @@ public function __get( $name ) { * @since 6.1.0 * * @param string $name Deprecated property name. - * * @return bool Returns true when for the new property the first item in the array exists, * or false otherwise. */ diff --git a/src/wp-includes/class-wp-term-query.php b/src/wp-includes/class-wp-term-query.php index a30d887aa56d1..909da85433a51 100644 --- a/src/wp-includes/class-wp-term-query.php +++ b/src/wp-includes/class-wp-term-query.php @@ -973,7 +973,6 @@ protected function parse_orderby( $orderby_raw ) { * * @param WP_Term[] $term_objects Array of term objects. * @param string $_fields Field to format. - * * @return WP_Term[]|int[]|string[] Array of terms / strings / ints depending on field requested. */ protected function format_terms( $term_objects, $_fields ) { @@ -1156,7 +1155,6 @@ protected function populate_terms( $terms ) { * * @param array $args WP_Term_Query arguments. * @param string $sql SQL statement. - * * @return string Cache key. */ protected function generate_cache_key( array $args, $sql ) { diff --git a/src/wp-includes/class-wp-textdomain-registry.php b/src/wp-includes/class-wp-textdomain-registry.php index bb2135e3650a2..c62e751b6e47b 100644 --- a/src/wp-includes/class-wp-textdomain-registry.php +++ b/src/wp-includes/class-wp-textdomain-registry.php @@ -87,7 +87,6 @@ public function init() { * * @param string $domain Text domain. * @param string $locale Locale. - * * @return string|false Languages directory path or false if there is none available. */ public function get( $domain, $locale ) { diff --git a/src/wp-includes/class-wp-theme-json-data.php b/src/wp-includes/class-wp-theme-json-data.php index 9a9e73ecffdbf..a1bf64b1d8232 100644 --- a/src/wp-includes/class-wp-theme-json-data.php +++ b/src/wp-includes/class-wp-theme-json-data.php @@ -50,7 +50,6 @@ public function __construct( $data = array( 'version' => WP_Theme_JSON::LATEST_S * @since 6.1.0 * * @param array $new_data Array following the theme.json specification. - * * @return WP_Theme_JSON_Data The own instance with access to the modified data. */ public function update_with( $new_data ) { diff --git a/src/wp-includes/class-wp-theme-json-schema.php b/src/wp-includes/class-wp-theme-json-schema.php index aaa2f968a6395..47c0f016ec3f3 100644 --- a/src/wp-includes/class-wp-theme-json-schema.php +++ b/src/wp-includes/class-wp-theme-json-schema.php @@ -73,7 +73,6 @@ public static function migrate( $theme_json, $origin = 'theme' ) { * @since 5.9.0 * * @param array $old Data to migrate. - * * @return array Data without the custom prefixes. */ private static function migrate_v1_to_v2( $old ) { @@ -169,7 +168,6 @@ private static function migrate_v2_to_v3( $old, $origin ) { * * @param array $settings Array to process. * @param array $paths_to_rename Paths to rename. - * * @return array The settings in the new format. */ private static function rename_paths( $settings, $paths_to_rename ) { diff --git a/src/wp-includes/class-wp-token-map.php b/src/wp-includes/class-wp-token-map.php index fc223b187f8c5..317a9830cba85 100644 --- a/src/wp-includes/class-wp-token-map.php +++ b/src/wp-includes/class-wp-token-map.php @@ -528,7 +528,6 @@ public function contains( string $word, string $case_sensitivity = 'case-sensiti * @param int $offset Optional. How many bytes into the string where the lookup key ought to start. Default 0. * @param int|null &$matched_token_byte_length Optional. Holds byte-length of found token matched, otherwise not set. Default null. * @param string $case_sensitivity Optional. Pass 'ascii-case-insensitive' to ignore ASCII case when matching. Default 'case-sensitive'. - * * @return string|null Mapped value of lookup key if found, otherwise `null`. */ public function read_token( string $text, int $offset = 0, &$matched_token_byte_length = null, $case_sensitivity = 'case-sensitive' ): ?string { @@ -589,7 +588,6 @@ public function read_token( string $text, int $offset = 0, &$matched_token_byte_ * @param int $offset Optional. How many bytes into the string where the lookup key ought to start. Default 0. * @param int|null &$matched_token_byte_length Optional. Holds byte-length of found lookup key if matched, otherwise not set. Default null. * @param string $case_sensitivity Optional. Pass 'ascii-case-insensitive' to ignore ASCII case when matching. Default 'case-sensitive'. - * * @return string|null Mapped value of lookup key if found, otherwise `null`. */ private function read_small_token( string $text, int $offset = 0, &$matched_token_byte_length = null, $case_sensitivity = 'case-sensitive' ): ?string { diff --git a/src/wp-includes/deprecated.php b/src/wp-includes/deprecated.php index 14f5c24aec914..3b78d1610fdad 100644 --- a/src/wp-includes/deprecated.php +++ b/src/wp-includes/deprecated.php @@ -6394,7 +6394,6 @@ function wp_enqueue_global_styles_custom_css() { * * @param array $block Block object. * @param string $variation Slug for the block style variation. - * * @return string The unique variation name. */ function wp_create_block_style_variation_instance_name( $block, $variation ) { diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index 5d84c0eeb32d5..a60bb57df7178 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -5300,7 +5300,6 @@ function _wp_array_set( &$input_array, $path, $value = null ) { * @link https://github.com/lodash-php/lodash-php/blob/master/src/internal/unicodeWords.php * * @param string $input_string The string to kebab-case. - * * @return string kebab-cased-string. */ function _wp_to_kebab_case( $input_string ) { @@ -8721,7 +8720,6 @@ function wp_get_default_update_php_url() { * @param string $before Markup to output before the annotation. Default `

`. * @param string $after Markup to output after the annotation. Default `

`. * @param bool $display Whether to echo or return the markup. Default `true` for echo. - * * @return string|null Update PHP page annotation if available and $display is false, null otherwise. */ function wp_update_php_annotation( $before = '

', $after = '

', $display = true ) { diff --git a/src/wp-includes/global-styles-and-settings.php b/src/wp-includes/global-styles-and-settings.php index 4b08301f9c7db..0534d8b0dee58 100644 --- a/src/wp-includes/global-styles-and-settings.php +++ b/src/wp-includes/global-styles-and-settings.php @@ -498,7 +498,6 @@ function wp_get_theme_data_template_parts() { * @param WP_Block_Type $block_type The block's type. * @param string|array $target The desired selector's target, `root` or array path. * @param boolean $fallback Whether to fall back to broader selector. - * * @return string|null CSS selector or `null` if no selector available. */ function wp_get_block_css_selector( $block_type, $target = 'root', $fallback = false ) { diff --git a/src/wp-includes/html-api/class-wp-html-doctype-info.php b/src/wp-includes/html-api/class-wp-html-doctype-info.php index f448aabde3ad9..ce6004a940cf3 100644 --- a/src/wp-includes/html-api/class-wp-html-doctype-info.php +++ b/src/wp-includes/html-api/class-wp-html-doctype-info.php @@ -410,7 +410,6 @@ private function __construct( * @since 6.7.0 * * @param string $doctype_html The complete raw DOCTYPE HTML string, e.g. ``. - * * @return WP_HTML_Doctype_Info|null A WP_HTML_Doctype_Info instance will be returned if the * provided DOCTYPE HTML is a valid DOCTYPE. Otherwise, null. */ diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index b4c590ef5141a..9e18d0e9b7121 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -1267,7 +1267,6 @@ public function get_current_depth(): int { * @since 6.7.0 * * @param string $html Input HTML to normalize. - * * @return string|null Normalized output, or `null` if unable to normalize. */ public static function normalize( string $html ): ?string { diff --git a/src/wp-includes/html-api/class-wp-html-tag-processor.php b/src/wp-includes/html-api/class-wp-html-tag-processor.php index dd99a8324b5c6..88487fb068d11 100644 --- a/src/wp-includes/html-api/class-wp-html-tag-processor.php +++ b/src/wp-includes/html-api/class-wp-html-tag-processor.php @@ -3233,7 +3233,6 @@ public function get_qualified_tag_name(): ?string { * @since 6.7.0 * * @param string $attribute_name Which attribute to adjust. - * * @return string|null */ public function get_qualified_attribute_name( $attribute_name ): ?string { diff --git a/src/wp-includes/kses.php b/src/wp-includes/kses.php index 9cd0f50f22487..9394b75989912 100644 --- a/src/wp-includes/kses.php +++ b/src/wp-includes/kses.php @@ -1390,7 +1390,6 @@ function _wp_kses_split_callback( $matches ) { * or a context name such as 'post'. See wp_kses_allowed_html() * for the list of accepted context names. * @param string[] $allowed_protocols Array of allowed URL protocols. - * * @return string Fixed HTML element */ function wp_kses_split2( $content, $allowed_html, $allowed_protocols ) { diff --git a/src/wp-includes/l10n.php b/src/wp-includes/l10n.php index 43b32017becac..0f9dd0d4016a0 100644 --- a/src/wp-includes/l10n.php +++ b/src/wp-includes/l10n.php @@ -1993,7 +1993,6 @@ function is_locale_switched() { * @param string|string[]|array[]|object $i18n_schema I18n schema for the setting. * @param string|string[]|array[] $settings Value for the settings. * @param string $textdomain Textdomain to use with translations. - * * @return string|string[]|array[] Translated settings. */ function translate_settings_using_i18n_schema( $i18n_schema, $settings, $textdomain ) { diff --git a/src/wp-includes/rest-api.php b/src/wp-includes/rest-api.php index d54cee18c5b39..892716b5d69e0 100644 --- a/src/wp-includes/rest-api.php +++ b/src/wp-includes/rest-api.php @@ -3458,7 +3458,6 @@ function rest_get_endpoint_args_for_schema( $schema, $method = WP_REST_Server::C * @since 5.7.0 * * @param WP_Error $error WP_Error instance. - * * @return WP_REST_Response List of associative arrays with code and message keys. */ function rest_convert_error_to_response( $error ) { diff --git a/src/wp-includes/rest-api/class-wp-rest-server.php b/src/wp-includes/rest-api/class-wp-rest-server.php index c331d73363541..c7ffb5b7677d0 100644 --- a/src/wp-includes/rest-api/class-wp-rest-server.php +++ b/src/wp-includes/rest-api/class-wp-rest-server.php @@ -245,7 +245,6 @@ protected function json_error( $code, $message, $status = null ) { * @since 6.1.0 * * @param \WP_REST_Request $request The current request object. - * * @return int The JSON encode options. */ protected function get_json_encode_options( WP_REST_Request $request ) { diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php index e8e81c3617fc4..ed8195cbb91b7 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php @@ -626,7 +626,6 @@ public function get_theme_items_permissions_check( $request ) { * @since 6.6.0 Added custom relative theme file URIs to `_links` for each item. * * @param WP_REST_Request $request The request instance. - * * @return WP_REST_Response|WP_Error */ public function get_theme_items( $request ) { diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-menu-items-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-menu-items-controller.php index dd72bc1c15210..396d657fd2546 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-menu-items-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-menu-items-controller.php @@ -337,7 +337,6 @@ public function delete_item( $request ) { * @since 5.9.0 * * @param WP_REST_Request $request Request object. - * * @return object|WP_Error */ protected function prepare_item_for_database( $request ) { diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-widget-types-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-widget-types-controller.php index 1d07c27251c3b..a36fe356e9070 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-widget-types-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-widget-types-controller.php @@ -604,7 +604,6 @@ private function get_widget_form( $widget_object, $instance ) { * @since 5.9.0 * * @param WP_REST_Request $request Full details about the request. - * * @return array An array with rendered Legacy Widget HTML. */ public function render( $request ) { @@ -623,7 +622,6 @@ public function render( $request ) { * * @param string $id_base The id base of the requested widget. * @param array $instance The widget instance attributes. - * * @return string Rendered Legacy Widget block preview. */ private function render_legacy_widget_preview_iframe( $id_base, $instance ) { diff --git a/src/wp-includes/script-loader.php b/src/wp-includes/script-loader.php index a364439f0abbb..7d5ba24e5617d 100644 --- a/src/wp-includes/script-loader.php +++ b/src/wp-includes/script-loader.php @@ -3212,7 +3212,6 @@ static function ( $a, $b ) { * * @param string $css The CSS to make URLs relative to the WordPress installation. * @param string $stylesheet_url The URL to the stylesheet. - * * @return string The CSS with URLs made relative to the WordPress installation. */ function _wp_normalize_relative_css_links( $css, $stylesheet_url ) { diff --git a/src/wp-includes/sitemaps/providers/class-wp-sitemaps-posts.php b/src/wp-includes/sitemaps/providers/class-wp-sitemaps-posts.php index 7436f5ff0083b..95bd10c5e4947 100644 --- a/src/wp-includes/sitemaps/providers/class-wp-sitemaps-posts.php +++ b/src/wp-includes/sitemaps/providers/class-wp-sitemaps-posts.php @@ -58,7 +58,6 @@ public function get_object_subtypes() { * * @param int $page_num Page of results. * @param string $object_subtype Optional. Post type name. Default empty. - * * @return array[] Array of URL information for a sitemap. */ public function get_url_list( $page_num, $object_subtype = '' ) { diff --git a/src/wp-includes/theme.php b/src/wp-includes/theme.php index 07869ae61d0ff..3262ebde134f2 100644 --- a/src/wp-includes/theme.php +++ b/src/wp-includes/theme.php @@ -4369,7 +4369,6 @@ function wp_is_block_theme() { * @since 6.1.0 * * @param string $element The name of the element. - * * @return string The name of the class. */ function wp_theme_get_element_class_name( $element ) { diff --git a/src/wp-includes/user.php b/src/wp-includes/user.php index 539240a42e9d2..1a1ce8359ccbe 100644 --- a/src/wp-includes/user.php +++ b/src/wp-includes/user.php @@ -853,7 +853,6 @@ function delete_user_option( $user_id, $option_name, $is_global = false ) { * @since 6.7.0 * * @param int $user_id User ID. - * * @return WP_User|false WP_User object on success, false on failure. */ function get_user( $user_id ) { From a554ae14aeef4b9f1b7c2f494d932754d706e445 Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Tue, 18 Aug 2026 11:44:01 +0000 Subject: [PATCH 253/634] Docs: Add missing descriptions and declare types for `Translation_Entry` properties. Developed in https://github.com/WordPress/wordpress-develop/pull/13126. Follow-up to r10584, r32990, r57734. Props pedromendonca, mukesh27, dhruvang21. Fixes #65901. git-svn-id: https://develop.svn.wordpress.org/trunk@63323 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/pomo/entry.php | 99 ++++++++++++++++++++++++++-------- 1 file changed, 77 insertions(+), 22 deletions(-) diff --git a/src/wp-includes/pomo/entry.php b/src/wp-includes/pomo/entry.php index e1b1c8f8c86a7..b7b0cf389d595 100644 --- a/src/wp-includes/pomo/entry.php +++ b/src/wp-includes/pomo/entry.php @@ -23,32 +23,85 @@ class Translation_Entry { */ public $is_plural = false; - public $context = null; - public $singular = null; - public $plural = null; - public $translations = array(); + /** + * The string to translate. + * + * @var string|null + */ + public $singular = null; + + /** + * The plural form of the string. + * + * @var string|null + */ + public $plural = null; + + /** + * Translations of the string and possibly its plural forms. + * + * Plural forms which have not been filled in are null. + * + * @var (string|null)[] + */ + public $translations = array(); + + /** + * Context of the string, used to differentiate two equal strings used in different contexts. + * + * @var string|null + */ + public $context = null; + + /** + * Comments left by translators. + * + * @var string + */ public $translator_comments = ''; - public $extracted_comments = ''; - public $references = array(); - public $flags = array(); /** + * Comments left by developers. + * + * @var string + */ + public $extracted_comments = ''; + + /** + * Places in the code this string is used, in relative_to_root_path/file.php:linenum form. + * + * @var string[] + */ + public $references = array(); + + /** + * Flags like php-format. + * + * @var string[] + */ + public $flags = array(); + + /** + * Constructor. + * + * @since 2.8.0 + * * @param array $args { - * Arguments array, supports the following keys: - * - * @type string $singular The string to translate, if omitted an - * empty entry will be created. - * @type string $plural The plural form of the string, setting - * this will set `$is_plural` to true. - * @type array $translations Translations of the string and possibly - * its plural forms. - * @type string $context A string differentiating two equal strings - * used in different contexts. - * @type string $translator_comments Comments left by translators. - * @type string $extracted_comments Comments left by developers. - * @type array $references Places in the code this string is used, in - * relative_to_root_path/file.php:linenum form. - * @type array $flags Flags like php-format. + * Optional. Array of arguments. Default empty array. + * + * @type string $singular The string to translate, if omitted an + * empty entry will be created. + * @type string $plural The plural form of the string, setting + * this will set `$is_plural` to true. + * @type (string|null)[] $translations Translations of the string and possibly + * its plural forms. + * @type string $context A string differentiating two equal strings + * used in different contexts. + * @type string $translator_comments Comments left by translators. + * @type string $extracted_comments Comments left by developers. + * @type string[] $references Places in the code this string is used, in + * relative_to_root_path/file.php:linenum form. + * @type string[] $flags Flags like php-format. * } */ public function __construct( $args = array() ) { @@ -81,6 +134,8 @@ public function __construct( $args = array() ) { * @deprecated 5.4.0 Use __construct() instead. * * @see Translation_Entry::__construct() + * + * @param array $args Optional. Array of arguments. Default empty array. */ public function Translation_Entry( $args = array() ) { _deprecated_constructor( self::class, '5.4.0', static::class ); From 8b91cc16cc78b817386b406f50ced8df86fb466d Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Thu, 20 Aug 2026 00:26:53 +0000 Subject: [PATCH 254/634] Build/Test Tools: Test 7.1 in upgrade testing workflows. This sets 7.1 as the most recent branch of WordPress in the upgrade testing workflows. See #65845, #65844. git-svn-id: https://develop.svn.wordpress.org/trunk@63327 602fd350-edb4-49c9-b593-d223f7449a82 --- .github/workflows/upgrade-develop-testing.yml | 4 ++-- .github/workflows/upgrade-testing.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/upgrade-develop-testing.yml b/.github/workflows/upgrade-develop-testing.yml index 4147d3f054b8b..a01e5239fac17 100644 --- a/.github/workflows/upgrade-develop-testing.yml +++ b/.github/workflows/upgrade-develop-testing.yml @@ -81,7 +81,7 @@ jobs: db-type: [ 'mysql' ] db-version: [ '5.7', '8.4' ] # WordPress 5.3 is the oldest version that supports PHP 7.4. - wp: [ '5.3', '6.9', '7.0', '7.1-RC2' ] + wp: [ '5.3', '7.0', '7.1' ] multisite: [ false, true ] with: os: ${{ matrix.os }} @@ -114,7 +114,7 @@ jobs: php: [ '7.4', '8.4' ] db-type: [ 'mysql' ] db-version: [ '8.4' ] - wp: [ '6.9', '7.0', '7.1-RC2' ] + wp: [ '7.0', '7.1' ] multisite: [ false, true ] with: os: ${{ matrix.os }} diff --git a/.github/workflows/upgrade-testing.yml b/.github/workflows/upgrade-testing.yml index 0d89c062f3b3b..ba82f96a7b779 100644 --- a/.github/workflows/upgrade-testing.yml +++ b/.github/workflows/upgrade-testing.yml @@ -71,7 +71,7 @@ jobs: php: [ '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5' ] db-type: [ 'mysql' ] db-version: [ '5.7', '8.0', '8.4', '9.7' ] - wp: [ '6.9', '7.0', '7.1-RC2' ] + wp: [ '7.0', '7.1' ] multisite: [ false, true ] with: os: ${{ matrix.os }} From 13aa7ebbf38131fb2106ce91ea20ae4dbbbde8bd Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 20 Aug 2026 21:23:53 +0000 Subject: [PATCH 255/634] Code Quality: Delete empty return.empty.neon PHPStan baseline file. Follow-up to r63314. See #65817. git-svn-id: https://develop.svn.wordpress.org/trunk@63328 602fd350-edb4-49c9-b593-d223f7449a82 --- tests/phpstan/baselines/return.empty.neon | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tests/phpstan/baselines/return.empty.neon diff --git a/tests/phpstan/baselines/return.empty.neon b/tests/phpstan/baselines/return.empty.neon deleted file mode 100644 index e69de29bb2d1d..0000000000000 From a51a237182397be2abb53e694de62535c1daacb9 Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Fri, 21 Aug 2026 03:27:16 +0000 Subject: [PATCH 256/634] Help/About: Update heading string to use placeholder. Updates the "Welcome to WordPress X.X" heading to use a placeholder for the version number to ease l10n efforts with a reusable string across each version of WordPress. Props nekojonez, khokansardar, mukesh27, SergeyBiryukov. Fixes #65895. git-svn-id: https://develop.svn.wordpress.org/trunk@63329 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/about.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/wp-admin/about.php b/src/wp-admin/about.php index 9091ca6ec958c..1bfc3018e0556 100644 --- a/src/wp-admin/about.php +++ b/src/wp-admin/about.php @@ -60,7 +60,15 @@
-

+

+ +

From 497de8c1e6d8de51371e510ad4edf39145d4586f Mon Sep 17 00:00:00 2001 From: ramonopoly Date: Fri, 21 Aug 2026 05:42:32 +0000 Subject: [PATCH 257/634] Block Supports: guard against non-string attribute values to avoid fatal errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit guards layout block supports values with type checks before render. The reason is that `block.json` / `theme.json` types aren't enforced at render time, so wrong-typed values can reach strict PHP checks and cause fatals. The cause is mainly hand-edited, imported, or AI-generated serialized content, not the block editor. Developed in: https://github.com/WordPress/wordpress-develop/pull/12674 Props im3dabasia1, ramonopoly, westonruter. Fixes #65774. git-svn-id: https://develop.svn.wordpress.org/trunk@63330 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/block-supports/layout.php | 97 ++++--- tests/phpunit/tests/block-supports/layout.php | 237 ++++++++++++++++++ 2 files changed, 302 insertions(+), 32 deletions(-) diff --git a/src/wp-includes/block-supports/layout.php b/src/wp-includes/block-supports/layout.php index 3be4f07b055ea..deef7ae61e495 100644 --- a/src/wp-includes/block-supports/layout.php +++ b/src/wp-includes/block-supports/layout.php @@ -159,8 +159,17 @@ function wp_get_child_layout_style_rules( $selector, $child_layout, $parent_layo } } - $column_start = $child_layout['columnStart'] ?? null; - $column_span = $child_layout['columnSpan'] ?? null; + /* + * Grid line numbers and spans are whole numbers. The editor stores them as numbers, but + * content saved by WordPress 6.3 to 6.6 stored them as numeric strings, and that + * migration only runs when a block is parsed in JavaScript, so the front end still sees + * strings. Accept any numeric value and cast it, and treat anything else as absent + * because it can't render as valid CSS. + */ + $column_start_attr = $child_layout['columnStart'] ?? null; + $column_start = is_numeric( $column_start_attr ) ? (int) $column_start_attr : null; + $column_span_attr = $child_layout['columnSpan'] ?? null; + $column_span = is_numeric( $column_span_attr ) ? (int) $column_span_attr : null; if ( null === $viewport_overrides || $has_viewport_property_override( 'columnStart' ) || $has_viewport_property_override( 'columnSpan' ) ) { if ( $column_start && $column_span ) { $child_layout_declarations['grid-column'] = "$column_start / span $column_span"; @@ -171,8 +180,10 @@ function wp_get_child_layout_style_rules( $selector, $child_layout, $parent_layo } } - $row_start = $child_layout['rowStart'] ?? null; - $row_span = $child_layout['rowSpan'] ?? null; + $row_start_attr = $child_layout['rowStart'] ?? null; + $row_start = is_numeric( $row_start_attr ) ? (int) $row_start_attr : null; + $row_span_attr = $child_layout['rowSpan'] ?? null; + $row_span = is_numeric( $row_span_attr ) ? (int) $row_span_attr : null; if ( null === $viewport_overrides || $has_viewport_property_override( 'rowStart' ) || $has_viewport_property_override( 'rowSpan' ) ) { if ( $row_start && $row_span ) { $child_layout_declarations['grid-row'] = "$row_start / span $row_span"; @@ -190,8 +201,9 @@ function wp_get_child_layout_style_rules( $selector, $child_layout, $parent_layo ); } - $minimum_column_width = $parent_layout['minimumColumnWidth'] ?? null; - $column_count = $parent_layout['columnCount'] ?? null; + $minimum_column_width_attr = $parent_layout['minimumColumnWidth'] ?? null; + $minimum_column_width = is_string( $minimum_column_width_attr ) ? $minimum_column_width_attr : null; + $column_count = $parent_layout['columnCount'] ?? null; /* * If columnSpan or columnStart is set, and the parent grid is responsive, i.e. if it has a minimumColumnWidth set, @@ -548,9 +560,14 @@ function wp_get_layout_style( $selector, $layout, $has_block_gap_support = false } } } elseif ( 'constrained' === $layout_type ) { - $content_size = $layout_for_styles['contentSize'] ?? ''; - $wide_size = $layout_for_styles['wideSize'] ?? ''; - $justify_content = $layout_for_styles['justifyContent'] ?? 'center'; + // The schemas and editor UI only produce strings here, so treat a non-string + // value as absent rather than casting it — it couldn't render as valid CSS anyway. + $content_size_attr = $layout_for_styles['contentSize'] ?? null; + $content_size = is_string( $content_size_attr ) ? $content_size_attr : ''; + $wide_size_attr = $layout_for_styles['wideSize'] ?? null; + $wide_size = is_string( $wide_size_attr ) ? $wide_size_attr : ''; + $justify_content_attr = $layout_for_styles['justifyContent'] ?? null; + $justify_content = is_string( $justify_content_attr ) ? $justify_content_attr : 'center'; // Check if viewport-specific ("override") values exist. Null values are valid and mean the user cleared a value inherited from the default viewport. $has_justify_content_override = null !== $viewport_overrides && $has_viewport_property_override( 'justifyContent' ); @@ -771,23 +788,26 @@ function wp_get_layout_style( $selector, $layout, $has_block_gap_support = false } } + $flex_justify_content = $layout_for_styles['justifyContent'] ?? null; + $flex_vertical_alignment = $layout_for_styles['verticalAlignment'] ?? null; + if ( 'horizontal' === $layout_orientation ) { /* * Add this style only if is not empty for backwards compatibility, * since we intend to convert blocks that had flex layout implemented * by custom css. */ - if ( $should_output_flex_justification && ! empty( $layout_for_styles['justifyContent'] ) && array_key_exists( $layout_for_styles['justifyContent'], $justify_content_options ) ) { + if ( $should_output_flex_justification && ! empty( $flex_justify_content ) && is_string( $flex_justify_content ) && array_key_exists( $flex_justify_content, $justify_content_options ) ) { $layout_styles[] = array( 'selector' => $selector, - 'declarations' => array( 'justify-content' => $justify_content_options[ $layout_for_styles['justifyContent'] ] ), + 'declarations' => array( 'justify-content' => $justify_content_options[ $flex_justify_content ] ), ); } - if ( $should_output_flex_alignment && ! empty( $layout_for_styles['verticalAlignment'] ) && array_key_exists( $layout_for_styles['verticalAlignment'], $vertical_alignment_options ) ) { + if ( $should_output_flex_alignment && ! empty( $flex_vertical_alignment ) && is_string( $flex_vertical_alignment ) && array_key_exists( $flex_vertical_alignment, $vertical_alignment_options ) ) { $layout_styles[] = array( 'selector' => $selector, - 'declarations' => array( 'align-items' => $vertical_alignment_options[ $layout_for_styles['verticalAlignment'] ] ), + 'declarations' => array( 'align-items' => $vertical_alignment_options[ $flex_vertical_alignment ] ), ); } } else { @@ -797,10 +817,10 @@ function wp_get_layout_style( $selector, $layout, $has_block_gap_support = false 'declarations' => array( 'flex-direction' => 'column' ), ); } - if ( $should_output_flex_justification && ! empty( $layout_for_styles['justifyContent'] ) && array_key_exists( $layout_for_styles['justifyContent'], $justify_content_options ) ) { + if ( $should_output_flex_justification && ! empty( $flex_justify_content ) && is_string( $flex_justify_content ) && array_key_exists( $flex_justify_content, $justify_content_options ) ) { $layout_styles[] = array( 'selector' => $selector, - 'declarations' => array( 'align-items' => $justify_content_options[ $layout_for_styles['justifyContent'] ] ), + 'declarations' => array( 'align-items' => $justify_content_options[ $flex_justify_content ] ), ); } elseif ( $should_output_flex_justification ) { $layout_styles[] = array( @@ -808,14 +828,23 @@ function wp_get_layout_style( $selector, $layout, $has_block_gap_support = false 'declarations' => array( 'align-items' => 'flex-start' ), ); } - if ( $should_output_flex_alignment && ! empty( $layout_for_styles['verticalAlignment'] ) && array_key_exists( $layout_for_styles['verticalAlignment'], $vertical_alignment_options ) ) { + if ( $should_output_flex_alignment && ! empty( $flex_vertical_alignment ) && is_string( $flex_vertical_alignment ) && array_key_exists( $flex_vertical_alignment, $vertical_alignment_options ) ) { $layout_styles[] = array( 'selector' => $selector, - 'declarations' => array( 'justify-content' => $vertical_alignment_options[ $layout_for_styles['verticalAlignment'] ] ), + 'declarations' => array( 'justify-content' => $vertical_alignment_options[ $flex_vertical_alignment ] ), ); } } } elseif ( 'grid' === $layout_type ) { + /* + * Column and row counts are whole numbers, for the same reason as the grid line + * numbers in wp_get_child_layout_style_rules(). + */ + $column_count_attr = $layout_for_styles['columnCount'] ?? null; + $column_count = is_numeric( $column_count_attr ) ? (int) $column_count_attr : null; + $row_count_attr = $layout_for_styles['rowCount'] ?? null; + $row_count = is_numeric( $row_count_attr ) ? (int) $row_count_attr : null; + /* * If the gap value is an array, we use the "left" value because it represents the vertical gap, which * is the relevant one for computation of responsive grid columns. @@ -862,12 +891,12 @@ function wp_get_layout_style( $selector, $layout, $has_block_gap_support = false * value for any of the grid properties. */ $should_output_grid_columns = null === $viewport_overrides || $has_viewport_property_override( 'minimumColumnWidth' ) || $has_viewport_property_override( 'columnCount' ) || $has_viewport_property_override( 'autoFit' ); - $uses_gap_in_grid_columns = ! empty( $layout_for_styles['columnCount'] ) && ! empty( $layout_for_styles['minimumColumnWidth'] ); + $uses_gap_in_grid_columns = ! empty( $column_count ) && ! empty( $layout_for_styles['minimumColumnWidth'] ); if ( $has_block_gap_override && $uses_gap_in_grid_columns ) { $should_output_grid_columns = true; } - $should_output_grid_rows = ( null === $viewport_overrides || $has_viewport_property_override( 'rowCount' ) ) && ! empty( $layout_for_styles['columnCount'] ) && ! empty( $layout_for_styles['rowCount'] ); + $should_output_grid_rows = ( null === $viewport_overrides || $has_viewport_property_override( 'rowCount' ) ) && ! empty( $column_count ) && ! empty( $row_count ); $grid_declarations = array(); /* @@ -876,11 +905,11 @@ function wp_get_layout_style( $selector, $layout, $has_block_gap_support = false */ $auto_placement = ! empty( $layout_for_styles['autoFit'] ) ? 'auto-fit' : 'auto-fill'; - if ( $should_output_grid_columns && ! empty( $layout_for_styles['columnCount'] ) && ! empty( $layout_for_styles['minimumColumnWidth'] ) ) { - $max_value = 'max(min(' . $layout_for_styles['minimumColumnWidth'] . ', 100%), (100% - (' . $responsive_gap_value . ' * (' . $layout_for_styles['columnCount'] . ' - 1))) /' . $layout_for_styles['columnCount'] . ')'; + if ( $should_output_grid_columns && ! empty( $column_count ) && ! empty( $layout_for_styles['minimumColumnWidth'] ) ) { + $max_value = 'max(min(' . $layout_for_styles['minimumColumnWidth'] . ', 100%), (100% - (' . $responsive_gap_value . ' * (' . $column_count . ' - 1))) /' . $column_count . ')'; $grid_declarations['grid-template-columns'] = 'repeat(' . $auto_placement . ', minmax(' . $max_value . ', 1fr))'; - } elseif ( $should_output_grid_columns && ! empty( $layout_for_styles['columnCount'] ) ) { - $grid_declarations['grid-template-columns'] = 'repeat(' . $layout_for_styles['columnCount'] . ', minmax(0, 1fr))'; + } elseif ( $should_output_grid_columns && ! empty( $column_count ) ) { + $grid_declarations['grid-template-columns'] = 'repeat(' . $column_count . ', minmax(0, 1fr))'; } elseif ( $should_output_grid_columns ) { $minimum_column_width = ! empty( $layout_for_styles['minimumColumnWidth'] ) ? $layout_for_styles['minimumColumnWidth'] : '12rem'; $grid_declarations['grid-template-columns'] = 'repeat(' . $auto_placement . ', minmax(min(' . $minimum_column_width . ', 100%), 1fr))'; @@ -888,7 +917,7 @@ function wp_get_layout_style( $selector, $layout, $has_block_gap_support = false if ( ! empty( $grid_declarations ) ) { $base_has_container_type = empty( $base_layout['columnCount'] ) || ( ! empty( $base_layout['columnCount'] ) && ! empty( $base_layout['minimumColumnWidth'] ) ); - if ( empty( $layout_for_styles['columnCount'] ) || ! empty( $layout_for_styles['minimumColumnWidth'] ) ) { + if ( empty( $column_count ) || ! empty( $layout_for_styles['minimumColumnWidth'] ) ) { if ( null === $viewport_overrides || ! $base_has_container_type ) { $grid_declarations['container-type'] = 'inline-size'; } @@ -902,7 +931,7 @@ function wp_get_layout_style( $selector, $layout, $has_block_gap_support = false if ( $should_output_grid_rows ) { $layout_styles[] = array( 'selector' => $selector, - 'declarations' => array( 'grid-template-rows' => 'repeat(' . $layout_for_styles['rowCount'] . ', minmax(1rem, auto))' ), + 'declarations' => array( 'grid-template-rows' => 'repeat(' . $row_count . ', minmax(1rem, auto))' ), ); } @@ -1123,20 +1152,23 @@ function wp_render_layout_support_flag( $block_content, $block ) { * not intended to provide an extended set of classes to match all block layout attributes * here. */ - if ( ! empty( $block['attrs']['layout']['orientation'] ) ) { - $class_names[] = 'is-' . sanitize_title( $block['attrs']['layout']['orientation'] ); + $orientation = $block['attrs']['layout']['orientation'] ?? null; + if ( ! empty( $orientation ) && is_string( $orientation ) ) { + $class_names[] = 'is-' . sanitize_title( $orientation ); } - if ( ! empty( $block['attrs']['layout']['justifyContent'] ) ) { - $class_names[] = 'is-content-justification-' . sanitize_title( $block['attrs']['layout']['justifyContent'] ); + $justify_content = $block['attrs']['layout']['justifyContent'] ?? null; + if ( ! empty( $justify_content ) && is_string( $justify_content ) ) { + $class_names[] = 'is-content-justification-' . sanitize_title( $justify_content ); } - if ( ! empty( $block['attrs']['layout']['flexWrap'] ) && 'nowrap' === $block['attrs']['layout']['flexWrap'] ) { + $flex_wrap = $block['attrs']['layout']['flexWrap'] ?? null; + if ( ! empty( $flex_wrap ) && 'nowrap' === $flex_wrap ) { $class_names[] = 'is-nowrap'; } // Get classname for layout type. - if ( isset( $used_layout['type'] ) ) { + if ( isset( $used_layout['type'] ) && is_string( $used_layout['type'] ) ) { $layout_classname = $layout_definitions[ $used_layout['type'] ]['className'] ?? ''; } else { $layout_classname = $layout_definitions['default']['className'] ?? ''; @@ -1463,7 +1495,8 @@ function wp_add_parent_layout_to_parsed_block( $parsed_block, $source_block, $pa * @return string Filtered block content. */ function wp_restore_group_inner_container( $block_content, $block ) { - $tag_name = $block['attrs']['tagName'] ?? 'div'; + $tag_name_attr = $block['attrs']['tagName'] ?? null; + $tag_name = is_string( $tag_name_attr ) ? $tag_name_attr : 'div'; $group_with_inner_container_regex = sprintf( '/(^\s*<%1$s\b[^>]*wp-block-group(\s|")[^>]*>)(\s*]*wp-block-group__inner-container(\s|")[^>]*>)((.|\S|\s)*)/U', preg_quote( $tag_name, '/' ) diff --git a/tests/phpunit/tests/block-supports/layout.php b/tests/phpunit/tests/block-supports/layout.php index 7ad00f7cc364c..5e8ab83041a29 100644 --- a/tests/phpunit/tests/block-supports/layout.php +++ b/tests/phpunit/tests/block-supports/layout.php @@ -1188,4 +1188,241 @@ static function ( $theme_json ) use ( &$user_data_resolutions ) { 'Global settings should still be resolved for a block that supports layout.' ); } + + /** + * Tests that a constrained layout with non-string contentSize/wideSize/justifyContent + * values (e.g. from hand-edited, imported, or AI-generated content) does not cause a + * fatal error in the explode() calls. + * + * @ticket 65774 + * @covers ::wp_get_layout_style + */ + public function test_wp_get_layout_style_with_non_string_constrained_sizes() { + $layout_styles = wp_get_layout_style( + '.wp-layout', + array( + 'type' => 'constrained', + 'contentSize' => array( '800px' ), + 'wideSize' => array( '1200px' ), + 'justifyContent' => array( 'center' ), + ) + ); + + $this->assertIsString( $layout_styles, 'Constrained layout should not fatal when sizes are not strings.' ); + $this->assertStringNotContainsString( 'Array', $layout_styles, 'A non-string size value should not leak into the output.' ); + } + + /** + * Tests that a flex layout with non-string justifyContent/verticalAlignment values + * does not cause a fatal error in the array_key_exists() calls. + * + * @ticket 65774 + * @covers ::wp_get_layout_style + */ + public function test_wp_get_layout_style_with_non_string_flex_alignment() { + $layout_styles = wp_get_layout_style( + '.wp-layout', + array( + 'type' => 'flex', + 'orientation' => 'horizontal', + 'justifyContent' => array( 'right' ), + 'verticalAlignment' => array( 'center' ), + ) + ); + + $this->assertIsString( $layout_styles, 'Flex layout should not fatal when alignment values are not strings.' ); + } + + /** + * Tests that a responsive grid child with a non-string parent minimumColumnWidth + * does not cause a fatal error in the explode() call. + * + * @ticket 65774 + * @covers ::wp_get_child_layout_style_rules + */ + public function test_wp_get_child_layout_style_rules_with_non_string_minimum_column_width() { + $actual_output = wp_get_child_layout_style_rules( + '.wp-container-content-test', + array( 'columnSpan' => '2' ), + array( 'minimumColumnWidth' => array( '12rem' ) ), + null + ); + + $this->assertIsArray( $actual_output, 'Child layout rules should not fatal when minimumColumnWidth is not a string.' ); + } + + /** + * Tests that layout classname generation does not fatal when the layout type, + * orientation, or justifyContent attributes are not strings. + * + * @ticket 65774 + * @covers ::wp_render_layout_support_flag + */ + public function test_layout_support_flag_with_non_string_layout_values() { + $block_content = '
'; + $block = array( + 'blockName' => 'core/group', + 'attrs' => array( + 'layout' => array( + 'type' => array( 'constrained' ), + 'orientation' => array( 'horizontal' ), + 'justifyContent' => array( 'center' ), + ), + ), + ); + + $this->assertIsString( + wp_render_layout_support_flag( $block_content, $block ), + 'Layout support should not fatal when layout values are not strings.' + ); + } + + /** + * Tests that restoring the group inner container does not fatal when the tagName + * attribute is not a string (which would break the preg_quote() calls). + * + * @ticket 65774 + * @covers ::wp_restore_group_inner_container + */ + public function test_restore_group_inner_container_with_non_string_tag_name() { + // The "default" theme doesn't have theme.json support, so the preg_quote() path runs. + switch_theme( 'default' ); + $block_content = '

Test

'; + $block = array( + 'blockName' => 'core/group', + 'attrs' => array( + 'tagName' => array( 'div' ), + ), + ); + + $this->assertIsString( + wp_restore_group_inner_container( $block_content, $block ), + 'Group inner container restore should not fatal when tagName is not a string.' + ); + } + + /** + * Tests that non-numeric grid placement values are dropped rather than being + * interpolated into the `grid-column` and `grid-row` declarations. + * + * @ticket 65774 + * @covers ::wp_get_child_layout_style_rules + */ + public function test_get_child_layout_style_rules_with_non_numeric_grid_placement() { + $actual_output = wp_get_child_layout_style_rules( + '.wp-container-content-test', + array( + 'columnStart' => array( 2 ), + 'columnSpan' => array( 3 ), + 'rowStart' => array( 1 ), + 'rowSpan' => array( 2 ), + ), + array(), + null + ); + + $this->assertSame( + array(), + $actual_output, + 'Non-numeric grid placement values should not produce any child layout rules.' + ); + } + + /** + * Tests that grid placement values saved as numeric strings (WordPress 6.3 to 6.6) + * produce the same declarations as numbers. + * + * @ticket 65774 + * @covers ::wp_get_child_layout_style_rules + */ + public function test_get_child_layout_style_rules_with_numeric_string_grid_placement() { + $expected_output = array( + array( + 'selector' => '.wp-container-content-test', + 'declarations' => array( + 'grid-column' => '2 / span 3', + 'grid-row' => '1 / span 2', + ), + ), + ); + + $actual_output = wp_get_child_layout_style_rules( + '.wp-container-content-test', + array( + 'columnStart' => '2', + 'columnSpan' => '3', + 'rowStart' => '1', + 'rowSpan' => '2', + ), + array( 'columnCount' => '3' ), + null + ); + + $this->assertSame( $expected_output, $actual_output ); + } + + /** + * Tests that non-numeric grid counts are treated as absent instead of leaking into the + * CSS. The rowCount case keeps columnCount valid, because the row track rule is only + * reached when there is a column count. + * + * @dataProvider data_get_layout_style_with_non_numeric_grid_counts + * + * @ticket 65774 + * @covers ::wp_get_layout_style + * + * @param array $layout Grid layout values. + * @param string $expected_output The expected output. + */ + public function test_get_layout_style_with_non_numeric_grid_counts( $layout, $expected_output ) { + $this->assertSame( $expected_output, wp_get_layout_style( '.wp-layout', $layout ) ); + } + + /** + * Data provider for test_get_layout_style_with_non_numeric_grid_counts(). + * + * @return array + */ + public function data_get_layout_style_with_non_numeric_grid_counts() { + return array( + 'non-numeric columnCount falls back to the responsive default' => array( + 'layout' => array( + 'type' => 'grid', + 'columnCount' => array( 3 ), + ), + 'expected_output' => '.wp-layout{grid-template-columns:repeat(auto-fill, minmax(min(12rem, 100%), 1fr));container-type:inline-size;}', + ), + 'non-numeric rowCount drops the row track rule' => array( + 'layout' => array( + 'type' => 'grid', + 'columnCount' => 3, + 'rowCount' => array( 2 ), + ), + 'expected_output' => '.wp-layout{grid-template-columns:repeat(3, minmax(0, 1fr));}', + ), + ); + } + + /** + * Tests that grid counts saved as numeric strings (WordPress 6.3 to 6.6) produce the + * same CSS as numbers. + * + * @ticket 65774 + * @covers ::wp_get_layout_style + */ + public function test_get_layout_style_with_numeric_string_grid_counts() { + $layout_styles = wp_get_layout_style( + '.wp-layout', + array( + 'type' => 'grid', + 'columnCount' => '3', + 'rowCount' => '2', + ) + ); + + $this->assertSame( + '.wp-layout{grid-template-columns:repeat(3, minmax(0, 1fr));grid-template-rows:repeat(2, minmax(1rem, auto));}', + $layout_styles + ); + } } From c1428bf6f0e26a69186b01640658ef4c3f988b53 Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Fri, 21 Aug 2026 13:25:59 +0000 Subject: [PATCH 258/634] General: Make `get_tag_regex()` match tags non-greedily. Fixes a bug where `get_tag_regex()` may match multiple tags of the same type in the content. Also, adds tests. Developed in https://github.com/WordPress/wordpress-develop/pull/13037 Props pbearne, kopepasah, gunjanjaswal, debarghyabanerjee, mukesh27, desrosj, ocean90, nacin, chriscct7, r1k0, afercia. Fixes 26674. Fixes 59791. git-svn-id: https://develop.svn.wordpress.org/trunk@63331 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/functions.php | 2 +- tests/phpunit/tests/functions/getTagRegex.php | 113 ++++++++++++++++++ 2 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 tests/phpunit/tests/functions/getTagRegex.php diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index a60bb57df7178..924684499c324 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -7700,7 +7700,7 @@ function get_tag_regex( $tag ) { if ( empty( $tag ) ) { return ''; } - return sprintf( '<%1$s[^<]*(?:>[\s\S]*<\/%1$s>|\s*\/>)', tag_escape( $tag ) ); + return sprintf( '<%1$s[^<]*?(?:>[\s\S]*?<\/%1$s>|\s*\/>)', tag_escape( $tag ) ); } /** diff --git a/tests/phpunit/tests/functions/getTagRegex.php b/tests/phpunit/tests/functions/getTagRegex.php new file mode 100644 index 0000000000000..e8e1893e4c4c1 --- /dev/null +++ b/tests/phpunit/tests/functions/getTagRegex.php @@ -0,0 +1,113 @@ +assertSame( $expected, $matches[0] ); + } + + /** + * Data provider. + * + * @since 7.2.0 + * + * @return array[] + */ + public function data_get_tag_regex_matches() { + // Each case embeds the element(s) within surrounding HTML, mirroring the + // original usage in get_media_embedded_in_content(), which is passed a + // string of HTML that may contain media elements rather than the bare + // element on its own. + return array( + 'a single tag with a body' => array( + 'iframe', + '

Before.

After.

', + array( '' ), + ), + + // The regression: a greedy match ran from the first opening tag to + // the last closing tag, merging both embeds and the text between + // them into a single match. See #26674. + 'two adjacent tags are matched separately' => array( + 'iframe', + '

Intro.

text

Outro.

', + array( + '', + '', + ), + ), + + // A self-closing void element (an iframe cannot self-close), matched + // both with and without the space before the slash (comment:16). + 'a self-closing tag with a space' => array( + 'input', + '
A form field: and more text.
', + array( '' ), + ), + + 'a self-closing tag without a space' => array( + 'input', + '
A form field: and more text.
', + array( '' ), + ), + + 'a tag with a multiline body' => array( + 'video', + "

Watch:

\n\n

End.

", + array( "" ), + ), + + 'no match when the tag is absent' => array( + 'iframe', + '

No embeds here.

', + array(), + ), + ); + } + + /** + * Tests that calling get_tag_regex() with an empty tag name returns an empty string. + * + * @ticket 26674 + * + * @since 7.2.0 + */ + public function test_get_tag_regex_returns_empty_string_for_empty_tag() { + $this->assertSame( '', get_tag_regex( '' ) ); + } + + /** + * Tests that the tag name is passed through tag_escape(), so casing and + * invalid characters do not change the generated pattern. + * + * @ticket 26674 + * + * @since 7.2.0 + */ + public function test_get_tag_regex_escapes_the_tag_name() { + $this->assertSame( get_tag_regex( 'iframe' ), get_tag_regex( 'IFRAME' ) ); + } +} From 9b24d2d08d47c4fdba9e8131deedb025809c0be8 Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Fri, 21 Aug 2026 14:15:14 +0000 Subject: [PATCH 259/634] Customize: Fix visual and DOM order mismatch of the Widgets panel buttons. In the Customizer > Widgets panel, the visual order of the 'Reorder' and 'Add a Widget' buttons didn't match the DOM order. For accessibility, the visual order and DOM order must match when they impact tab sequence, interaction, and meaning. Also, improves the alignment of the buttons. Developed in https://github.com/WordPress/wordpress-develop/pull/13135 Props khokansardar, joedolson, afercia. Fixes #65902. git-svn-id: https://develop.svn.wordpress.org/trunk@63332 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/css/customize-controls.css | 11 ++++++++--- .../class-wp-widget-area-customize-control.php | 16 +++++++++------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/wp-admin/css/customize-controls.css b/src/wp-admin/css/customize-controls.css index 3dfdfea790fb3..a81e5c7e575b9 100644 --- a/src/wp-admin/css/customize-controls.css +++ b/src/wp-admin/css/customize-controls.css @@ -2493,12 +2493,18 @@ body.cheatin p { * Widgets and Menus common styles */ +.customize-control-widgets-buttons { + display: flex; + justify-content: flex-end; + align-items: center; + gap: 8px; +} + /* higher specificity than .wp-core-ui .button */ #customize-theme-controls .add-new-widget, #customize-theme-controls .add-new-menu-item { cursor: pointer; - float: right; - margin: 0 0 0 10px; + margin: 0; transition: all 0.2s; -webkit-user-select: none; user-select: none; @@ -2530,7 +2536,6 @@ body.cheatin p { /* Reordering */ .reorder-toggle { - float: right; padding: 5px 8px; text-decoration: none; cursor: pointer; diff --git a/src/wp-includes/customize/class-wp-widget-area-customize-control.php b/src/wp-includes/customize/class-wp-widget-area-customize-control.php index 66162827bc8a1..bcc27e23ab02d 100644 --- a/src/wp-includes/customize/class-wp-widget-area-customize-control.php +++ b/src/wp-includes/customize/class-wp-widget-area-customize-control.php @@ -53,13 +53,15 @@ public function to_json() { public function render_content() { $id = 'reorder-widgets-desc-' . str_replace( array( '[', ']' ), array( '-', '' ), $this->id ); ?> - - +
+ + +

Date: Fri, 21 Aug 2026 16:09:21 +0000 Subject: [PATCH 260/634] Docs: Remove a blank line between `@param` and `@return` in test docblocks. The [https://developer.wordpress.org/coding-standards/inline-documentation-standards/php/ PHP inline documentation standards] place `@return` immediately after the last `@param` tag, with no blank line between them: {{{ /** * Summary. * * @param string $var Description. * @return string Description. */ }}} This corrects 65 docblocks across 29 files in the PHPUnit test suite. Developed in https://github.com/WordPress/wordpress-develop/pull/13119. Follow-up to [63320]. Props mukesh27. See #65818, #65860. git-svn-id: https://develop.svn.wordpress.org/trunk@63333 602fd350-edb4-49c9-b593-d223f7449a82 --- .../class-wp-unittest-factory-callback-after-create.php | 1 - .../factory/class-wp-unittest-factory-for-attachment.php | 2 -- .../factory/class-wp-unittest-factory-for-blog.php | 2 -- .../factory/class-wp-unittest-factory-for-bookmark.php | 3 --- .../factory/class-wp-unittest-factory-for-comment.php | 4 ---- .../factory/class-wp-unittest-factory-for-network.php | 2 -- .../factory/class-wp-unittest-factory-for-post.php | 3 --- .../factory/class-wp-unittest-factory-for-term.php | 4 ---- .../factory/class-wp-unittest-factory-for-thing.php | 6 ------ .../factory/class-wp-unittest-factory-for-user.php | 3 --- tests/phpunit/tests/ajax/wpAjaxCropImage.php | 1 - .../tests/ajax/wpAjaxWpPrivacyErasePersonalData.php | 7 ------- .../tests/ajax/wpAjaxWpPrivacyExportPersonalData.php | 7 ------- tests/phpunit/tests/block-supports/aria-label.php | 1 - tests/phpunit/tests/block-supports/shadow.php | 1 - tests/phpunit/tests/blocks/wpBlockType.php | 1 - tests/phpunit/tests/customize/manager.php | 3 --- tests/phpunit/tests/customize/selective-refresh-ajax.php | 1 - tests/phpunit/tests/customize/setting.php | 2 -- tests/phpunit/tests/functions.php | 1 - .../tests/html-api/wpHtmlProcessorWebPlatformTests.php | 2 -- tests/phpunit/tests/image/editor.php | 1 - tests/phpunit/tests/kses/wpFilterGlobalStylesPost.php | 1 - tests/phpunit/tests/post/metaRevisions.php | 1 - .../tests/privacy/wpPrivacyDeleteOldExportFiles.php | 1 - tests/phpunit/tests/rest-api/rest-sidebars-controller.php | 1 - tests/phpunit/tests/rest-api/rest-widgets-controller.php | 1 - tests/phpunit/tests/rest-api/wpRestMenuItemsController.php | 1 - tests/phpunit/tests/term/wpGenerateTagCloud.php | 1 - 29 files changed, 65 deletions(-) diff --git a/tests/phpunit/includes/factory/class-wp-unittest-factory-callback-after-create.php b/tests/phpunit/includes/factory/class-wp-unittest-factory-callback-after-create.php index 115c950c2f27e..a9386f1c06233 100644 --- a/tests/phpunit/includes/factory/class-wp-unittest-factory-callback-after-create.php +++ b/tests/phpunit/includes/factory/class-wp-unittest-factory-callback-after-create.php @@ -24,7 +24,6 @@ public function __construct( $callback ) { * @since UT (3.7.0) * * @param int $object_id ID of the object to apply the callback on. - * * @return mixed Updated object field. */ public function call( $object_id ) { diff --git a/tests/phpunit/includes/factory/class-wp-unittest-factory-for-attachment.php b/tests/phpunit/includes/factory/class-wp-unittest-factory-for-attachment.php index 2c1872795fb37..7919404c58b2b 100644 --- a/tests/phpunit/includes/factory/class-wp-unittest-factory-for-attachment.php +++ b/tests/phpunit/includes/factory/class-wp-unittest-factory-for-attachment.php @@ -26,7 +26,6 @@ class WP_UnitTest_Factory_For_Attachment extends WP_UnitTest_Factory_For_Post { * } * @param int $legacy_parent Deprecated. * @param array $legacy_args Deprecated. - * * @return int|WP_Error The attachment ID on success, WP_Error object on failure. */ public function create_object( $args, $legacy_parent = 0, $legacy_args = array() ) { @@ -58,7 +57,6 @@ public function create_object( $args, $legacy_parent = 0, $legacy_args = array() * @param string $file Full path to the file to create an attachment object for. * The name of the file will be used as the attachment name. * @param int $parent_post_id ID of the post to attach the file to. - * * @return int|WP_Error The attachment ID on success, WP_Error object on failure. */ public function create_upload_object( $file, $parent_post_id = 0 ) { diff --git a/tests/phpunit/includes/factory/class-wp-unittest-factory-for-blog.php b/tests/phpunit/includes/factory/class-wp-unittest-factory-for-blog.php index c9ce9f335ccaf..3b807055130d4 100644 --- a/tests/phpunit/includes/factory/class-wp-unittest-factory-for-blog.php +++ b/tests/phpunit/includes/factory/class-wp-unittest-factory-for-blog.php @@ -27,7 +27,6 @@ public function __construct( $factory = null ) { * Creates a site object. * * @param array $args Arguments for the site object. - * * @return int|WP_Error The site ID on success, WP_Error object on failure. */ public function create_object( $args ) { @@ -80,7 +79,6 @@ public function update_object( $blog_id, $fields ) {} * Retrieves a site by a given ID. * * @param int $blog_id ID of the site to retrieve. - * * @return WP_Site|null The site object on success, null on failure. */ public function get_object_by_id( $blog_id ) { diff --git a/tests/phpunit/includes/factory/class-wp-unittest-factory-for-bookmark.php b/tests/phpunit/includes/factory/class-wp-unittest-factory-for-bookmark.php index d9f8e06fbe353..124be01c5b89d 100644 --- a/tests/phpunit/includes/factory/class-wp-unittest-factory-for-bookmark.php +++ b/tests/phpunit/includes/factory/class-wp-unittest-factory-for-bookmark.php @@ -29,7 +29,6 @@ public function __construct( $factory = null ) { * @since 6.2.0 Returns a WP_Error object on failure. * * @param array $args Arguments for the link object. - * * @return int|WP_Error The link ID on success, WP_Error object on failure. */ public function create_object( $args ) { @@ -44,7 +43,6 @@ public function create_object( $args ) { * * @param int $link_id ID of the link to update. * @param array $fields The fields to update. - * * @return int|WP_Error The link ID on success, WP_Error object on failure. */ public function update_object( $link_id, $fields ) { @@ -65,7 +63,6 @@ public function update_object( $link_id, $fields ) { * @since 4.6.0 * * @param int $link_id ID of the link to retrieve. - * * @return object|null The link object on success, null on failure. */ public function get_object_by_id( $link_id ) { diff --git a/tests/phpunit/includes/factory/class-wp-unittest-factory-for-comment.php b/tests/phpunit/includes/factory/class-wp-unittest-factory-for-comment.php index 194a8bf6eca0b..7095070005a22 100644 --- a/tests/phpunit/includes/factory/class-wp-unittest-factory-for-comment.php +++ b/tests/phpunit/includes/factory/class-wp-unittest-factory-for-comment.php @@ -31,7 +31,6 @@ public function __construct( $factory = null ) { * @global wpdb $wpdb WordPress database abstraction object. * * @param array $args The comment details. - * * @return int|WP_Error The comment ID on success, WP_Error object on failure. */ public function create_object( $args ) { @@ -58,7 +57,6 @@ public function create_object( $args ) { * * @param int $comment_id The comment ID. * @param array $fields The comment details. - * * @return int|WP_Error The value 1 if the comment was updated, 0 if not updated. * WP_Error object on failure. */ @@ -76,7 +74,6 @@ public function update_object( $comment_id, $fields ) { * @param int $count Total amount of comments to create. * @param array $args The comment details. * @param null $generation_definitions Default values. - * * @return int[] Array with the comment IDs. */ public function create_post_comments( $post_id, $count = 1, $args = array(), $generation_definitions = null ) { @@ -90,7 +87,6 @@ public function create_post_comments( $post_id, $count = 1, $args = array(), $ge * @since UT (3.7.0) * * @param int $comment_id ID of the comment to retrieve. - * * @return WP_Comment|null WP_Comment object on success, null on failure. */ public function get_object_by_id( $comment_id ) { diff --git a/tests/phpunit/includes/factory/class-wp-unittest-factory-for-network.php b/tests/phpunit/includes/factory/class-wp-unittest-factory-for-network.php index 686ebe89bba3d..6fc53645f07de 100644 --- a/tests/phpunit/includes/factory/class-wp-unittest-factory-for-network.php +++ b/tests/phpunit/includes/factory/class-wp-unittest-factory-for-network.php @@ -30,7 +30,6 @@ public function __construct( $factory = null ) { * @since 6.2.0 Returns a WP_Error object on failure. * * @param array $args Arguments for the network object. - * * @return int|WP_Error The network ID on success, WP_Error object on failure. */ public function create_object( $args ) { @@ -74,7 +73,6 @@ public function update_object( $network_id, $fields ) {} * @since 3.9.0 * * @param int $network_id ID of the network to retrieve. - * * @return WP_Network|null The network object on success, null on failure. */ public function get_object_by_id( $network_id ) { diff --git a/tests/phpunit/includes/factory/class-wp-unittest-factory-for-post.php b/tests/phpunit/includes/factory/class-wp-unittest-factory-for-post.php index 16fdf04166776..4f553b02a577b 100644 --- a/tests/phpunit/includes/factory/class-wp-unittest-factory-for-post.php +++ b/tests/phpunit/includes/factory/class-wp-unittest-factory-for-post.php @@ -30,7 +30,6 @@ public function __construct( $factory = null ) { * @since 6.2.0 Returns a WP_Error object on failure. * * @param array $args Array with elements for the post. - * * @return int|WP_Error The post ID on success, WP_Error object on failure. */ public function create_object( $args ) { @@ -45,7 +44,6 @@ public function create_object( $args ) { * * @param int $post_id ID of the post to update. * @param array $fields Post data. - * * @return int|WP_Error The post ID on success, WP_Error object on failure. */ public function update_object( $post_id, $fields ) { @@ -59,7 +57,6 @@ public function update_object( $post_id, $fields ) { * @since UT (3.7.0) * * @param int $post_id ID of the post to retrieve. - * * @return WP_Post|null WP_Post object on success, null on failure. */ public function get_object_by_id( $post_id ) { diff --git a/tests/phpunit/includes/factory/class-wp-unittest-factory-for-term.php b/tests/phpunit/includes/factory/class-wp-unittest-factory-for-term.php index 6b2b7340df176..e5ad663837ef8 100644 --- a/tests/phpunit/includes/factory/class-wp-unittest-factory-for-term.php +++ b/tests/phpunit/includes/factory/class-wp-unittest-factory-for-term.php @@ -31,7 +31,6 @@ public function __construct( $factory = null, $taxonomy = null ) { * @since UT (3.7.0) * * @param array $args Array of arguments for inserting a term. - * * @return int|WP_Error The term ID on success, WP_Error object on failure. */ public function create_object( $args ) { @@ -53,7 +52,6 @@ public function create_object( $args ) { * * @param int|object $term The term to update. * @param array $fields Array of arguments for updating a term. - * * @return int|WP_Error The term ID on success, WP_Error object on failure. */ public function update_object( $term, $fields ) { @@ -99,7 +97,6 @@ public function add_post_terms( $post_id, $terms, $taxonomy, $append = true ) { * * @param array $args Array or string of arguments for inserting a term. * @param null $generation_definitions The default values. - * * @return WP_Term|WP_Error|null WP_Term on success. WP_Error if taxonomy does not exist. Null for miscellaneous failure. */ public function create_and_get( $args = array(), $generation_definitions = null ) { @@ -120,7 +117,6 @@ public function create_and_get( $args = array(), $generation_definitions = null * @since UT (3.7.0) * * @param int $term_id ID of the term to retrieve. - * * @return WP_Term|WP_Error|null WP_Term on success. WP_Error if taxonomy does not exist. Null for miscellaneous failure. */ public function get_object_by_id( $term_id ) { diff --git a/tests/phpunit/includes/factory/class-wp-unittest-factory-for-thing.php b/tests/phpunit/includes/factory/class-wp-unittest-factory-for-thing.php index 786e70bdc4b70..89cefcaf3b306 100644 --- a/tests/phpunit/includes/factory/class-wp-unittest-factory-for-thing.php +++ b/tests/phpunit/includes/factory/class-wp-unittest-factory-for-thing.php @@ -34,7 +34,6 @@ public function __construct( $factory, $default_generation_definitions = array() * @since UT (3.7.0) * * @param array $args The arguments. - * * @return int|WP_Error The object ID on success, WP_Error object on failure. */ abstract public function create_object( $args ); @@ -46,7 +45,6 @@ abstract public function create_object( $args ); * * @param int $object_id The object ID. * @param array $fields The values to update. - * * @return int|WP_Error The object ID on success, WP_Error object on failure. */ abstract public function update_object( $object_id, $fields ); @@ -115,7 +113,6 @@ public function create_and_get( $args = array(), $generation_definitions = null * @since UT (3.7.0) * * @param int $object_id The object ID. - * * @return mixed The object. Can be anything. */ abstract public function get_object_by_id( $object_id ); @@ -197,7 +194,6 @@ public function generate_args( $args = array(), $generation_definitions = null, * * @param WP_UnitTest_Factory_Callback_After_Create[] $callbacks Array with callback functions. * @param int $object_id ID of the object to apply callbacks for. - * * @return array The altered fields. */ public function apply_callbacks( $callbacks, $object_id ) { @@ -216,7 +212,6 @@ public function apply_callbacks( $callbacks, $object_id ) { * @since UT (3.7.0) * * @param callable $callback The callback function. - * * @return WP_UnitTest_Factory_Callback_After_Create */ public function callback( $callback ) { @@ -229,7 +224,6 @@ public function callback( $callback ) { * @since UT (3.7.0) * * @param array|object|string|mixed $value The value to add slashes to. - * * @return array|string The value with the possibly applied slashes. */ public function addslashes_deep( $value ) { diff --git a/tests/phpunit/includes/factory/class-wp-unittest-factory-for-user.php b/tests/phpunit/includes/factory/class-wp-unittest-factory-for-user.php index 5bdc8312fc2af..2a3f2d4d940e2 100644 --- a/tests/phpunit/includes/factory/class-wp-unittest-factory-for-user.php +++ b/tests/phpunit/includes/factory/class-wp-unittest-factory-for-user.php @@ -27,7 +27,6 @@ public function __construct( $factory = null ) { * @since UT (3.7.0) * * @param array $args The user data to insert. - * * @return int|WP_Error The user ID on success, WP_Error object on failure. */ public function create_object( $args ) { @@ -41,7 +40,6 @@ public function create_object( $args ) { * * @param int $user_id ID of the user to update. * @param array $fields The user data to update. - * * @return int|WP_Error The user ID on success, WP_Error object on failure. */ public function update_object( $user_id, $fields ) { @@ -55,7 +53,6 @@ public function update_object( $user_id, $fields ) { * @since UT (3.7.0) * * @param int $user_id ID of the user ID to retrieve. - * * @return WP_User The user object. */ public function get_object_by_id( $user_id ) { diff --git a/tests/phpunit/tests/ajax/wpAjaxCropImage.php b/tests/phpunit/tests/ajax/wpAjaxCropImage.php index 3a23f3a425b50..7ccea87533f2a 100644 --- a/tests/phpunit/tests/ajax/wpAjaxCropImage.php +++ b/tests/phpunit/tests/ajax/wpAjaxCropImage.php @@ -214,7 +214,6 @@ private function prepare_post( WP_Post $attachment ) { /** * @param WP_Post $attachment - * * @return string */ private function get_attachment_filename( WP_Post $attachment ) { diff --git a/tests/phpunit/tests/ajax/wpAjaxWpPrivacyErasePersonalData.php b/tests/phpunit/tests/ajax/wpAjaxWpPrivacyErasePersonalData.php index 4f76ea12fb52d..d2c6446508784 100644 --- a/tests/phpunit/tests/ajax/wpAjaxWpPrivacyErasePersonalData.php +++ b/tests/phpunit/tests/ajax/wpAjaxWpPrivacyErasePersonalData.php @@ -170,7 +170,6 @@ protected function _set_eraser_callback( $callback ) { * @since 5.2.0 * * @param array $erasers List of data erasers. - * * @return array Array of data erasers. */ public function filter_eraser_callback_value( $erasers ) { @@ -197,7 +196,6 @@ protected function _unset_eraser_key( $key ) { * @since 5.2.0 * * @param array $erasers Erasers. - * * @return array Erasers. */ public function filter_unset_eraser_index( $erasers ) { @@ -229,7 +227,6 @@ protected function _unset_response_key( $key ) { * * @param string $email_address The requester's email address. * @param int $page Page number. - * * @return array Export data. */ public function filter_unset_response_index( $email_address, $page = 1 ) { @@ -639,7 +636,6 @@ public function test_error_when_eraser_messages_not_array() { * * @param string $email_address The requester's email address. * @param int $page Page number. - * * @return array Export data. */ public function filter_response_messages_invalid( $email_address, $page = 1 ) { @@ -741,7 +737,6 @@ public function test_output_should_be_filterable() { * @param int $page The page for this response. * @param int $request_id The privacy request post ID associated with this request. * @param string $eraser_key The key (slug) of the eraser that provided this data. - * * @return array Filtered erase response. */ public function filter_eraser_data_response( $response, $eraser_index, $email_address, $page, $request_id, $eraser_key ) { @@ -760,7 +755,6 @@ public function filter_eraser_data_response( $response, $eraser_index, $email_ad * @since 5.2.0 * * @param array $erasers An array of personal data erasers. - * * @return array An array of personal data erasers. */ public function register_custom_personal_data_eraser( $erasers ) { @@ -778,7 +772,6 @@ public function register_custom_personal_data_eraser( $erasers ) { * * @param string $email_address The comment author email address. * @param int $page Page number. - * * @return array Erase data. */ public function callback_personal_data_eraser( $email_address, $page = 1 ) { diff --git a/tests/phpunit/tests/ajax/wpAjaxWpPrivacyExportPersonalData.php b/tests/phpunit/tests/ajax/wpAjaxWpPrivacyExportPersonalData.php index 51e4cb1391dff..e79f0dffe98e8 100644 --- a/tests/phpunit/tests/ajax/wpAjaxWpPrivacyExportPersonalData.php +++ b/tests/phpunit/tests/ajax/wpAjaxWpPrivacyExportPersonalData.php @@ -204,7 +204,6 @@ protected function _unset_exporter_key( $key ) { * Unset a specified key in the test exporter array. * * @param array $exporters List of data exporters. - * * @return array List of data exporters. */ public function filter_unset_exporter_key( $exporters ) { @@ -579,7 +578,6 @@ public function test_error_when_exporter_missing_data_response() { * * @param string $email_address The requester's email address. * @param int $page Page number. - * * @return array Export data. */ public function callback_missing_data_response( $email_address, $page = 1 ) { @@ -615,7 +613,6 @@ public function test_function_should_error_when_exporter_missing_data_array_resp * * @param string $email_address The requester's email address. * @param int $page Page number. - * * @return array Export data. */ public function callback_missing_data_array_response( $email_address, $page = 1 ) { @@ -650,7 +647,6 @@ public function test_error_when_exporter_missing_done_response() { * * @param string $email_address The requester's email address. * @param int $page Page number. - * * @return array Export data. */ public function callback_missing_done_response( $email_address, $page = 1 ) { @@ -729,7 +725,6 @@ public function test_output_should_be_filterable() { * @param int $request_id The privacy request post ID associated with this request. * @param bool $send_as_email Whether the final results of the export should be emailed to the user. * @param string $exporter_key The key (slug) of the exporter that provided this data. - * * @return array The personal data for the given exporter and page. */ public function filter_exporter_data_response( $response, $exporter_index, $email_address, $page, $request_id, $send_as_email, $exporter_key ) { @@ -757,7 +752,6 @@ public function filter_exporter_data_response( $response, $exporter_index, $emai * @since 5.2.0 * * @param array $exporters An array of personal data exporters. - * * @return array An array of personal data exporters. */ public function filter_register_custom_personal_data_exporter( $exporters ) { @@ -775,7 +769,6 @@ public function filter_register_custom_personal_data_exporter( $exporters ) { * * @param string $email_address The requester's email address. * @param int $page Page number. - * * @return array Export data response. */ public function callback_custom_personal_data_exporter( $email_address, $page = 1 ) { diff --git a/tests/phpunit/tests/block-supports/aria-label.php b/tests/phpunit/tests/block-supports/aria-label.php index 93666ba0fb493..5e9a814721f85 100644 --- a/tests/phpunit/tests/block-supports/aria-label.php +++ b/tests/phpunit/tests/block-supports/aria-label.php @@ -26,7 +26,6 @@ public function tear_down() { * * @param string $block_name Name for the test block. * @param array $supports Array defining block support configuration. - * * @return WP_Block_Type The block type for the newly registered test block. */ private function register_aria_label_block_with_support( $block_name, $supports = array() ) { diff --git a/tests/phpunit/tests/block-supports/shadow.php b/tests/phpunit/tests/block-supports/shadow.php index c925bb2f43fe4..fbf7cc6fa98c0 100644 --- a/tests/phpunit/tests/block-supports/shadow.php +++ b/tests/phpunit/tests/block-supports/shadow.php @@ -26,7 +26,6 @@ public function tear_down() { * * @param string $block_name Name for the test block. * @param array $supports Array defining block support configuration. - * * @return WP_Block_Type The block type for the newly registered test block. */ private function register_shadow_block_with_support( $block_name, $supports = array() ) { diff --git a/tests/phpunit/tests/blocks/wpBlockType.php b/tests/phpunit/tests/blocks/wpBlockType.php index 3e69b67d965db..95e6ddbb51a33 100644 --- a/tests/phpunit/tests/blocks/wpBlockType.php +++ b/tests/phpunit/tests/blocks/wpBlockType.php @@ -588,7 +588,6 @@ public function test_variations_callback_happens_only_once() { * * @param array $variations Block variations before filter. * @param WP_Block_Type $block_type Block type. - * * @return array Block variations after filter. */ public function filter_test_variations( $variations, $block_type ) { diff --git a/tests/phpunit/tests/customize/manager.php b/tests/phpunit/tests/customize/manager.php index bedf0b39b3e95..6937fcd4b2c1e 100644 --- a/tests/phpunit/tests/customize/manager.php +++ b/tests/phpunit/tests/customize/manager.php @@ -3252,7 +3252,6 @@ public function test_customize_loaded_components_filter() { * * @param array $components Components. * @param WP_Customize_Manager $customize_manager Manager. - * * @return array Components. */ public function return_array_containing_widgets( $components, $customize_manager ) { @@ -3269,7 +3268,6 @@ public function return_array_containing_widgets( $components, $customize_manager * * @param array $components Components. * @param WP_Customize_Manager $customize_manager Manager. - * * @return array Components. */ public function return_array_containing_nav_menus( $components, $customize_manager ) { @@ -3561,7 +3559,6 @@ private function filtered_device_list() { * Callback for the customize_previewable_devices filter. * * @param array $devices The list of devices. - * * @return array */ public function filter_customize_previewable_devices( $devices ) { diff --git a/tests/phpunit/tests/customize/selective-refresh-ajax.php b/tests/phpunit/tests/customize/selective-refresh-ajax.php index 8d9305962b7f7..7c9c55e0c9856 100644 --- a/tests/phpunit/tests/customize/selective-refresh-ajax.php +++ b/tests/phpunit/tests/customize/selective-refresh-ajax.php @@ -359,7 +359,6 @@ public function test_handle_render_partials_request_with_single_valid_placement( * * @param array $partial_args Partial args. * @param string $partial_id Partial ID. - * * @return array|false Args. */ public function filter_customize_dynamic_partial_args( $partial_args, $partial_id ) { diff --git a/tests/phpunit/tests/customize/setting.php b/tests/phpunit/tests/customize/setting.php index 8addb229d4edc..917bbe59c4679 100644 --- a/tests/phpunit/tests/customize/setting.php +++ b/tests/phpunit/tests/customize/setting.php @@ -352,7 +352,6 @@ private function custom_type_setter( $name, $value ) { * * @param mixed $default_value * @param WP_Customize_Setting $setting - * * @return mixed|null */ public function custom_type_value_filter( $default_value, $setting = null ) { @@ -741,7 +740,6 @@ public function test_validate() { * * @param WP_Error $validity Validity. * @param string $value Value. - * * @return WP_Error */ public function filter_validate_for_test_validate( $validity, $value ) { diff --git a/tests/phpunit/tests/functions.php b/tests/phpunit/tests/functions.php index 3c709f3ea7090..608b31f058d99 100644 --- a/tests/phpunit/tests/functions.php +++ b/tests/phpunit/tests/functions.php @@ -419,7 +419,6 @@ public function test_wp_unique_filename_with_additional_image_extension() { * (if the image editor in PHP supports it). * * @param array $formats - * * @return array */ public function image_editor_output_format_handler( $formats ) { diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessorWebPlatformTests.php b/tests/phpunit/tests/html-api/wpHtmlProcessorWebPlatformTests.php index 0cd53678858bd..a7d9288393ad3 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessorWebPlatformTests.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessorWebPlatformTests.php @@ -137,7 +137,6 @@ public function data_external_web_platform_tests() { * * @param string|null $test_context_element Context element for fragment parsing, or null for full document parsing. * @param string $test_name Test name. - * * @return bool True if the test case should be skipped. False otherwise. */ private static function should_skip_test( ?string $test_context_element, string $test_name ): bool { @@ -353,7 +352,6 @@ static function ( $a, $b ) { * Convert a given Web Platform Tests fixture file into a series of test cases. * * @param string $filename Path to `.dat` file with test cases. - * * @return Generator Date: Fri, 21 Aug 2026 16:15:34 +0000 Subject: [PATCH 261/634] Plugins: Prevent object IDs from becoming integer array keys. To improve performance, r62408 replaced `spl_object_hash()` with `spl_object_id()` when building the array keys for `WP_Hook::$callbacks` and for `WP_Widget_Factory::$widgets`. Even when the `spl_object_id()` return value is cast to a string to preserve the previous string array keys, PHP automatically converts such numeric strings to `int` when assigning the array key. This resulted in a back-compat breakage for plugins that expected to use the array keys in string functions, including possible fatal errors when using `strict_types`. To preserve the previous string key behavior, any array keys using `spl_object_id()` are now prefixed with a string to prevent coercion to `int`. This not only fixes the expected array key types when iterating over these arrays, but it also fixes the return type for `WP_Widget_Factory::get_widget_key()` so it actually returns a string. In addition to the added tests, the `non-decimal-int-string` type in PHPStan is leveraged instead of a plain `string` to prevent this regression from returning. Developed in https://github.com/WordPress/wordpress-develop/pull/13209. Follow-up to r62408, r62733. Props westonruter, dugi-digitaly, sergeybiryukov. See #58291. Fixes #65919. git-svn-id: https://develop.svn.wordpress.org/trunk@63334 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/class-wp-hook.php | 14 ++-- src/wp-includes/class-wp-widget-factory.php | 22 ++++++- src/wp-includes/plugin.php | 10 ++- tests/phpunit/tests/hooks/buildUniqueId.php | 72 +++++++++++++++++++-- tests/phpunit/tests/widgets.php | 50 ++++++++++++++ 5 files changed, 153 insertions(+), 15 deletions(-) diff --git a/src/wp-includes/class-wp-hook.php b/src/wp-includes/class-wp-hook.php index 38895c87f1349..3675070106236 100644 --- a/src/wp-includes/class-wp-hook.php +++ b/src/wp-includes/class-wp-hook.php @@ -20,8 +20,8 @@ * accepted_args: int, * } * - * @phpstan-implements Iterator> - * @phpstan-implements ArrayAccess> + * @phpstan-implements Iterator> + * @phpstan-implements ArrayAccess> */ #[AllowDynamicProperties] final class WP_Hook implements Iterator, ArrayAccess { @@ -31,7 +31,7 @@ final class WP_Hook implements Iterator, ArrayAccess { * * @since 4.7.0 * @var array - * @phpstan-var array> + * @phpstan-var array> */ public $callbacks = array(); @@ -502,7 +502,7 @@ public function offsetExists( $offset ) { * * @param int $offset The offset to retrieve. * @return array|null If set, the value at the specified offset, null otherwise. - * @phpstan-return array|null + * @phpstan-return array|null */ #[ReturnTypeWillChange] public function offsetGet( $offset ) { @@ -518,7 +518,7 @@ public function offsetGet( $offset ) { * * @param int|null $offset The offset to assign the value to. * @param array $value The value to set. - * @phpstan-param array $value + * @phpstan-param array $value */ #[ReturnTypeWillChange] public function offsetSet( $offset, $value ) { @@ -554,7 +554,7 @@ public function offsetUnset( $offset ) { * @link https://www.php.net/manual/en/iterator.current.php * * @return array|false Array of callbacks at current priority, false if there are no more elements. - * @phpstan-return array|false + * @phpstan-return array|false */ #[ReturnTypeWillChange] public function current() { @@ -569,7 +569,7 @@ public function current() { * @link https://www.php.net/manual/en/iterator.next.php * * @return array|false Array of callbacks at next priority, false if there are no more elements. - * @phpstan-return array|false + * @phpstan-return array|false */ #[ReturnTypeWillChange] public function next() { diff --git a/src/wp-includes/class-wp-widget-factory.php b/src/wp-includes/class-wp-widget-factory.php index b6233eabba002..1f6ed3a58919e 100644 --- a/src/wp-includes/class-wp-widget-factory.php +++ b/src/wp-includes/class-wp-widget-factory.php @@ -16,11 +16,25 @@ #[AllowDynamicProperties] class WP_Widget_Factory { + /** + * Prefix for the key under which a widget registered as an instance is stored. + * + * Without it the key would be the decimal representation of an integer, which PHP casts from + * string to int when it is used as an array key. + * + * @since 7.1.1 + */ + private const INSTANCE_KEY_PREFIX = 'spl_object_id:'; + /** * Widgets array. * + * Keyed by class name for a widget registered by name, and by a prefixed object ID for a widget + * registered as an instance. + * * @since 2.8.0 - * @var array + * @var array + * @phpstan-var array */ public $widgets = array(); @@ -52,12 +66,13 @@ public function WP_Widget_Factory() { * @since 2.8.0 * @since 4.6.0 Updated the `$widget` parameter to also accept a WP_Widget instance object * instead of simply a `WP_Widget` subclass name. + * @since 7.1.1 The key for an instance is prefixed so that it is never cast to an integer. * * @param string|WP_Widget $widget Either the name of a `WP_Widget` subclass or an instance of a `WP_Widget` subclass. */ public function register( $widget ) { if ( $widget instanceof WP_Widget ) { - $this->widgets[ spl_object_id( $widget ) ] = $widget; + $this->widgets[ self::INSTANCE_KEY_PREFIX . spl_object_id( $widget ) ] = $widget; } else { $this->widgets[ $widget ] = new $widget(); } @@ -69,12 +84,13 @@ public function register( $widget ) { * @since 2.8.0 * @since 4.6.0 Updated the `$widget` parameter to also accept a WP_Widget instance object * instead of simply a `WP_Widget` subclass name. + * @since 7.1.1 The key for an instance is prefixed so that it is never cast to an integer. * * @param string|WP_Widget $widget Either the name of a `WP_Widget` subclass or an instance of a `WP_Widget` subclass. */ public function unregister( $widget ) { if ( $widget instanceof WP_Widget ) { - unset( $this->widgets[ spl_object_id( $widget ) ] ); + unset( $this->widgets[ self::INSTANCE_KEY_PREFIX . spl_object_id( $widget ) ] ); } else { unset( $this->widgets[ $widget ] ); } diff --git a/src/wp-includes/plugin.php b/src/wp-includes/plugin.php index f64b584374c8e..717aebb0e5860 100644 --- a/src/wp-includes/plugin.php +++ b/src/wp-includes/plugin.php @@ -989,6 +989,7 @@ function _wp_call_all_hook( $args ) { * and no longer returns false, but can still return void for invalid callbacks. * @since 6.9.0 Returns explicit null if an invalid callback is supplied. * @since 7.1.0 Uses spl_object_id() instead of spl_object_hash() for performance. + * @since 7.1.1 The ID for an object callback is prefixed so that it is never cast to an integer array key. * * @access private * @@ -998,6 +999,8 @@ function _wp_call_all_hook( $args ) { * @param int $priority Unused. The order in which the functions * associated with a particular action are executed. * @return string|null Unique function ID for usage as array key, or null if it couldn't be determined. + * + * @phpstan-return non-decimal-int-string|null */ function _wp_filter_build_unique_id( $hook_name, $callback, $priority ): ?string { if ( is_string( $callback ) ) { @@ -1005,7 +1008,12 @@ function _wp_filter_build_unique_id( $hook_name, $callback, $priority ): ?string } if ( is_object( $callback ) ) { - return (string) spl_object_id( $callback ); + /* + * The prefix keeps the ID from being the decimal representation of an integer. PHP casts such a + * string to int when it is used as an array key, which would change the type of the keys in + * WP_Hook::$callbacks and break consumers that pass them to string functions. + */ + return 'spl_object_id:' . spl_object_id( $callback ); } if ( ! isset( $callback[1] ) || ! is_string( $callback[1] ) ) { diff --git a/tests/phpunit/tests/hooks/buildUniqueId.php b/tests/phpunit/tests/hooks/buildUniqueId.php index 387a24bbc2fd1..20ef31bdd9942 100644 --- a/tests/phpunit/tests/hooks/buildUniqueId.php +++ b/tests/phpunit/tests/hooks/buildUniqueId.php @@ -8,29 +8,63 @@ */ class Tests_Hooks_BuildUniqueId extends WP_UnitTestCase { + public static function set_up_before_class() { + parent::set_up_before_class(); + + require_once __DIR__ . '/../../includes/mock-invokable.php'; + } + + /** + * @ticket 58291 + * @ticket 65919 + */ public function test_string_callback_returns_string(): void { $result = _wp_filter_build_unique_id( '', '__return_null', 10 ); - $this->assertIsString( $result ); + $this->assertIsNonDecimalIntString( $result ); $this->assertSame( '__return_null', $result ); } + /** + * @ticket 58291 + * @ticket 65919 + */ public function test_closure_returns_string(): void { $cb = function (): void {}; $result = _wp_filter_build_unique_id( '', $cb, 10 ); - $this->assertIsString( $result ); + $this->assertIsNonDecimalIntString( $result ); + } + + /** + * @ticket 58291 + * @ticket 65919 + */ + public function test_invokable_object_returns_string(): void { + $result = _wp_filter_build_unique_id( '', new Mock_Invokable(), 10 ); + $this->assertIsNonDecimalIntString( $result ); } + /** + * @ticket 58291 + * @ticket 65919 + */ public function test_object_callback_returns_string(): void { $a = new MockAction(); $result = _wp_filter_build_unique_id( '', array( $a, 'action' ), 10 ); - $this->assertIsString( $result ); + $this->assertIsNonDecimalIntString( $result ); } + /** + * @ticket 58291 + * @ticket 65919 + */ public function test_static_callback_returns_string(): void { $result = _wp_filter_build_unique_id( '', array( 'MockAction', 'action' ), 10 ); - $this->assertIsString( $result ); + $this->assertIsNonDecimalIntString( $result ); } + /** + * @ticket 58291 + */ public function test_two_different_objects_produce_different_ids(): void { $a = new MockAction(); $b = new MockAction(); @@ -40,6 +74,9 @@ public function test_two_different_objects_produce_different_ids(): void { ); } + /** + * @ticket 58291 + */ public function test_same_object_produces_same_id(): void { $a = new MockAction(); $this->assertSame( @@ -48,15 +85,42 @@ public function test_same_object_produces_same_id(): void { ); } + /** + * @ticket 58291 + */ public function test_malformed_array_missing_method_returns_null(): void { $a = new MockAction(); $result = _wp_filter_build_unique_id( '', array( $a ), 10 ); $this->assertNull( $result ); } + /** + * @ticket 58291 + */ public function test_malformed_array_non_string_method_returns_null(): void { $a = new MockAction(); $result = _wp_filter_build_unique_id( '', array( $a, 123 ), 10 ); $this->assertNull( $result ); } + + /** + * Asserts that a value is a string which PHP does not cast to an integer when used as an array key. + * + * The return value of _wp_filter_build_unique_id() is used as the callback key in WP_Hook::$callbacks. + * PHP silently casts an array key from string to int when the string is the canonical decimal + * representation of an integer, which changes the type of the keys that consumers of that public + * property read back. This is the runtime equivalent of PHPStan's `non-decimal-int-string` type. + * + * @param mixed $value Value to check. + */ + private function assertIsNonDecimalIntString( $value ): void { + $this->assertIsString( $value, 'The unique ID is not a string.' ); + + $array = array( $value => true ); + + $this->assertIsString( + array_key_first( $array ), + sprintf( 'The unique ID "%s" was cast to an integer when used as an array key.', $value ) + ); + } } diff --git a/tests/phpunit/tests/widgets.php b/tests/phpunit/tests/widgets.php index 8eb5914c9400d..7362146fda7fc 100644 --- a/tests/phpunit/tests/widgets.php +++ b/tests/phpunit/tests/widgets.php @@ -45,6 +45,56 @@ public function test_register_and_unregister_widget_core_widget() { $this->assertArrayNotHasKey( $widget_class, $wp_widget_factory->widgets ); } + /** + * Tests that a widget registered as an instance is keyed by a string. + * + * WP_Widget_Factory::$widgets is public, and its keys were strings in every release before the + * object ID was introduced. PHP casts an array key from string to int whenever the string is the + * canonical decimal representation of an integer, so a bare spl_object_id() value would change + * the type of the keys that consumers of that property read back. + * + * @see register_widget() + * @ticket 65919 + * + * @global WP_Widget_Factory $wp_widget_factory + */ + public function test_register_widget_instance_is_keyed_by_string() { + global $wp_widget_factory; + + register_widget( new WP_Widget_Search() ); + + $this->assertCount( 1, $wp_widget_factory->widgets ); + $this->assertIsString( array_key_first( $wp_widget_factory->widgets ) ); + } + + /** + * Tests that the key returned for a widget registered as an instance is a string. + * + * WP_Widget_Factory::get_widget_key() is documented as returning a string, and core passes what + * it returns to the_widget(), which in turn passes it to the 'the_widget' action, both of which + * document the value as a string. + * + * @see WP_Widget_Factory::get_widget_key() + * @ticket 65919 + * + * @global WP_Widget_Factory $wp_widget_factory + */ + public function test_get_widget_key_for_instance_returns_string() { + global $wp_widget_factory; + + $widget = new WP_Widget_Search(); + $widget->id_base = 'better_search'; + $widget->name = 'Better Search'; + $widget->option_name = 'widget_' . $widget->id_base; + $widget->widget_options['classname'] = 'widget_' . $widget->id_base; + $widget->control_options['id_base'] = $widget->id_base; + + register_widget( $widget ); + + $this->assertIsString( $wp_widget_factory->get_widget_key( 'better_search' ) ); + $this->assertSame( $widget, $wp_widget_factory->get_widget_object( 'better_search' ) ); + } + /** * Test that registering a widget class and registering a widget instance work together. * From efa89a0cbd1272545754dc6abe36460c98d2a6e7 Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Fri, 21 Aug 2026 19:50:26 +0000 Subject: [PATCH 262/634] Customize: Take into account longer translations for the Widgets panel buttons. Amends [63332]. Allows buttons to wrap when longer translations may cause them to overflow the panel width. Props sabernhardt, afercia. Fixes #65902. git-svn-id: https://develop.svn.wordpress.org/trunk@63335 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/css/customize-controls.css | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wp-admin/css/customize-controls.css b/src/wp-admin/css/customize-controls.css index a81e5c7e575b9..31fa33b1950f2 100644 --- a/src/wp-admin/css/customize-controls.css +++ b/src/wp-admin/css/customize-controls.css @@ -2495,6 +2495,7 @@ body.cheatin p { .customize-control-widgets-buttons { display: flex; + flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 8px; From caf7e3bac04f628557ca7ac5407fa685da9c159b Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Fri, 21 Aug 2026 20:33:05 +0000 Subject: [PATCH 263/634] Customize: Fix visual and DOM order mismatch of the Menus panel buttons. In the Customizer > Menus panel, the visual order of the 'Reorder' and 'Add Items' buttons didn't match the DOM order. For accessibility, the visual order and DOM order must match when they impact tab sequence, interaction, and meaning. Developed in https://github.com/WordPress/wordpress-develop/pull/13228 Props afercia. Fixes #65935. git-svn-id: https://develop.svn.wordpress.org/trunk@63336 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/css/customize-controls.css | 1 + src/wp-admin/css/customize-nav-menus.css | 4 ---- .../class-wp-customize-nav-menu-control.php | 6 +++--- tests/qunit/index.html | 14 ++++++++------ 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/wp-admin/css/customize-controls.css b/src/wp-admin/css/customize-controls.css index 31fa33b1950f2..b415b769d046d 100644 --- a/src/wp-admin/css/customize-controls.css +++ b/src/wp-admin/css/customize-controls.css @@ -2493,6 +2493,7 @@ body.cheatin p { * Widgets and Menus common styles */ + .customize-control-nav_menu-buttons, .customize-control-widgets-buttons { display: flex; flex-wrap: wrap; diff --git a/src/wp-admin/css/customize-nav-menus.css b/src/wp-admin/css/customize-nav-menus.css index cb3052e75f3b5..37008d6d8e29a 100644 --- a/src/wp-admin/css/customize-nav-menus.css +++ b/src/wp-admin/css/customize-nav-menus.css @@ -860,10 +860,6 @@ li.assigned-to-menu-location .add-new-menu-item { } .customize-control-nav_menu .customize-control-nav_menu-buttons { - display: flex; - flex-direction: row-reverse; - align-items: center; - gap: 8px; margin-top: 12px; } diff --git a/src/wp-includes/customize/class-wp-customize-nav-menu-control.php b/src/wp-includes/customize/class-wp-customize-nav-menu-control.php index 7b2e4396166b4..7b064e89ca09d 100644 --- a/src/wp-includes/customize/class-wp-customize-nav-menu-control.php +++ b/src/wp-includes/customize/class-wp-customize-nav-menu-control.php @@ -49,13 +49,13 @@ public function content_template() { ?>

- +

', ), - 'expected' => '

alert("Howdy,admin!");">

A notice with an unsafe type.

', + 'expected' => '

A notice with an unsafe type.

', ), 'an unsafe ID' => array( 'message' => 'A notice with an unsafe ID.', 'args' => array( 'id' => '">
alert( "Howdy, admin!" );

A notice with an unsafe ID.

', + 'expected' => '

A notice with an unsafe ID.

', ), 'unsafe additional classes' => array( 'message' => 'A notice with unsafe additional classes.', 'args' => array( 'additional_classes' => array( '">
alert( "Howdy, admin!" );

A notice with unsafe additional classes.

', + 'expected' => '

A notice with unsafe additional classes.

', ), 'a type that is not a string' => array( 'message' => 'A notice with a type that is not a string.', diff --git a/tests/phpunit/tests/functions/wpGetAdminNotice.php b/tests/phpunit/tests/functions/wpGetAdminNotice.php index 41b24a122be88..87343479a2670 100644 --- a/tests/phpunit/tests/functions/wpGetAdminNotice.php +++ b/tests/phpunit/tests/functions/wpGetAdminNotice.php @@ -21,7 +21,7 @@ class Tests_Functions_WpGetAdminNotice extends WP_UnitTestCase { * @param string $expected The expected admin notice markup. */ public function test_should_return_admin_notice( $message, $args, $expected ) { - $this->assertSame( $expected, wp_get_admin_notice( $message, $args ) ); + $this->assertEqualHTML( $expected, wp_get_admin_notice( $message, $args ) ); } /** @@ -150,21 +150,21 @@ public function data_should_return_admin_notice() { 'args' => array( 'type' => '">', ), - 'expected' => '
">

A notice with an unsafe type.

', + 'expected' => '

A notice with an unsafe type.

', ), 'an unsafe ID' => array( 'message' => 'A notice with an unsafe ID.', 'args' => array( 'id' => '">

A notice with an unsafe ID.

', + 'expected' => '

A notice with an unsafe ID.

', ), 'unsafe additional classes' => array( 'message' => 'A notice with unsafe additional classes.', 'args' => array( 'additional_classes' => array( '">

A notice with unsafe additional classes.

', + 'expected' => '

A notice with unsafe additional classes.

', ), 'a type that is not a string' => array( 'message' => 'A notice with a type that is not a string.', From ddcfed2024b075b074694d6d3412a93a132fa70f Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Fri, 28 Aug 2026 00:45:55 +0000 Subject: [PATCH 308/634] Code Quality: Resolve the `encapsedStringPart.nonString` error. The `get_attachment_fields_to_edit()` function documented every value of its returned array as a field definition array, but the `attachment_fields_to_edit` filter may also add a `_final` entry holding raw HTML, which `get_media_item()` interpolates into a string. Declare that structure in a `@phpstan-return` tag so the `_final` entry is typed as a string while the remaining keys stay typed as field definition arrays, and widen the plain `@return` to a union so the array shape remains a proper subtype of it. The `menu_order` key is listed explicitly in the shape because `get_media_item()` unsets it. Unsetting a key that an unsealed array shape does not declare collapses the shape into a plain union of its value types, which would reintroduce the imprecision for every other field. Developed in https://github.com/WordPress/wordpress-develop/pull/13078. Follow-up to r61594, r63020. Props dpantazis. See #65817. git-svn-id: https://develop.svn.wordpress.org/trunk@63381 602fd350-edb4-49c9-b593-d223f7449a82 --- phpstan.neon.dist | 1 - src/wp-admin/includes/media.php | 11 +++++++- .../encapsedStringPart.nonString.neon | 25 ------------------- 3 files changed, 10 insertions(+), 27 deletions(-) delete mode 100644 tests/phpstan/baselines/encapsedStringPart.nonString.neon diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 4292aa4ddb408..3a4cce5b04ae3 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -42,7 +42,6 @@ includes: - tests/phpstan/baselines/empty.offset.neon - tests/phpstan/baselines/empty.property.neon - tests/phpstan/baselines/empty.variable.neon - - tests/phpstan/baselines/encapsedStringPart.nonString.neon - tests/phpstan/baselines/foreach.nonIterable.neon - tests/phpstan/baselines/function.alreadyNarrowedType.neon - tests/phpstan/baselines/function.impossibleType.neon diff --git a/src/wp-admin/includes/media.php b/src/wp-admin/includes/media.php index 99281712f66cf..babc0e85c33ac 100644 --- a/src/wp-admin/includes/media.php +++ b/src/wp-admin/includes/media.php @@ -1398,7 +1398,16 @@ function image_media_send_to_editor( $html, $attachment_id, $attachment ) { * * @param WP_Post $post * @param array $errors - * @return array> The attachment fields. + * @return array|string> The attachment fields, keyed by field name. Each value is a + * field definition array, except for the `_final` key, which the + * `attachment_fields_to_edit` filter may set to raw HTML that is + * rendered after all other fields. + * + * @phpstan-return array{ + * _final?: string, + * menu_order?: array, // Listed explicitly so that unsetting it in get_media_item() does not collapse this shape. + * ...> + * } */ function get_attachment_fields_to_edit( $post, $errors = null ) { if ( is_int( $post ) ) { diff --git a/tests/phpstan/baselines/encapsedStringPart.nonString.neon b/tests/phpstan/baselines/encapsedStringPart.nonString.neon deleted file mode 100644 index 707a2192a4c8a..0000000000000 --- a/tests/phpstan/baselines/encapsedStringPart.nonString.neon +++ /dev/null @@ -1,25 +0,0 @@ -# PHPStan baseline for the `encapsedStringPart.nonString` errors in WordPress core. -# -# https://phpstan.org/error-identifiers/encapsedStringPart.nonString -# -# Each entry is scoped to a single file and carries an exact occurrence count, -# so that a new instance is reported as a new error rather than being absorbed -# silently. Fixing an occurrence therefore means decrementing or removing its -# entry here as part of the same change. -# -# The goal is to empty this file and delete it, along with the `includes` entry -# for it in phpstan.neon.dist. -# -# Generated by `composer phpstan:baselines`. Do not edit by hand; regenerate with -# -# composer phpstan:baselines -- --identifier=encapsedStringPart.nonString -# -# which reruns the analysis with this file suppressed so the errors surface again. - -parameters: - ignoreErrors: - - - message: '#^Part \$form_fields\[''_final''\] \(non\-empty\-array\\) of encapsed string cannot be cast to string\.$#' - identifier: encapsedStringPart.nonString - count: 1 - path: ../../../src/wp-admin/includes/media.php From 8c787059570b8ffae03e3d0c4d64ddde56096ce2 Mon Sep 17 00:00:00 2001 From: Aki Hamano Date: Fri, 28 Aug 2026 01:49:20 +0000 Subject: [PATCH 309/634] Editor: Add the fit text CSS class to server-rendered blocks. Inject the `has-fit-text` class into the block wrapper during server-side rendering, so that fit text also takes effect on dynamically rendered blocks. Developed in: https://github.com/WordPress/wordpress-develop/pull/13287 Props westonruter, wildworks. Fixes #65973. git-svn-id: https://develop.svn.wordpress.org/trunk@63382 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/block-supports/typography.php | 1 + .../tests/block-supports/typography.php | 77 +++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/src/wp-includes/block-supports/typography.php b/src/wp-includes/block-supports/typography.php index 6573119933721..e99d0254fb43d 100644 --- a/src/wp-includes/block-supports/typography.php +++ b/src/wp-includes/block-supports/typography.php @@ -311,6 +311,7 @@ function wp_render_typography_support( $block_content, $block ) { if ( ! empty( $block_content ) ) { $processor = new WP_HTML_Tag_Processor( $block_content ); if ( $processor->next_tag() ) { + $processor->add_class( 'has-fit-text' ); if ( ! $processor->get_attribute( 'data-wp-interactive' ) ) { $processor->set_attribute( 'data-wp-interactive', true ); } diff --git a/tests/phpunit/tests/block-supports/typography.php b/tests/phpunit/tests/block-supports/typography.php index 59c47516caa2d..2c39b9c51b82e 100644 --- a/tests/phpunit/tests/block-supports/typography.php +++ b/tests/phpunit/tests/block-supports/typography.php @@ -58,6 +58,9 @@ public function tear_down() { unregister_block_type( $this->test_block_name ); $this->test_block_name = null; + // Resets script modules enqueued while rendering fit text. + $GLOBALS['wp_script_modules'] = null; + parent::tear_down(); } @@ -1135,6 +1138,80 @@ public function data_generate_replace_inline_font_styles_with_fluid_values_fixtu ); } + /** + * Tests that the `has-fit-text` class name is added to the block wrapper when the + * `fitText` attribute is set. + * + * @ticket 65973 + * + * @covers ::wp_render_typography_support + * + * @dataProvider data_should_add_fit_text_class_name + * + * @param non-falsy-string $block_content HTML block content. + * @param non-falsy-string $expected_class Expected value of the class attribute on the block wrapper. + */ + public function test_should_add_fit_text_class_name( string $block_content, string $expected_class ) { + $block = array( + 'blockName' => 'core/site-title', + 'attrs' => array( + 'fitText' => true, + ), + ); + + $actual = wp_render_typography_support( $block_content, $block ); + + $processor = new WP_HTML_Tag_Processor( $actual ); + $processor->next_tag(); + + $this->assertSame( $expected_class, $processor->get_attribute( 'class' ), 'The block wrapper does not have the expected class names.' ); + $this->assertSame( 1, substr_count( $actual, 'has-fit-text' ), 'The class name should be added exactly once, to the outermost tag only.' ); + } + + /** + * Data provider for test_should_add_fit_text_class_name(). + * + * @return array + */ + public function data_should_add_fit_text_class_name(): array { + return array( + 'wrapper without a class attribute' => array( + 'block_content' => '

Site Title

', + 'expected_class' => 'has-fit-text', + ), + 'wrapper with existing class names' => array( + 'block_content' => '

Site Title

', + 'expected_class' => 'wp-block-site-title has-fit-text', + ), + 'wrapper with an already serialized class name' => array( + 'block_content' => '

A paragraph

', + 'expected_class' => 'has-fit-text', + ), + 'wrapper with inner blocks' => array( + 'block_content' => '

A paragraph inside a group

', + 'expected_class' => 'wp-block-group has-fit-text', + ), + ); + } + + /** + * Tests that the `has-fit-text` class name is not added when the block does not + * opt in to the fit text support. + * + * @ticket 65973 + * + * @covers ::wp_render_typography_support + */ + public function test_should_not_add_fit_text_class_name_without_fit_text_attribute() { + $block_content = '

Site Title

'; + $block = array( + 'blockName' => 'core/site-title', + 'attrs' => array(), + ); + + $this->assertSame( $block_content, wp_render_typography_support( $block_content, $block ) ); + } + /** * Tests that valid font size values are parsed. * From 6794f59d6b5ab75426647a5ae743e18654c99516 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Fri, 28 Aug 2026 02:50:34 +0000 Subject: [PATCH 310/634] Users: Document `comment_shortcuts` and `infinite_scrolling` properties on `WP_User`. Both are user preferences read straight off a `WP_User` through the magic `__get()`, exactly like `rich_editing` and `syntax_highlighting` beside them, but neither was listed among the class's `@property` tags, so nothing could resolve them. The `infinite_scrolling` property arrived in r62632 with the Media Library opt-out option; `comment_shortcuts` has gone undocumented since r9217 added the comment hotkeys opt-in, and was missing for the same reason. Regenerating the baselines drops both entries from `tests/phpstan/baselines/property.nonObject.neon`. Developed as subset of https://github.com/WordPress/wordpress-develop/pull/13064. Follow-up to r9217, r62632, r63020. See #65817. git-svn-id: https://develop.svn.wordpress.org/trunk@63383 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/class-wp-user.php | 2 ++ tests/phpstan/baselines/property.nonObject.neon | 10 ---------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/wp-includes/class-wp-user.php b/src/wp-includes/class-wp-user.php index d921a83de7f1f..d11d3b67af534 100644 --- a/src/wp-includes/class-wp-user.php +++ b/src/wp-includes/class-wp-user.php @@ -33,6 +33,8 @@ * @property string $display_name * @property string $spam * @property string $deleted + * @property string $comment_shortcuts + * @property string $infinite_scrolling * @property string $locale * @property string $rich_editing * @property string $syntax_highlighting diff --git a/tests/phpstan/baselines/property.nonObject.neon b/tests/phpstan/baselines/property.nonObject.neon index 81a4af3e09511..13fd1ccf89fc9 100644 --- a/tests/phpstan/baselines/property.nonObject.neon +++ b/tests/phpstan/baselines/property.nonObject.neon @@ -178,16 +178,6 @@ parameters: identifier: property.nonObject count: 2 path: ../../../src/wp-admin/update.php - - - message: '#^Cannot access property \$comment_shortcuts on WP_User\|false\.$#' - identifier: property.nonObject - count: 1 - path: ../../../src/wp-admin/user-edit.php - - - message: '#^Cannot access property \$infinite_scrolling on WP_User\|false\.$#' - identifier: property.nonObject - count: 1 - path: ../../../src/wp-admin/user-edit.php - message: '#^Cannot access property \$id on int\|string\|WP_Term\.$#' identifier: property.nonObject From 4a8a86b0fddb74aaeb68fb5cc143fb73557fdae9 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Fri, 28 Aug 2026 04:57:25 +0000 Subject: [PATCH 311/634] Code Quality: Call `WP_Theme_JSON`'s private statics via `self::`. In r52744 this class's internal calls were rewritten from `self::` to `static::` so that the subclasses it was opening the class up to could override them. For a private method that buys nothing, since a subclass cannot supply one, and PHPStan reports it as unsafe: late static binding resolves `static::` to the runtime class, where the private method is not visible. Thirty such call sites were left, reaching fourteen private statics. All fourteen are declared `private static` on `WP_Theme_JSON` itself, so `self::` is behavior-identical. A docblock example on `compute_spacing_sizes()` showed the same form and is updated along with the code it documents. This now eliminates the `tests/phpstan/baselines/staticClassAccess.privateMethod.neon` baseline. In r63368 the identifier was cleared from the four other classes reporting it, and `WP_Theme_JSON` was the last. Developed as subset of https://github.com/WordPress/wordpress-develop/pull/13064. Follow-up to r52744, r63020, r63368. See #65817. git-svn-id: https://develop.svn.wordpress.org/trunk@63384 602fd350-edb4-49c9-b593-d223f7449a82 --- phpstan.neon.dist | 1 - src/wp-includes/class-wp-theme-json.php | 60 ++++++------- .../staticClassAccess.privateMethod.neon | 90 ------------------- 3 files changed, 30 insertions(+), 121 deletions(-) delete mode 100644 tests/phpstan/baselines/staticClassAccess.privateMethod.neon diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 3a4cce5b04ae3..9f53887d400de 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -78,7 +78,6 @@ includes: - tests/phpstan/baselines/return.type.neon - tests/phpstan/baselines/return.unusedType.neon - tests/phpstan/baselines/smallerOrEqual.alwaysTrue.neon - - tests/phpstan/baselines/staticClassAccess.privateMethod.neon - tests/phpstan/baselines/ternary.alwaysTrue.neon - tests/phpstan/baselines/varTag.noVariable.neon - tests/phpstan/baselines/variable.undefined.neon diff --git a/src/wp-includes/class-wp-theme-json.php b/src/wp-includes/class-wp-theme-json.php index 7175d7a88747d..f9d07ccaa6c10 100644 --- a/src/wp-includes/class-wp-theme-json.php +++ b/src/wp-includes/class-wp-theme-json.php @@ -718,7 +718,7 @@ class WP_Theme_JSON { * @return array Responsive media queries. */ public static function get_viewport_media_queries( $viewport_settings = null, $options = array() ) { - $breakpoints = static::sanitize_viewport_settings( $viewport_settings ); + $breakpoints = self::sanitize_viewport_settings( $viewport_settings ); $responsive_media_queries = array(); @@ -788,7 +788,7 @@ private static function is_valid_viewport_breakpoint_size( $value ) { * @return float|null Viewport breakpoint size in pixels, or null when invalid. */ private static function get_viewport_breakpoint_value_in_pixels( $value ) { - if ( ! static::is_valid_viewport_breakpoint_size( $value ) ) { + if ( ! self::is_valid_viewport_breakpoint_size( $value ) ) { return null; } @@ -831,7 +831,7 @@ private static function sanitize_viewport_settings( $viewport_settings ) { $breakpoints = array(); foreach ( array_keys( static::DEFAULT_VIEWPORT_BREAKPOINTS ) as $breakpoint ) { $value = $viewport_settings[ $breakpoint ] ?? null; - $px = static::get_viewport_breakpoint_value_in_pixels( $value ); + $px = self::get_viewport_breakpoint_value_in_pixels( $value ); if ( null !== $px ) { $breakpoints[ $breakpoint ] = array( 'value' => trim( $value ), @@ -989,8 +989,8 @@ private function process_pseudo_selectors( $node, $base_selector, $settings, $bl if ( is_array( $block_metadata ) ) { $feature_declarations = $this->get_feature_declarations_for_node( $block_metadata, $pseudo_node ); - $feature_declarations = static::update_paragraph_text_indent_selector( $feature_declarations, $settings, $block_name ); - $feature_declarations = static::update_button_width_declarations( $feature_declarations, $settings ); + $feature_declarations = self::update_paragraph_text_indent_selector( $feature_declarations, $settings, $block_name ); + $feature_declarations = self::update_button_width_declarations( $feature_declarations, $settings ); foreach ( $feature_declarations as $feature_selector => $declarations ) { $target_selector = is_array( $style_variation ) @@ -1098,7 +1098,7 @@ public function __construct( $theme_json = array( 'version' => self::LATEST_SCHE $valid_block_names = array_keys( $blocks_metadata ); $valid_element_names = array_keys( static::ELEMENTS ); $valid_variations = static::get_valid_block_style_variations( $blocks_metadata ); - $this->theme_json = static::unwrap_shared_block_style_variations( $this->theme_json, $valid_variations ); + $this->theme_json = self::unwrap_shared_block_style_variations( $this->theme_json, $valid_variations ); $this->theme_json = static::sanitize( $this->theme_json, $valid_block_names, $valid_element_names, $valid_variations ); $this->theme_json = static::maybe_opt_in_into_settings( $this->theme_json ); @@ -1136,8 +1136,8 @@ public function __construct( $theme_json = array( 'version' => self::LATEST_SCHE if ( isset( $spacing_scale ) ) { $sizes_path = array( 'settings', 'spacing', 'spacingSizes', $origin ); $spacing_sizes = _wp_array_get( $this->theme_json, $sizes_path, array() ); - $spacing_scale_sizes = static::compute_spacing_sizes( $spacing_scale ); - $merged_spacing_sizes = static::merge_spacing_sizes( $spacing_scale_sizes, $spacing_sizes ); + $spacing_scale_sizes = self::compute_spacing_sizes( $spacing_scale ); + $merged_spacing_sizes = self::merge_spacing_sizes( $spacing_scale_sizes, $spacing_sizes ); _wp_array_set( $this->theme_json, $sizes_path, $merged_spacing_sizes ); } } @@ -1457,13 +1457,13 @@ protected static function sanitize( $input, $valid_block_names, $valid_element_n $result = static::remove_keys_not_in_schema( $input[ $subtree ], $schema[ $subtree ] ); if ( 'settings' === $subtree && array_key_exists( 'viewport', $input[ $subtree ] ) ) { - $result['viewport'] = static::sanitize_viewport_settings( $input[ $subtree ]['viewport'] ); + $result['viewport'] = self::sanitize_viewport_settings( $input[ $subtree ]['viewport'] ); } if ( empty( $result ) ) { unset( $output[ $subtree ] ); } else { - $output[ $subtree ] = static::resolve_custom_css_format( $result ); + $output[ $subtree ] = self::resolve_custom_css_format( $result ); } } @@ -2509,7 +2509,7 @@ protected function get_css_variables( $nodes, $origins ) { continue; } - $target = static::get_feature_selector( $feature_selectors, $preset_metadata['path'][0], $selector ); + $target = self::get_feature_selector( $feature_selectors, $preset_metadata['path'][0], $selector ); if ( ! isset( $vars_by_selector[ $target ] ) ) { $vars_by_selector[ $target ] = array(); @@ -3307,7 +3307,7 @@ protected static function get_style_nodes( $theme_json, $selectors = array(), $o return $nodes; } - $block_nodes = static::get_block_nodes( $theme_json, $selectors, $options ); + $block_nodes = self::get_block_nodes( $theme_json, $selectors, $options ); foreach ( $block_nodes as $block_node ) { $nodes[] = $block_node; } @@ -3332,7 +3332,7 @@ protected static function get_style_nodes( $theme_json, $selectors = array(), $o * @return array The block nodes in theme.json. */ public function get_styles_block_nodes() { - return static::get_block_nodes( $this->theme_json ); + return self::get_block_nodes( $this->theme_json ); } /** @@ -3824,11 +3824,11 @@ public function get_styles_for_block( $block_metadata ) { // Update text indent selector for paragraph blocks based on the textIndent setting. $block_name = $block_metadata['name'] ?? null; - $feature_declarations = static::update_paragraph_text_indent_selector( $feature_declarations, $settings, $block_name ); + $feature_declarations = self::update_paragraph_text_indent_selector( $feature_declarations, $settings, $block_name ); $block_elements = $block_metadata['elements'] ?? array(); // Update button width declarations for percentage values to use calc() with block gap. - $feature_declarations = static::update_button_width_declarations( $feature_declarations, $settings ); + $feature_declarations = self::update_button_width_declarations( $feature_declarations, $settings ); // If there are style variations, generate the declarations for them, including any feature selectors the block may have. $style_variation_declarations = array(); @@ -3844,10 +3844,10 @@ public function get_styles_for_block( $block_metadata ) { $variation_declarations = static::get_feature_declarations_for_node( $block_metadata, $style_variation_node ); // Update text indent selector for paragraph blocks based on the textIndent setting. - $variation_declarations = static::update_paragraph_text_indent_selector( $variation_declarations, $settings, $block_name ); + $variation_declarations = self::update_paragraph_text_indent_selector( $variation_declarations, $settings, $block_name ); // Update button width declarations for percentage values to use calc() with block gap. - $variation_declarations = static::update_button_width_declarations( $variation_declarations, $settings ); + $variation_declarations = self::update_button_width_declarations( $variation_declarations, $settings ); // Combine selectors with style variation's selector and add to overall style variation declarations. foreach ( $variation_declarations as $current_selector => $new_declarations ) { @@ -3864,7 +3864,7 @@ public function get_styles_for_block( $block_metadata ) { if ( isset( $block_metadata['name'] ) ) { $block_name = $block_metadata['name']; } elseif ( in_array( 'blocks', $block_metadata['path'], true ) && count( $block_metadata['path'] ) >= 3 ) { - $block_name = static::get_block_name_from_metadata_path( $block_metadata ); + $block_name = self::get_block_name_from_metadata_path( $block_metadata ); } else { $block_name = null; } @@ -3902,8 +3902,8 @@ public function get_styles_for_block( $block_metadata ) { $breakpoint_media = $responsive_media_queries[ $breakpoint ]; // Process feature-level declarations for this breakpoint. $breakpoint_feature_declarations = static::get_feature_declarations_for_node( $block_metadata, $breakpoint_node ); - $breakpoint_feature_declarations = static::update_paragraph_text_indent_selector( $breakpoint_feature_declarations, $settings, $block_name ); - $breakpoint_feature_declarations = static::update_button_width_declarations( $breakpoint_feature_declarations, $settings ); + $breakpoint_feature_declarations = self::update_paragraph_text_indent_selector( $breakpoint_feature_declarations, $settings, $block_name ); + $breakpoint_feature_declarations = self::update_button_width_declarations( $breakpoint_feature_declarations, $settings ); foreach ( $breakpoint_feature_declarations as $feature_selector => $feature_decl ) { $combined_selectors = static::get_block_style_variation_feature_selector( $style_variation, $feature_selector ); @@ -4101,7 +4101,7 @@ static function ( $pseudo_selector ) use ( $selector ) { // Update declarations if there are separators with only background color defined. if ( '.wp-block-separator' === $selector ) { - $declarations = static::update_separator_declarations( $declarations ); + $declarations = self::update_separator_declarations( $declarations ); } /* @@ -4343,8 +4343,8 @@ public function merge( $incoming ) { // Generate and merge the scales for this layer. $sizes_path = array( 'settings', 'spacing', 'spacingSizes', $origin ); $spacing_sizes = _wp_array_get( $incoming_data, $sizes_path, array() ); - $spacing_scale_sizes = static::compute_spacing_sizes( $flattened_spacing_scale ); - $merged_spacing_sizes = static::merge_spacing_sizes( $spacing_scale_sizes, $spacing_sizes ); + $spacing_scale_sizes = self::compute_spacing_sizes( $flattened_spacing_scale ); + $merged_spacing_sizes = self::merge_spacing_sizes( $spacing_scale_sizes, $spacing_sizes ); _wp_array_set( $incoming_data, $sizes_path, $merged_spacing_sizes ); } @@ -4441,7 +4441,7 @@ public function merge( $incoming ) { * some values provide exceptions, namely style values that are * objects and represent unique definitions for the style. */ - $style_nodes = static::get_block_nodes( + $style_nodes = self::get_block_nodes( $this->theme_json, array(), array( 'include_node_paths_only' => true ) @@ -4681,7 +4681,7 @@ public static function remove_insecure_properties( $theme_json, $origin = 'theme } $block_name = in_array( 'blocks', $metadata['path'], true ) - ? static::get_block_name_from_metadata_path( $metadata ) + ? self::get_block_name_from_metadata_path( $metadata ) : null; // The global styles custom CSS is not sanitized, but can only be edited by users with 'edit_css' capability. @@ -5008,13 +5008,13 @@ protected static function remove_insecure_settings( $input, $is_root = false ) { } // Ensure indirect properties not included in any `PRESETS_METADATA` value are allowed. - static::remove_indirect_properties( $input, $output ); + self::remove_indirect_properties( $input, $output ); // Preserve all valid settings that have type markers in VALID_SETTINGS. self::preserve_valid_typed_settings( $input, $output, static::VALID_SETTINGS ); if ( $is_root && array_key_exists( 'viewport', $input ) ) { - $output['viewport'] = static::sanitize_viewport_settings( $input['viewport'] ); + $output['viewport'] = self::sanitize_viewport_settings( $input['viewport'] ); } return $output; @@ -5049,7 +5049,7 @@ protected static function remove_insecure_styles( $input ) { } // Ensure indirect properties not handled by `compute_style_properties` are allowed. - static::remove_indirect_properties( $input, $output ); + self::remove_indirect_properties( $input, $output ); return $output; } @@ -5382,7 +5382,7 @@ public function set_spacing_sizes() { return; } - $spacing_sizes = static::compute_spacing_sizes( $spacing_scale ); + $spacing_sizes = self::compute_spacing_sizes( $spacing_scale ); // If there are 7 or fewer steps in the scale revert to numbers for labels instead of t-shirt sizes. if ( $spacing_scale['steps'] <= 7 ) { @@ -5434,7 +5434,7 @@ private static function merge_spacing_sizes( $base, $incoming ) { * 'operator' => '+', * 'increment' => 2, * ); - * $spacing_sizes = static::compute_spacing_sizes( $spacing_scale ); + * $spacing_sizes = self::compute_spacing_sizes( $spacing_scale ); * // -> array( * // array( 'name' => 'Small', 'slug' => '40', 'size' => '14px' ), * // array( 'name' => 'Medium', 'slug' => '50', 'size' => '16px' ), diff --git a/tests/phpstan/baselines/staticClassAccess.privateMethod.neon b/tests/phpstan/baselines/staticClassAccess.privateMethod.neon deleted file mode 100644 index 7e8a5c1cf59e1..0000000000000 --- a/tests/phpstan/baselines/staticClassAccess.privateMethod.neon +++ /dev/null @@ -1,90 +0,0 @@ -# PHPStan baseline for the `staticClassAccess.privateMethod` errors in WordPress core. -# -# https://phpstan.org/error-identifiers/staticClassAccess.privateMethod -# -# Each entry is scoped to a single file and carries an exact occurrence count, -# so that a new instance is reported as a new error rather than being absorbed -# silently. Fixing an occurrence therefore means decrementing or removing its -# entry here as part of the same change. -# -# The goal is to empty this file and delete it, along with the `includes` entry -# for it in phpstan.neon.dist. -# -# Generated by `composer phpstan:baselines`. Do not edit by hand; regenerate with -# -# composer phpstan:baselines -- --identifier=staticClassAccess.privateMethod -# -# which reruns the analysis with this file suppressed so the errors surface again. - -parameters: - ignoreErrors: - - - message: '#^Unsafe call to private method WP_Theme_JSON\:\:compute_spacing_sizes\(\) through static\:\:\.$#' - identifier: staticClassAccess.privateMethod - count: 3 - path: ../../../src/wp-includes/class-wp-theme-json.php - - - message: '#^Unsafe call to private method WP_Theme_JSON\:\:get_block_name_from_metadata_path\(\) through static\:\:\.$#' - identifier: staticClassAccess.privateMethod - count: 2 - path: ../../../src/wp-includes/class-wp-theme-json.php - - - message: '#^Unsafe call to private method WP_Theme_JSON\:\:get_block_nodes\(\) through static\:\:\.$#' - identifier: staticClassAccess.privateMethod - count: 3 - path: ../../../src/wp-includes/class-wp-theme-json.php - - - message: '#^Unsafe call to private method WP_Theme_JSON\:\:get_feature_selector\(\) through static\:\:\.$#' - identifier: staticClassAccess.privateMethod - count: 1 - path: ../../../src/wp-includes/class-wp-theme-json.php - - - message: '#^Unsafe call to private method WP_Theme_JSON\:\:get_viewport_breakpoint_value_in_pixels\(\) through static\:\:\.$#' - identifier: staticClassAccess.privateMethod - count: 1 - path: ../../../src/wp-includes/class-wp-theme-json.php - - - message: '#^Unsafe call to private method WP_Theme_JSON\:\:is_valid_viewport_breakpoint_size\(\) through static\:\:\.$#' - identifier: staticClassAccess.privateMethod - count: 1 - path: ../../../src/wp-includes/class-wp-theme-json.php - - - message: '#^Unsafe call to private method WP_Theme_JSON\:\:merge_spacing_sizes\(\) through static\:\:\.$#' - identifier: staticClassAccess.privateMethod - count: 2 - path: ../../../src/wp-includes/class-wp-theme-json.php - - - message: '#^Unsafe call to private method WP_Theme_JSON\:\:remove_indirect_properties\(\) through static\:\:\.$#' - identifier: staticClassAccess.privateMethod - count: 2 - path: ../../../src/wp-includes/class-wp-theme-json.php - - - message: '#^Unsafe call to private method WP_Theme_JSON\:\:resolve_custom_css_format\(\) through static\:\:\.$#' - identifier: staticClassAccess.privateMethod - count: 1 - path: ../../../src/wp-includes/class-wp-theme-json.php - - - message: '#^Unsafe call to private method WP_Theme_JSON\:\:sanitize_viewport_settings\(\) through static\:\:\.$#' - identifier: staticClassAccess.privateMethod - count: 3 - path: ../../../src/wp-includes/class-wp-theme-json.php - - - message: '#^Unsafe call to private method WP_Theme_JSON\:\:unwrap_shared_block_style_variations\(\) through static\:\:\.$#' - identifier: staticClassAccess.privateMethod - count: 1 - path: ../../../src/wp-includes/class-wp-theme-json.php - - - message: '#^Unsafe call to private method WP_Theme_JSON\:\:update_button_width_declarations\(\) through static\:\:\.$#' - identifier: staticClassAccess.privateMethod - count: 4 - path: ../../../src/wp-includes/class-wp-theme-json.php - - - message: '#^Unsafe call to private method WP_Theme_JSON\:\:update_paragraph_text_indent_selector\(\) through static\:\:\.$#' - identifier: staticClassAccess.privateMethod - count: 4 - path: ../../../src/wp-includes/class-wp-theme-json.php - - - message: '#^Unsafe call to private method WP_Theme_JSON\:\:update_separator_declarations\(\) through static\:\:\.$#' - identifier: staticClassAccess.privateMethod - count: 1 - path: ../../../src/wp-includes/class-wp-theme-json.php From 032e6b69edb01a98dfc7b70bae3dd7d560fe7e98 Mon Sep 17 00:00:00 2001 From: Aki Hamano Date: Fri, 28 Aug 2026 08:36:10 +0000 Subject: [PATCH 312/634] Themes: Correct slug generation for block template files. Block template and template part slugs are now derived by stripping the theme directory and the template directory from the front of the file path. Slugs are correct regardless of where the theme is located or how its folder is named, and for templates in nested subdirectories. Developed in https://github.com/WordPress/wordpress-develop/pull/12399 Props mamaduka, wildworks, yashjawale. Fixes #65580. git-svn-id: https://develop.svn.wordpress.org/trunk@63385 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/block-template-utils.php | 4 +- tests/phpunit/tests/block-template.php | 121 ++++++++++++++++++++++- 2 files changed, 122 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/block-template-utils.php b/src/wp-includes/block-template-utils.php index d17aa174398e3..b8ccd0f94a137 100644 --- a/src/wp-includes/block-template-utils.php +++ b/src/wp-includes/block-template-utils.php @@ -415,8 +415,8 @@ function _get_block_templates_files( $template_type, $query = array() ) { $template_base_path = $template_base_paths[ $template_type ]; $template_slug = substr( $template_file, - // Starting position of slug. - strpos( $template_file, $template_base_path . DIRECTORY_SEPARATOR ) + 1 + strlen( $template_base_path ), + // Starting position of the slug - the theme directory and the template base path. + strlen( $theme_dir . DIRECTORY_SEPARATOR . $template_base_path . DIRECTORY_SEPARATOR ), // Subtract ending '.html'. -5 ); diff --git a/tests/phpunit/tests/block-template.php b/tests/phpunit/tests/block-template.php index e0307b5782165..bfa60dadd65bb 100644 --- a/tests/phpunit/tests/block-template.php +++ b/tests/phpunit/tests/block-template.php @@ -21,7 +21,6 @@ public function set_up() { public function tear_down() { global $_wp_current_template_id, $_wp_current_template_content; unset( $_wp_current_template_id, $_wp_current_template_content ); - parent::tear_down(); } @@ -509,6 +508,126 @@ public function test_get_block_templates_paths_dir_doesnt_exists() { $this->assertSame( array(), $template_paths ); } + /** + * Tests that `_get_block_templates_files()` derives the correct template + * slugs from the theme's template files. + * + * The base path (e.g. `parts` or `templates`) must not end up in the slug, + * even when the theme folder name itself ends with the base path. + * + * @ticket 65580 + * + * @covers ::_get_block_templates_files + * + * @dataProvider data_get_block_templates_files_slugs + * + * @param string $theme_directory Directory name used as the theme directory. + * @param string $template_type Template type. Either 'wp_template' or 'wp_template_part'. + * @param array $expected_slugs Expected template slugs. + */ + public function test_get_block_templates_files_slugs( $theme_directory, $template_type, $expected_slugs ) { + $theme_root = sys_get_temp_dir() . '/wp-tests-block-template-slug-' . uniqid(); + $theme_dir = $theme_root . '/' . $theme_directory; + + $relative_paths = array( + 'parts/header.html', + 'parts/footer.html', + 'parts/footer-parts/header.html', + 'templates/index.html', + 'templates/footer.html', + ); + + $files = array(); + foreach ( $relative_paths as $relative_path ) { + $file_path = $theme_dir . '/' . $relative_path; + wp_mkdir_p( dirname( $file_path ) ); + touch( $file_path ); + $files[] = $file_path; + } + + add_filter( + 'stylesheet_directory', + static function () use ( $theme_dir ) { + return $theme_dir; + } + ); + + $slugs = wp_list_pluck( _get_block_templates_files( $template_type ), 'slug' ); + sort( $slugs ); + + // Collect every directory for cleanup. + $directories = array( $theme_root ); + foreach ( $files as $file_path ) { + $directory = dirname( $file_path ); + while ( strlen( $directory ) >= strlen( $theme_root ) ) { + $directories[] = $directory; + $directory = dirname( $directory ); + } + } + $directories = array_values( array_unique( $directories ) ); + + rsort( $directories ); + + foreach ( $files as $file_path ) { + unlink( $file_path ); + } + foreach ( $directories as $directory ) { + rmdir( $directory ); + } + + $this->assertSame( $expected_slugs, $slugs ); + } + + /** + * Data provider. + * + * @return array + */ + public function data_get_block_templates_files_slugs() { + return array( + 'template parts in a theme whose directory name does not end with parts' => array( + 'theme_directory' => 'default', + 'template_type' => 'wp_template_part', + 'expected_slugs' => array( 'footer', 'footer-parts/header', 'header' ), + ), + 'templates in a theme whose directory name does not end with parts' => array( + 'theme_directory' => 'default', + 'template_type' => 'wp_template', + 'expected_slugs' => array( 'footer', 'index' ), + ), + 'template parts in a theme whose directory name ends with parts' => array( + 'theme_directory' => 'auto-parts', + 'template_type' => 'wp_template_part', + 'expected_slugs' => array( 'footer', 'footer-parts/header', 'header' ), + ), + 'templates in a theme whose directory name ends with parts' => array( + 'theme_directory' => 'auto-parts', + 'template_type' => 'wp_template', + 'expected_slugs' => array( 'footer', 'index' ), + ), + 'template parts in a theme whose directory name is exactly parts' => array( + 'theme_directory' => 'parts', + 'template_type' => 'wp_template_part', + 'expected_slugs' => array( 'footer', 'footer-parts/header', 'header' ), + ), + 'templates in a theme whose directory name ends with templates' => array( + 'theme_directory' => 'my-templates', + 'template_type' => 'wp_template', + 'expected_slugs' => array( 'footer', 'index' ), + ), + 'template parts in a theme placed inside a directory named parts' => array( + 'theme_directory' => 'parts/default', + 'template_type' => 'wp_template_part', + 'expected_slugs' => array( 'footer', 'footer-parts/header', 'header' ), + ), + 'templates in a theme placed inside a directory named templates' => array( + 'theme_directory' => 'templates/default', + 'template_type' => 'wp_template', + 'expected_slugs' => array( 'footer', 'index' ), + ), + ); + } + /** * Tests that get_block_templates() returns plugin-registered templates. * From 7b282cdfe900de724dca9236165bd12dba66ade7 Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Fri, 28 Aug 2026 09:31:10 +0000 Subject: [PATCH 313/634] Administration: Fix the CSS Coding Standards in buttons.css. Lints the `src/wp-includes/css/buttons.css` file. Part of the ongoing effort to lint all the admin CSS files. Developed in https://github.com/WordPress/wordpress-develop/pull/13159 See #65898. git-svn-id: https://develop.svn.wordpress.org/trunk@63386 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/css/buttons.css | 37 ++++++++++++++------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/src/wp-includes/css/buttons.css b/src/wp-includes/css/buttons.css index 57d5754483199..3d9650c98cc89 100644 --- a/src/wp-includes/css/buttons.css +++ b/src/wp-includes/css/buttons.css @@ -36,9 +36,9 @@ TABLE OF CONTENTS: ---------------------------------------------------------------------------- */ -/* ---------------------------------------------------------------------------- - 1.0 - Button Layouts ----------------------------------------------------------------------------- */ +/** + * 1.0 Button Layouts + */ .wp-core-ui .button, .wp-core-ui .button-primary, @@ -141,9 +141,9 @@ TABLE OF CONTENTS: width: auto; } -/* ---------------------------------------------------------------------------- - 2.0 - Default Button Style ----------------------------------------------------------------------------- */ +/** + * 2.0 Default Button Style + */ .wp-core-ui .button, .wp-core-ui .button-secondary { @@ -241,7 +241,7 @@ TABLE OF CONTENTS: color: var(--wp-admin-theme-color, #3858e9); text-decoration: underline; transition-property: border, background, color; - transition-duration: .05s; + transition-duration: 0.05s; transition-timing-function: ease-in-out; } @@ -273,10 +273,9 @@ TABLE OF CONTENTS: background: transparent !important; } - -/* ---------------------------------------------------------------------------- - 3.0 - Primary Button Style ----------------------------------------------------------------------------- */ +/** + * 3.0 Primary Button Style + */ .wp-core-ui .button-primary { background: var(--wp-admin-theme-color, #3858e9); @@ -330,9 +329,9 @@ TABLE OF CONTENTS: cursor: default; } -/* ---------------------------------------------------------------------------- - 4.0 - Button Groups ----------------------------------------------------------------------------- */ +/** + * 4.0 Button Groups + */ .wp-core-ui .button-group { position: relative; @@ -376,12 +375,11 @@ TABLE OF CONTENTS: box-shadow: inset 0 2px 6px -2px var(--wp-admin-theme-color-darker-20), 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color); } -/* ---------------------------------------------------------------------------- - 5.0 - Responsive Button Styles ----------------------------------------------------------------------------- */ +/** + * 5.0 Responsive Button Styles + */ @media screen and (max-width: 782px) { - .wp-core-ui .button, .wp-core-ui .button.button-large, .wp-core-ui .button.button-compact, @@ -427,7 +425,6 @@ TABLE OF CONTENTS: } /* Reset responsive styles in Press This, Customizer */ - .wp-core-ui.wp-customizer .button { font-size: 13px; line-height: 2.30769231; /* 30px */ @@ -446,11 +443,9 @@ TABLE OF CONTENTS: } /* Reset responsive styles on Log in button on iframed login form */ - .interim-login .button.button-large { min-height: 32px; line-height: 2.30769231; /* 30px */ padding: 0 12px; } - } From 9748195729dc4266b2dd280e3a7dbbc29402472c Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Fri, 28 Aug 2026 09:37:05 +0000 Subject: [PATCH 314/634] Administration: Fix the CSS Coding Standards in l10n.css. Lints the `src/wp-admin/css/l10n.css` file. Part of the ongoing effort to lint all the admin CSS files. Developed in https://github.com/WordPress/wordpress-develop/pull/13141 See #65898. git-svn-id: https://develop.svn.wordpress.org/trunk@63387 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/css/l10n.css | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/wp-admin/css/l10n.css b/src/wp-admin/css/l10n.css index 2d0b9b2145f69..18458c4872469 100644 --- a/src/wp-admin/css/l10n.css +++ b/src/wp-admin/css/l10n.css @@ -49,27 +49,37 @@ body.locale-he-il .press-this a.wp-switch-editor { } /* zh_CN: Enlarge dashboard widget 'Configure' link */ -.locale-zh-cn .hdnle a { font-size: 12px; } +.locale-zh-cn .hdnle a { + font-size: 12px; +} /* zn_CH: Enlarge font size, set font-size: normal */ -.locale-zh-cn form.upgrade .hint { font-style: normal; font-size: 100%; } +.locale-zh-cn form.upgrade .hint { + font-style: normal; + font-size: 100%; +} /* zh_CN: Enlarge font-size. */ -.locale-zh-cn #sort-buttons { font-size: 1em !important; } +.locale-zh-cn #sort-buttons { + font-size: 1em !important; +} /* de_DE: Text needs more space for translation */ .locale-de-de #customize-header-actions .button, .locale-de-de-formal #customize-header-actions .button { padding: 0 5px 1px; /* default 0 10px 1px */ } + .locale-de-de #customize-header-actions .spinner, .locale-de-de-formal #customize-header-actions .spinner { margin: 16px 3px 0; /* default 16px 4px 0 5px */ } + body[class*="locale-de-"] .inline-edit-row fieldset label span.title, body[class*="locale-de-"] .inline-edit-row fieldset.inline-edit-date legend { width: 7em; /* default 6em */ } + body[class*="locale-de-"] .inline-edit-row fieldset label span.input-text-wrap, body[class*="locale-de-"] .inline-edit-row fieldset .timestamp-wrap { margin-left: 7em; /* default 6em */ @@ -79,31 +89,39 @@ body[class*="locale-de-"] .inline-edit-row fieldset .timestamp-wrap { .locale-ru-ru #adminmenu { width: inherit; /* back-compat for pre-3.2 */ } + .locale-ru-ru #adminmenu, .locale-ru-ru #wpbody { margin-left: 0; /* back-compat for pre-3.2 */ } + .locale-ru-ru .inline-edit-row fieldset label span.title, .locale-ru-ru .inline-edit-row fieldset.inline-edit-date legend { width: 8em; /* default 6em */ } + .locale-ru-ru .inline-edit-row fieldset label span.input-text-wrap, .locale-ru-ru .inline-edit-row fieldset .timestamp-wrap { margin-left: 8em; /* default 6em */ } + .locale-ru-ru.post-php .tagsdiv .newtag, .locale-ru-ru.post-new-php .tagsdiv .newtag { width: 165px; /* default 180px - 15px */ } + .locale-ru-ru.press-this .posting { margin-right: 277px; /* default 252px + 25px */ } + .locale-ru-ru .press-this-sidebar { width: 265px; /* default 240px + 25px */ } + .locale-ru-ru #customize-header-actions .button { padding: 0 5px 1px; /* default 0 10px 1px */ } + .locale-ru-ru #customize-header-actions .spinner { margin: 16px 3px 0; /* default 16px 4px 0 5px */ } @@ -113,6 +131,7 @@ body[class*="locale-de-"] .inline-edit-row fieldset .timestamp-wrap { .locale-lt-lt .inline-edit-row fieldset.inline-edit-date legend { width: 8em; /* default 6em */ } + .locale-lt-lt .inline-edit-row fieldset label span.input-text-wrap, .locale-lt-lt .inline-edit-row fieldset .timestamp-wrap { margin-left: 8em; /* default 6em */ From d5f778399d4d34c6811e53ac23c552a943c109bb Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Fri, 28 Aug 2026 09:40:34 +0000 Subject: [PATCH 315/634] Administration: Fix the CSS Coding Standards in sunrise colors.scss. Lints the `src/wp-admin/css/colors/sunrise/colors.scss` file. Part of the ongoing effort to lint all the admin CSS files. Developed in https://github.com/WordPress/wordpress-develop/pull/13176 See #65898. git-svn-id: https://develop.svn.wordpress.org/trunk@63388 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/css/colors/sunrise/colors.scss | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/wp-admin/css/colors/sunrise/colors.scss b/src/wp-admin/css/colors/sunrise/colors.scss index 3a00c91778d79..a1ef34054906e 100644 --- a/src/wp-admin/css/colors/sunrise/colors.scss +++ b/src/wp-admin/css/colors/sunrise/colors.scss @@ -1,10 +1,10 @@ @use "../_admin.scss" with ( - $scheme-name: "sunrise", - $base-color: #8a312d, - $highlight-color: #ad631e, - $notification-color: #ccaf0b, - $menu-highlight-text: #fff, - $menu-highlight-icon: #fff, - $menu-bubble-text: #1e1e1e, - $menu-submenu-focus-text: #fff + $scheme-name: "sunrise", + $base-color: #8a312d, + $highlight-color: #ad631e, + $notification-color: #ccaf0b, + $menu-highlight-text: #fff, + $menu-highlight-icon: #fff, + $menu-bubble-text: #1e1e1e, + $menu-submenu-focus-text: #fff ); From 0953851a48c728b608a437cd5e8380c044544805 Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Fri, 28 Aug 2026 09:44:02 +0000 Subject: [PATCH 316/634] Administration: Fix the CSS Coding Standards in _variables.scss. Lints the `src/wp-admin/css/colors/_variables.scss` file. Part of the ongoing effort to lint all the admin CSS files. Developed in https://github.com/WordPress/wordpress-develop/pull/13175 See #65898. git-svn-id: https://develop.svn.wordpress.org/trunk@63389 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/css/colors/_variables.scss | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/wp-admin/css/colors/_variables.scss b/src/wp-admin/css/colors/_variables.scss index d37c2b1392f00..6c0c15f4bb3ab 100644 --- a/src/wp-admin/css/colors/_variables.scss +++ b/src/wp-admin/css/colors/_variables.scss @@ -15,7 +15,6 @@ $icon-color: hsl(color.channel($base-color, "hue", $space: hsl), 7%, 95%) !defau $highlight-color: #0073aa !default; $notification-color: #d54e21 !default; - // global $body-background: $gray-100 !default; @@ -42,7 +41,7 @@ $menu-current-text: $menu-highlight-text !default; $menu-current-icon: $menu-highlight-icon !default; $menu-current-background: $menu-highlight-background !default; -$menu-submenu-text: color.mix( $base-color, $text-color, 30% ) !default; +$menu-submenu-text: color.mix($base-color, $text-color, 30%) !default; $menu-submenu-background: color.adjust($base-color, $lightness: -7%) !default; $menu-submenu-background-alt: color.adjust(color.adjust($menu-background, $lightness: 7%), $saturation: -7%) !default; @@ -64,9 +63,9 @@ $adminbar-input-background: color.adjust($menu-background, $lightness: 7%) !defa $adminbar-recovery-exit-text: $menu-bubble-text !default; $adminbar-recovery-exit-background: $menu-bubble-background !default; -$adminbar-recovery-exit-background-alt: color.mix(black, $adminbar-recovery-exit-background, 10%) !default; +$adminbar-recovery-exit-background-alt: color.mix(#000, $adminbar-recovery-exit-background, 10%) !default; -$menu-customizer-text: color.mix( $base-color, $text-color, 40% ) !default; +$menu-customizer-text: color.mix($base-color, $text-color, 40%) !default; // Dashboard Colors From 1bff82b2820bbcc98b2da751f8a8c1c07701e93e Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Fri, 28 Aug 2026 09:46:42 +0000 Subject: [PATCH 317/634] Administration: Fix the CSS Coding Standards in _mixins.scss. Lints the `src/wp-admin/css/colors/_mixins.scss` file. Part of the ongoing effort to lint all the admin CSS files. Developed in https://github.com/WordPress/wordpress-develop/pull/13173 See #65898. git-svn-id: https://develop.svn.wordpress.org/trunk@63390 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/css/colors/_mixins.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp-admin/css/colors/_mixins.scss b/src/wp-admin/css/colors/_mixins.scss index 9575f1f2d623b..7b3802307a637 100644 --- a/src/wp-admin/css/colors/_mixins.scss +++ b/src/wp-admin/css/colors/_mixins.scss @@ -1,5 +1,5 @@ -@use 'sass:color'; -@use 'tokens'; +@use "sass:color"; +@use "tokens"; /* * Button mixin - creates a primary button effect. From f3c74e13a9afdb95ca7ad68a5fd69fe5aa1f61bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Zi=C3=B3=C5=82kowski?= Date: Fri, 28 Aug 2026 11:09:30 +0000 Subject: [PATCH 318/634] Abilities API: Add missing `@since 7.1.0` changelog entries Document the 7.1 changes to existing docblocks that had no changelog line: the `public` meta argument, the `wp_ability_validate_input` and `wp_ability_validate_output` filters, exception handling in `invoke_callback()`, and the new schema property and collection parameters in the REST list controller. Follow-up to [62238], [62398], [62420], [62548], [62729], [62737]. Props khokansardar. See #65058, #64311, #64990, #65568. git-svn-id: https://develop.svn.wordpress.org/trunk@63391 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/abilities-api.php | 1 + .../abilities-api/class-wp-abilities-registry.php | 2 ++ src/wp-includes/abilities-api/class-wp-ability.php | 5 +++++ .../endpoints/class-wp-rest-abilities-v1-list-controller.php | 2 ++ 4 files changed, 10 insertions(+) diff --git a/src/wp-includes/abilities-api.php b/src/wp-includes/abilities-api.php index 92e13f1b489fc..393e40b56ed8c 100644 --- a/src/wp-includes/abilities-api.php +++ b/src/wp-includes/abilities-api.php @@ -232,6 +232,7 @@ * ), * * @since 6.9.0 + * @since 7.1.0 Added the `public` meta argument. * @since 7.2.0 The `category` argument is now optional and defaults to `uncategorized`. * * @see WP_Abilities_Registry::register() diff --git a/src/wp-includes/abilities-api/class-wp-abilities-registry.php b/src/wp-includes/abilities-api/class-wp-abilities-registry.php index cc795a1a8a430..813c3dd49f7be 100644 --- a/src/wp-includes/abilities-api/class-wp-abilities-registry.php +++ b/src/wp-includes/abilities-api/class-wp-abilities-registry.php @@ -40,6 +40,7 @@ final class WP_Abilities_Registry { * Do not use this method directly. Instead, use the `wp_register_ability()` function. * * @since 6.9.0 + * @since 7.1.0 Added the `public` meta argument. * @since 7.2.0 The `category` argument is now optional and defaults to `uncategorized`. * * @see wp_register_ability() @@ -110,6 +111,7 @@ public function register( string $name, array $args ): ?WP_Ability { * Filters the ability arguments before they are validated and used to instantiate the ability. * * @since 6.9.0 + * @since 7.1.0 Added the `public` meta argument. * @since 7.2.0 The `category` argument is now optional and defaults to `uncategorized`. * * @param array $args { diff --git a/src/wp-includes/abilities-api/class-wp-ability.php b/src/wp-includes/abilities-api/class-wp-ability.php index 9efefc6713f5a..8f2d431f05318 100644 --- a/src/wp-includes/abilities-api/class-wp-ability.php +++ b/src/wp-includes/abilities-api/class-wp-ability.php @@ -139,6 +139,7 @@ class WP_Ability { * @access private * * @since 6.9.0 + * @since 7.1.0 Added the `public` meta argument. * * @see wp_register_ability() * @@ -209,6 +210,7 @@ public function __construct( string $name, array $args ) { * caught and converted to a WP_Error by WP_Abilities_Registry::register(). * * @since 6.9.0 + * @since 7.1.0 Added the `public` meta argument. * * @see WP_Abilities_Registry::register() * @@ -512,6 +514,7 @@ public function normalize_input( $input = null ) { * Validates input data against the input schema. * * @since 6.9.0 + * @since 7.1.0 Added the `wp_ability_validate_input` filter. * * @param mixed $input Optional. The input data to validate. Default `null`. * @return true|WP_Error Returns true if valid or the WP_Error object if validation fails. @@ -577,6 +580,7 @@ public function validate_input( $input = null ) { * Invokes a callable, ensuring the input is passed through only if the input schema is defined. * * @since 6.9.0 + * @since 7.1.0 Exceptions thrown by the callback are now caught and returned as a `WP_Error`. * * @param callable $callback The callable to invoke. * @param mixed $input Optional. The input data for the ability. Default `null`. @@ -705,6 +709,7 @@ protected function do_execute( $input = null ) { * Validates output data against the output schema. * * @since 6.9.0 + * @since 7.1.0 Added the `wp_ability_validate_output` filter. * * @param mixed $output The output data to validate. * @return true|WP_Error Returns true if valid, or a WP_Error object if validation fails. diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-abilities-v1-list-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-abilities-v1-list-controller.php index 97d97ce379e8d..5547e7e002f02 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-abilities-v1-list-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-abilities-v1-list-controller.php @@ -244,6 +244,7 @@ public function prepare_item_for_response( $ability, $request ) { * Retrieves the ability's schema, conforming to JSON Schema. * * @since 6.9.0 + * @since 7.1.0 Added the `meta.public` property. * * @return array Item schema data. */ @@ -330,6 +331,7 @@ public function get_item_schema(): array { * Retrieves the query params for collections. * * @since 6.9.0 + * @since 7.1.0 Added the `namespace` and `meta` parameters and the `rest_abilities_collection_params` filter. * * @return array Collection parameters. */ From 06c6908f94a20f7b92cc7e905c5377f2431c1ed4 Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Fri, 28 Aug 2026 13:23:59 +0000 Subject: [PATCH 319/634] Build/Test Tools: Update the `lint:jsdoc` configuration to be compatible with ESLint v10. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The JSDoc ESLint script is meant to check the JSDocs conformity with the ​WordPress JavaScript Docs Coding Standards. It was added in the context of ​the ​JavaScript Inline Docs Initiative, aimed to improve JavaScript documentation across the codebase. The new ESLint v10 provided by `@wordpress/scripts` requires a different configuration format. This change updates the configuration as needed, replicating as much as possible the previous configuration based on the `valid-jsdoc` rules. Developed in https://github.com/WordPress/wordpress-develop/pull/13237 Props afercia, mciampini. Fixes #65939. git-svn-id: https://develop.svn.wordpress.org/trunk@63392 602fd350-edb4-49c9-b593-d223f7449a82 --- .eslintignore | 26 -------------- .eslintrc-jsdoc.js | 85 +++++++++++++++++++++++++++++++--------------- eslint.config.js | 38 +++++++++++++++++++++ 3 files changed, 96 insertions(+), 53 deletions(-) delete mode 100644 .eslintignore create mode 100644 eslint.config.js diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 9b3144df5c64d..0000000000000 --- a/.eslintignore +++ /dev/null @@ -1,26 +0,0 @@ -# Files and folders related to build/test tools including generated files -/build -/node_modules -/tests -/vendor -/tools -/jsdoc -/artifacts -/coverage -.cache/* -/src/wp-includes/blocks/**/*.js -/src/wp-includes/blocks/**/*.js.map -/src/wp-admin/js -/src/wp-includes/js - -# Excluded files and folders based on `jsdoc.conf.json` exclusions -/src/js/_enqueues/vendor - -# Themes -src/wp-content/themes - -# Files and folders that get created in wp-content -/src/wp-content/plugins -/src/wp-content/mu-plugins -/src/wp-content/upgrade -/src/wp-content/uploads diff --git a/.eslintrc-jsdoc.js b/.eslintrc-jsdoc.js index 6f7351ec08945..1e1059efeed2a 100644 --- a/.eslintrc-jsdoc.js +++ b/.eslintrc-jsdoc.js @@ -1,29 +1,60 @@ -module.exports = { - rules: { - 'require-jsdoc': 'off', - 'valid-jsdoc': [ 'error', { - prefer: { - arg: 'param', - argument: 'param', - extends: 'augments', - returns: 'return', +/** + * ESLint v10 flat config file for JSDoc linting. + * This config is based on the original valid-jsdoc rules. + */ + +const jsdocPlugin = require( 'eslint-plugin-jsdoc' ); + +module.exports = [ + { + plugins: { + jsdoc: jsdocPlugin, + }, + settings: { + jsdoc: { + tagNamePreference: { + 'arg': 'param', + 'argument': 'param', + 'extends': 'augments', + 'returns': 'return', + }, + preferredTypes: { + 'array': 'Array', + 'bool': 'boolean', + 'Boolean': 'boolean', + 'float': 'number', + 'Float': 'number', + 'function': 'Function', + 'int': 'number', + 'integer': 'number', + 'Integer': 'number', + 'Number': 'number', + 'object': 'Object', + 'String': 'string', + 'Void': 'void', + }, }, - preferType: { - array: 'Array', - bool: 'boolean', - Boolean: 'boolean', - float: 'number', - Float: 'number', - int: 'number', - integer: 'number', - Integer: 'number', - Number: 'number', - object: 'Object', - String: 'string', - Void: 'void', - }, - requireParamDescription: false, - requireReturn: false, - } ], + }, + rules: { + 'jsdoc/check-param-names': 'error', + 'jsdoc/check-types': 'error', + 'jsdoc/check-tag-names': [ 'error', { + definedTags: [ + 'memberOf', + 'output', + 'ticket', + 'link', + ], + } ], + 'jsdoc/require-param': [ 'error', { + enableFixer: false, + } ], + 'jsdoc/require-param-type': 'error', + 'jsdoc/require-returns-check': 'error', + 'jsdoc/require-returns-description': 'error', + 'jsdoc/require-returns': 'error', + 'jsdoc/require-returns-type': 'error', + 'jsdoc/check-syntax': 'error', + }, }, -}; +]; diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000000000..a3f2f384d7d7b --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,38 @@ +/** + * ESLint v10 flat config entry point. + * + * This minimal config focuses only on JSDoc linting by importing + * the configuration from .eslintrc-jsdoc.js. + * + * General JavaScript linting is not performed here. + */ + +const jsdocConfig = require( './.eslintrc-jsdoc.js' ); + +module.exports = [ + ...jsdocConfig, + { + ignores: [ + 'build/**', + '**/build/**', + 'node_modules/**', + 'tests/**', + 'vendor/**', + 'tools/**', + 'jsdoc/**', + 'artifacts/**', + 'coverage/**', + '.cache/**', + 'src/wp-includes/blocks/**/*.js', + 'src/wp-includes/blocks/**/*.js.map', + 'src/wp-content/themes/**', + 'src/wp-content/plugins/**', + 'src/wp-content/mu-plugins/**', + 'src/wp-content/upgrade/**', + 'src/wp-content/uploads/**', + 'src/js/_enqueues/vendor/**', + 'src/wp-admin/js/**', + 'src/wp-includes/js/**', + ], + }, +]; From 67c01d5705e932507dd0f30d3b439ec7dafd0282 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Fri, 28 Aug 2026 21:09:19 +0000 Subject: [PATCH 320/634] XML-RPC: Require the `$fields` argument to be an array. Ten `wp.*` methods accept an optional `$fields` argument from the client and pass it straight through to the `_prepare_*()` helpers, where `in_array()` raises a fatal `TypeError` as soon as the value is not an array. A new `wp_xmlrpc_server::_is_fields_array()` helper now checks the argument up front, so a malformed request returns a 400 `IXR_Error` to the client instead of taking the request down with a fatal error. The affected methods are `wp.getPost`, `wp.getPosts`, `wp.getTaxonomy`, `wp.getTaxonomies`, `wp.getUser`, `wp.getUsers`, `wp.getProfile`, `wp.getPostType`, `wp.getPostTypes`, and `wp.getRevisions`. Unit tests covering each of them are included, along with the `@since` entries that were missing from `wp_getUser()`, `wp_getUsers()`, and `wp_getProfile()`. Developed in https://github.com/WordPress/wordpress-develop/pull/13299. Props josephscott, westonruter. Fixes #65983. git-svn-id: https://develop.svn.wordpress.org/trunk@63393 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/class-wp-xmlrpc-server.php | 75 +++++++++++++++++++ tests/phpunit/tests/xmlrpc/wp/getPost.php | 12 +++ tests/phpunit/tests/xmlrpc/wp/getPostType.php | 14 ++++ .../phpunit/tests/xmlrpc/wp/getPostTypes.php | 14 ++++ tests/phpunit/tests/xmlrpc/wp/getPosts.php | 14 ++++ tests/phpunit/tests/xmlrpc/wp/getProfile.php | 14 ++++ .../phpunit/tests/xmlrpc/wp/getRevisions.php | 15 ++++ .../phpunit/tests/xmlrpc/wp/getTaxonomies.php | 14 ++++ tests/phpunit/tests/xmlrpc/wp/getTaxonomy.php | 14 ++++ tests/phpunit/tests/xmlrpc/wp/getUser.php | 12 +++ tests/phpunit/tests/xmlrpc/wp/getUsers.php | 14 ++++ 11 files changed, 212 insertions(+) diff --git a/src/wp-includes/class-wp-xmlrpc-server.php b/src/wp-includes/class-wp-xmlrpc-server.php index 1061dbd1831d2..506b3faebd1c8 100644 --- a/src/wp-includes/class-wp-xmlrpc-server.php +++ b/src/wp-includes/class-wp-xmlrpc-server.php @@ -808,6 +808,25 @@ protected function minimum_args( $args, $count ) { return true; } + /** + * Checks that the `$fields` argument received from a client is an array. + * + * @since 7.2.0 + * + * @param mixed $fields The `$fields` argument to check. + * @return bool True if `$fields` is an array, false otherwise. + * + * @phpstan-assert-if-true array $fields + */ + protected function _is_fields_array( $fields ): bool { + if ( ! is_array( $fields ) ) { + $this->error = new IXR_Error( 400, __( 'The fields argument must be an array.' ) ); + return false; + } + + return true; + } + /** * Prepares taxonomy data for return in an XML-RPC object. * @@ -1871,6 +1890,7 @@ public function wp_deletePost( $args ) { * Retrieves a post. * * @since 3.4.0 + * @since 7.2.0 Returns an error if the `$fields` argument is not an array. * * The optional $fields parameter specifies what fields will be included * in the response array. This should be a list of field names. 'post_id' will @@ -1928,6 +1948,10 @@ public function wp_getPost( $args ) { $post_id = (int) $args[3]; if ( isset( $args[4] ) ) { + if ( ! $this->_is_fields_array( $args[4] ) ) { + return $this->error; + } + $fields = $args[4]; } else { /** @@ -1967,6 +1991,7 @@ public function wp_getPost( $args ) { * Retrieves posts. * * @since 3.4.0 + * @since 7.2.0 Returns an error if the `$fields` argument is not an array. * * @see wp_get_recent_posts() * @see wp_getPost() for more on `$fields` @@ -1997,6 +2022,10 @@ public function wp_getPosts( $args ) { $filter = $args[3] ?? array(); if ( isset( $args[4] ) ) { + if ( ! $this->_is_fields_array( $args[4] ) ) { + return $this->error; + } + $fields = $args[4]; } else { /** This action is documented in wp-includes/class-wp-xmlrpc-server.php */ @@ -2534,6 +2563,7 @@ public function wp_getTerms( $args ) { * Retrieves a taxonomy. * * @since 3.4.0 + * @since 7.2.0 Returns an error if the `$fields` argument is not an array. * * @see get_taxonomy() * @@ -2562,6 +2592,10 @@ public function wp_getTaxonomy( $args ) { $taxonomy = $args[3]; if ( isset( $args[4] ) ) { + if ( ! $this->_is_fields_array( $args[4] ) ) { + return $this->error; + } + $fields = $args[4]; } else { /** @@ -2601,6 +2635,7 @@ public function wp_getTaxonomy( $args ) { * Retrieves all taxonomies. * * @since 3.4.0 + * @since 7.2.0 Returns an error if the `$fields` argument is not an array. * * @see get_taxonomies() * @@ -2628,6 +2663,10 @@ public function wp_getTaxonomies( $args ) { $filter = $args[3] ?? array( 'public' => true ); if ( isset( $args[4] ) ) { + if ( ! $this->_is_fields_array( $args[4] ) ) { + return $this->error; + } + $fields = $args[4]; } else { /** This action is documented in wp-includes/class-wp-xmlrpc-server.php */ @@ -2670,6 +2709,9 @@ public function wp_getTaxonomies( $args ) { * names can be used to specify multiple fields. The available conceptual * groups are 'basic' and 'all'. * + * @since 3.5.0 + * @since 7.2.0 Returns an error if the `$fields` argument is not an array. + * * @uses get_userdata() * * @param array $args { @@ -2707,6 +2749,10 @@ public function wp_getUser( $args ) { $user_id = (int) $args[3]; if ( isset( $args[4] ) ) { + if ( ! $this->_is_fields_array( $args[4] ) ) { + return $this->error; + } + $fields = $args[4]; } else { /** @@ -2751,6 +2797,9 @@ public function wp_getUser( $args ) { * The optional $fields parameter specifies what fields will be included * in the response array. * + * @since 3.5.0 + * @since 7.2.0 Returns an error if the `$fields` argument is not an array. + * * @uses get_users() * @see wp_getUser() for more on $fields and return values * @@ -2777,6 +2826,10 @@ public function wp_getUsers( $args ) { $filter = $args[3] ?? array(); if ( isset( $args[4] ) ) { + if ( ! $this->_is_fields_array( $args[4] ) ) { + return $this->error; + } + $fields = $args[4]; } else { /** This action is documented in wp-includes/class-wp-xmlrpc-server.php */ @@ -2834,6 +2887,9 @@ public function wp_getUsers( $args ) { /** * Retrieves information about the requesting user. * + * @since 3.5.0 + * @since 7.2.0 Returns an error if the `$fields` argument is not an array. + * * @uses get_userdata() * * @param array $args { @@ -2857,6 +2913,10 @@ public function wp_getProfile( $args ) { $password = $args[2]; if ( isset( $args[3] ) ) { + if ( ! $this->_is_fields_array( $args[3] ) ) { + return $this->error; + } + $fields = $args[3]; } else { /** This action is documented in wp-includes/class-wp-xmlrpc-server.php */ @@ -4533,6 +4593,7 @@ public function wp_getPostFormats( $args ) { * Retrieves a post type. * * @since 3.4.0 + * @since 7.2.0 Returns an error if the `$fields` argument is not an array. * * @see get_post_type_object() * @@ -4568,6 +4629,10 @@ public function wp_getPostType( $args ) { $post_type_name = $args[3]; if ( isset( $args[4] ) ) { + if ( ! $this->_is_fields_array( $args[4] ) ) { + return $this->error; + } + $fields = $args[4]; } else { /** @@ -4607,6 +4672,7 @@ public function wp_getPostType( $args ) { * Retrieves post types. * * @since 3.4.0 + * @since 7.2.0 Returns an error if the `$fields` argument is not an array. * * @see get_post_types() * @@ -4633,6 +4699,10 @@ public function wp_getPostTypes( $args ) { $filter = $args[3] ?? array( 'public' => true ); if ( isset( $args[4] ) ) { + if ( ! $this->_is_fields_array( $args[4] ) ) { + return $this->error; + } + $fields = $args[4]; } else { /** This action is documented in wp-includes/class-wp-xmlrpc-server.php */ @@ -4666,6 +4736,7 @@ public function wp_getPostTypes( $args ) { * Retrieves revisions for a specific post. * * @since 3.5.0 + * @since 7.2.0 Returns an error if the `$fields` argument is not an array. * * The optional $fields parameter specifies what fields will be included * in the response array. @@ -4696,6 +4767,10 @@ public function wp_getRevisions( $args ) { $post_id = (int) $args[3]; if ( isset( $args[4] ) ) { + if ( ! $this->_is_fields_array( $args[4] ) ) { + return $this->error; + } + $fields = $args[4]; } else { /** diff --git a/tests/phpunit/tests/xmlrpc/wp/getPost.php b/tests/phpunit/tests/xmlrpc/wp/getPost.php index be25ca2770238..72a0685a8a11a 100644 --- a/tests/phpunit/tests/xmlrpc/wp/getPost.php +++ b/tests/phpunit/tests/xmlrpc/wp/getPost.php @@ -147,4 +147,16 @@ public function test_valid_page() { $this->assertEquals( $parent_page_id, $result['post_parent'] ); $this->assertSame( 2, $result['menu_order'] ); } + + /** + * Ensure a non-array `$fields` argument is rejected instead of causing a fatal error. + * + * @ticket 65983 + */ + public function test_non_array_fields_returns_error(): void { + $result = $this->myxmlrpcserver->wp_getPost( array( 1, 'author', 'author', $this->post_id, 'post' ) ); + + $this->assertIXRError( $result ); + $this->assertSame( 400, $result->code ); + } } diff --git a/tests/phpunit/tests/xmlrpc/wp/getPostType.php b/tests/phpunit/tests/xmlrpc/wp/getPostType.php index 0a791d3517581..f3f34cc1bd9ab 100644 --- a/tests/phpunit/tests/xmlrpc/wp/getPostType.php +++ b/tests/phpunit/tests/xmlrpc/wp/getPostType.php @@ -123,4 +123,18 @@ public function test_valid_type() { $this->assertSame( $value, $result[ $key ] ); } } + + /** + * Ensure a non-array `$fields` argument is rejected instead of causing a fatal error. + * + * @ticket 65983 + */ + public function test_non_array_fields_returns_error(): void { + $this->make_user_by_role( 'editor' ); + + $result = $this->myxmlrpcserver->wp_getPostType( array( 1, 'editor', 'editor', 'post', 'labels' ) ); + + $this->assertIXRError( $result ); + $this->assertSame( 400, $result->code ); + } } diff --git a/tests/phpunit/tests/xmlrpc/wp/getPostTypes.php b/tests/phpunit/tests/xmlrpc/wp/getPostTypes.php index cb12c6958e29f..dbd94ec33007f 100644 --- a/tests/phpunit/tests/xmlrpc/wp/getPostTypes.php +++ b/tests/phpunit/tests/xmlrpc/wp/getPostTypes.php @@ -40,4 +40,18 @@ public function test_simple_filter() { $this->assertContains( 'page', $result_names ); $this->assertNotContains( 'post', $result_names ); } + + /** + * Ensure a non-array `$fields` argument is rejected instead of causing a fatal error. + * + * @ticket 65983 + */ + public function test_non_array_fields_returns_error(): void { + $this->make_user_by_role( 'editor' ); + + $result = $this->myxmlrpcserver->wp_getPostTypes( array( 1, 'editor', 'editor', array(), 'labels' ) ); + + $this->assertIXRError( $result ); + $this->assertSame( 400, $result->code ); + } } diff --git a/tests/phpunit/tests/xmlrpc/wp/getPosts.php b/tests/phpunit/tests/xmlrpc/wp/getPosts.php index 1369aaaae2844..b1ab560886eb9 100644 --- a/tests/phpunit/tests/xmlrpc/wp/getPosts.php +++ b/tests/phpunit/tests/xmlrpc/wp/getPosts.php @@ -169,4 +169,18 @@ public function test_search() { $this->assertNotIXRError( $results ); $this->assertCount( 1, $results ); } + + /** + * Ensure a non-array `$fields` argument is rejected instead of causing a fatal error. + * + * @ticket 65983 + */ + public function test_non_array_fields_returns_error(): void { + $this->make_user_by_role( 'editor' ); + + $result = $this->myxmlrpcserver->wp_getPosts( array( 1, 'editor', 'editor', array(), 'post' ) ); + + $this->assertIXRError( $result ); + $this->assertSame( 400, $result->code ); + } } diff --git a/tests/phpunit/tests/xmlrpc/wp/getProfile.php b/tests/phpunit/tests/xmlrpc/wp/getProfile.php index 9893243cc6f26..c9325ade3d670 100644 --- a/tests/phpunit/tests/xmlrpc/wp/getProfile.php +++ b/tests/phpunit/tests/xmlrpc/wp/getProfile.php @@ -45,4 +45,18 @@ public function test_arbitrary_fields() { sort( $keys ); $this->assertSameSets( $expected_fields, $keys ); } + + /** + * Ensure a non-array `$fields` argument is rejected instead of causing a fatal error. + * + * @ticket 65983 + */ + public function test_non_array_fields_returns_error(): void { + $this->make_user_by_role( 'editor' ); + + $result = $this->myxmlrpcserver->wp_getProfile( array( 1, 'editor', 'editor', 'all' ) ); + + $this->assertIXRError( $result ); + $this->assertSame( 400, $result->code ); + } } diff --git a/tests/phpunit/tests/xmlrpc/wp/getRevisions.php b/tests/phpunit/tests/xmlrpc/wp/getRevisions.php index 893a7a06dae93..01d8614460d8d 100644 --- a/tests/phpunit/tests/xmlrpc/wp/getRevisions.php +++ b/tests/phpunit/tests/xmlrpc/wp/getRevisions.php @@ -77,4 +77,19 @@ public function test_revision_count_for_auto_draft_post_creation() { $result = $this->myxmlrpcserver->wp_getRevisions( array( 1, 'editor', 'editor', $post_id ) ); $this->assertCount( 1, $result ); } + + /** + * Ensure a non-array `$fields` argument is rejected instead of causing a fatal error. + * + * @ticket 65983 + */ + public function test_non_array_fields_returns_error(): void { + $this->make_user_by_role( 'editor' ); + $post_id = self::factory()->post->create(); + + $result = $this->myxmlrpcserver->wp_getRevisions( array( 1, 'editor', 'editor', $post_id, 'post_date' ) ); + + $this->assertIXRError( $result ); + $this->assertSame( 400, $result->code ); + } } diff --git a/tests/phpunit/tests/xmlrpc/wp/getTaxonomies.php b/tests/phpunit/tests/xmlrpc/wp/getTaxonomies.php index 13c78781813c0..ab5cadb19f8a6 100644 --- a/tests/phpunit/tests/xmlrpc/wp/getTaxonomies.php +++ b/tests/phpunit/tests/xmlrpc/wp/getTaxonomies.php @@ -17,4 +17,18 @@ public function test_taxonomy_validated() { $result = $this->myxmlrpcserver->wp_getTaxonomies( array( 1, 'editor', 'editor' ) ); $this->assertNotIXRError( $result ); } + + /** + * Ensure a non-array `$fields` argument is rejected instead of causing a fatal error. + * + * @ticket 65983 + */ + public function test_non_array_fields_returns_error(): void { + $this->make_user_by_role( 'editor' ); + + $result = $this->myxmlrpcserver->wp_getTaxonomies( array( 1, 'editor', 'editor', array(), 'labels' ) ); + + $this->assertIXRError( $result ); + $this->assertSame( 400, $result->code ); + } } diff --git a/tests/phpunit/tests/xmlrpc/wp/getTaxonomy.php b/tests/phpunit/tests/xmlrpc/wp/getTaxonomy.php index be94db724d1ca..59e65b9e54c04 100644 --- a/tests/phpunit/tests/xmlrpc/wp/getTaxonomy.php +++ b/tests/phpunit/tests/xmlrpc/wp/getTaxonomy.php @@ -75,4 +75,18 @@ public function test_taxonomy_with_menu_field_specified() { $this->assertNotIXRError( $result ); $this->assertTrue( $result['show_in_menu'] ); } + + /** + * Ensure a non-array `$fields` argument is rejected instead of causing a fatal error. + * + * @ticket 65983 + */ + public function test_non_array_fields_returns_error(): void { + $this->make_user_by_role( 'editor' ); + + $result = $this->myxmlrpcserver->wp_getTaxonomy( array( 1, 'editor', 'editor', 'category', 'labels' ) ); + + $this->assertIXRError( $result ); + $this->assertSame( 400, $result->code ); + } } diff --git a/tests/phpunit/tests/xmlrpc/wp/getUser.php b/tests/phpunit/tests/xmlrpc/wp/getUser.php index c9392bb1ce312..8cfb34ae3e7eb 100644 --- a/tests/phpunit/tests/xmlrpc/wp/getUser.php +++ b/tests/phpunit/tests/xmlrpc/wp/getUser.php @@ -140,4 +140,16 @@ public function test_arbitrary_fields() { sort( $keys ); $this->assertSameSets( $expected_fields, $keys ); } + + /** + * Ensure a non-array `$fields` argument is rejected instead of causing a fatal error. + * + * @ticket 65983 + */ + public function test_non_array_fields_returns_error(): void { + $result = $this->myxmlrpcserver->wp_getUser( array( 1, 'administrator', 'administrator', $this->administrator_id, 'all' ) ); + + $this->assertIXRError( $result ); + $this->assertSame( 400, $result->code ); + } } diff --git a/tests/phpunit/tests/xmlrpc/wp/getUsers.php b/tests/phpunit/tests/xmlrpc/wp/getUsers.php index 2c8c4ec245cb3..a0eeee4026645 100644 --- a/tests/phpunit/tests/xmlrpc/wp/getUsers.php +++ b/tests/phpunit/tests/xmlrpc/wp/getUsers.php @@ -125,4 +125,18 @@ public function test_order_filters() { $last_email = $user['email']; } } + + /** + * Ensure a non-array `$fields` argument is rejected instead of causing a fatal error. + * + * @ticket 65983 + */ + public function test_non_array_fields_returns_error(): void { + $this->make_user_by_role( 'administrator' ); + + $result = $this->myxmlrpcserver->wp_getUsers( array( 1, 'administrator', 'administrator', array(), 'all' ) ); + + $this->assertIXRError( $result ); + $this->assertSame( 400, $result->code ); + } } From 33a4f876c7c13ffe8e0b13ac06737e24c0bf4184 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Fri, 28 Aug 2026 21:27:00 +0000 Subject: [PATCH 321/634] Feeds: Add a filterable list of XML namespaces. The `rss2_ns`, `rss2_comments_ns`, `rdf_ns`, `atom_ns`, and `atom_comments_ns` actions are echo-only: a callback prints its `xmlns` attribute straight into the feed's root element with no way to know what another callback already printed. Two plugins declaring the same namespace therefore emit a duplicate attribute, which is a well-formedness error, so every strict consumer rejects the whole feed rather than just ignoring the repetition. The new `wp_get_feed_namespaces()` and `wp_feed_namespaces()` functions build and print that list from a `wp_feed_namespaces` filter, keyed by prefix so the same prefix cannot be declared twice. Prefixes are validated as XML names, with the reserved `xml` and `xmlns` rejected, and namespace URIs are escaped on output. The namespaces previously hard-coded in the bundled feed templates now come from this list and are merged back in after the filter runs, so a callback can neither remove them nor duplicate them. The `*_ns` actions are left in place and still fire, so a plugin echoing a namespace through one of them behaves exactly as before. Their documentation now points to the filter as the safer alternative. Developed in https://github.com/WordPress/wordpress-develop/pull/12812. Props pfefferle, westonruter, abcd95. Fixes #65785. git-svn-id: https://develop.svn.wordpress.org/trunk@63394 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/feed-atom-comments.php | 6 +- src/wp-includes/feed-atom.php | 6 +- src/wp-includes/feed-rdf.php | 10 +- src/wp-includes/feed-rss2-comments.php | 9 +- src/wp-includes/feed-rss2.php | 11 +- src/wp-includes/feed.php | 120 ++++++++++ tests/phpunit/tests/feed/feedNamespaces.php | 250 ++++++++++++++++++++ tests/phpunit/tests/feed/rss2.php | 37 +++ 8 files changed, 432 insertions(+), 17 deletions(-) create mode 100644 tests/phpunit/tests/feed/feedNamespaces.php diff --git a/src/wp-includes/feed-atom-comments.php b/src/wp-includes/feed-atom-comments.php index 1de77e391794d..2563e1f11e604 100644 --- a/src/wp-includes/feed-atom-comments.php +++ b/src/wp-includes/feed-atom-comments.php @@ -14,14 +14,18 @@ @@ -26,6 +24,9 @@ /** * Fires at the end of the RSS root to add namespaces. * + * Consider using the {@see 'wp_feed_namespaces'} filter instead, which + * prevents duplicate `xmlns` attributes. + * * @since 2.8.0 */ do_action( 'rss2_comments_ns' ); diff --git a/src/wp-includes/feed-rss2.php b/src/wp-includes/feed-rss2.php index 8b30313e6d606..0de3a3d9f4671 100644 --- a/src/wp-includes/feed-rss2.php +++ b/src/wp-includes/feed-rss2.php @@ -21,16 +21,15 @@ do_action( 'rss_tag_pre', 'rss2' ); ?> Array of namespace URIs, keyed by their prefix. + * @phpstan-param non-falsy-string $type + * @phpstan-return array + */ +function wp_get_feed_namespaces( string $type ): array { + $defaults = array(); + + switch ( $type ) { + case 'rss2': + $defaults = array( + 'content' => 'http://purl.org/rss/1.0/modules/content/', + 'wfw' => 'http://wellformedweb.org/CommentAPI/', + 'dc' => 'http://purl.org/dc/elements/1.1/', + 'atom' => 'http://www.w3.org/2005/Atom', + 'sy' => 'http://purl.org/rss/1.0/modules/syndication/', + 'slash' => 'http://purl.org/rss/1.0/modules/slash/', + ); + break; + + case 'rss2-comments': + $defaults = array( + 'content' => 'http://purl.org/rss/1.0/modules/content/', + 'dc' => 'http://purl.org/dc/elements/1.1/', + 'atom' => 'http://www.w3.org/2005/Atom', + 'sy' => 'http://purl.org/rss/1.0/modules/syndication/', + ); + break; + + case 'rdf': + $defaults = array( + 'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', + 'dc' => 'http://purl.org/dc/elements/1.1/', + 'sy' => 'http://purl.org/rss/1.0/modules/syndication/', + 'admin' => 'http://webns.net/mvcb/', + 'content' => 'http://purl.org/rss/1.0/modules/content/', + ); + break; + + case 'atom': + case 'atom-comments': + $defaults = array( + 'thr' => 'http://purl.org/syndication/thread/1.0', + ); + break; + } + + /** + * Filters the XML namespaces of a feed's root element. + * + * Namespaces are keyed by their prefix, which makes duplicate `xmlns` + * attributes impossible. + * + * @since 7.2.0 + * + * @param array $namespaces Array of namespace URIs, keyed by their prefix. + * @param string $type Type of feed. Possible values include 'rss2', + * 'rss2-comments', 'rdf', 'atom', and 'atom-comments'. + */ + $namespaces = apply_filters( 'wp_feed_namespaces', $defaults, $type ); + + if ( ! is_array( $namespaces ) ) { + $namespaces = array(); + } + + // The bundled feed templates use the default namespaces, so they cannot be removed. + $namespaces = array_merge( $namespaces, $defaults ); + + $sanitized = array(); + + foreach ( $namespaces as $prefix => $uri ) { + $prefix = (string) $prefix; + + // Prefixes must be valid XML names, and the `xml` and `xmlns` prefixes are reserved. + if ( ! preg_match( '/^[\p{L}_][\p{L}\p{M}\p{N}._\-\x{B7}]*\z/u', $prefix ) + || in_array( strtolower( $prefix ), array( 'xml', 'xmlns' ), true ) + ) { + continue; + } + + if ( ! is_string( $uri ) || empty( $uri ) ) { + continue; + } + + $sanitized[ $prefix ] = $uri; + } + + return $sanitized; +} + +/** + * Displays the XML namespaces for the root element of a feed. + * + * Plugins should add namespaces via the {@see 'wp_feed_namespaces'} filter instead + * of the older {@see "{$type}_ns"} actions, as two action callbacks printing the + * same namespace produce a duplicate attribute, which is a well-formedness + * error in XML. + * + * @since 7.2.0 + * + * @param string $type Type of feed. Possible values include 'rss2', 'rss2-comments', + * 'rdf', 'atom', and 'atom-comments'. + * @phpstan-param non-falsy-string $type + */ +function wp_feed_namespaces( string $type ): void { + foreach ( wp_get_feed_namespaces( $type ) as $prefix => $uri ) { + printf( "xmlns:%s=\"%s\"\n\t", $prefix, esc_attr( $uri ) ); + } +} + /** * Gets the UTC time of the most recently modified post from WP_Query. * diff --git a/tests/phpunit/tests/feed/feedNamespaces.php b/tests/phpunit/tests/feed/feedNamespaces.php new file mode 100644 index 0000000000000..cc5b823f6c8a4 --- /dev/null +++ b/tests/phpunit/tests/feed/feedNamespaces.php @@ -0,0 +1,250 @@ +assertSameSetsWithIndex( + array( + 'content' => 'http://purl.org/rss/1.0/modules/content/', + 'wfw' => 'http://wellformedweb.org/CommentAPI/', + 'dc' => 'http://purl.org/dc/elements/1.1/', + 'atom' => 'http://www.w3.org/2005/Atom', + 'sy' => 'http://purl.org/rss/1.0/modules/syndication/', + 'slash' => 'http://purl.org/rss/1.0/modules/slash/', + ), + $namespaces + ); + } + + /** + * @ticket 65785 + */ + public function test_should_return_default_atom_namespaces() { + $namespaces = wp_get_feed_namespaces( 'atom' ); + + $this->assertSameSetsWithIndex( + array( + 'thr' => 'http://purl.org/syndication/thread/1.0', + ), + $namespaces + ); + } + + /** + * @ticket 65785 + */ + public function test_should_return_namespace_added_via_filter() { + add_filter( + 'wp_feed_namespaces', + static function ( array $namespaces ): array { + $namespaces['source'] = 'http://source.scripting.com/'; + return $namespaces; + } + ); + + $namespaces = wp_get_feed_namespaces( 'rss2' ); + + $this->assertArrayHasKey( 'source', $namespaces ); + $this->assertSame( 'http://source.scripting.com/', $namespaces['source'] ); + } + + /** + * The feed type is passed to the filter, so namespaces can be added to + * specific feeds only. + * + * @ticket 65785 + */ + public function test_filter_should_receive_the_feed_type() { + add_filter( + 'wp_feed_namespaces', + static function ( array $namespaces, string $type ): array { + if ( 'rss2' === $type ) { + $namespaces['source'] = 'http://source.scripting.com/'; + } + return $namespaces; + }, + 10, + 2 + ); + + $this->assertArrayHasKey( 'source', wp_get_feed_namespaces( 'rss2' ) ); + $this->assertArrayNotHasKey( 'source', wp_get_feed_namespaces( 'atom' ) ); + } + + /** + * The bundled feed templates use the default namespaces in their static + * markup, so a filter must not be able to remove them. + * + * @ticket 65785 + */ + public function test_should_not_allow_removing_default_namespaces() { + add_filter( + 'wp_feed_namespaces', + static function () { + return array( 'media' => 'http://search.yahoo.com/mrss/' ); + } + ); + + $namespaces = wp_get_feed_namespaces( 'rss2' ); + + $this->assertArrayHasKey( 'media', $namespaces ); + $this->assertArrayHasKey( 'content', $namespaces ); + $this->assertArrayHasKey( 'atom', $namespaces ); + } + + /** + * A filter callback without a return value must not break the feed. + * + * @ticket 65785 + */ + public function test_should_handle_a_non_array_filter_return() { + add_filter( 'wp_feed_namespaces', '__return_null' ); + + $namespaces = wp_get_feed_namespaces( 'rss2' ); + + $this->assertArrayHasKey( 'content', $namespaces ); + } + + /** + * @ticket 65785 + */ + public function test_should_skip_invalid_prefixes() { + add_filter( + 'wp_feed_namespaces', + static function ( array $namespaces ): array { + $namespaces[''] = 'http://example.org/empty'; + $namespaces['foo bar'] = 'http://example.org/space'; + $namespaces['"onload="x"'] = 'http://example.org/attack'; + $namespaces['0numeric'] = 'http://example.org/numeric'; + $namespaces['xmlns'] = 'http://example.org/reserved'; + $namespaces['XML'] = 'http://example.org/reserved-too'; + $namespaces['empty-uri'] = ''; + return $namespaces; + } + ); + + $namespaces = wp_get_feed_namespaces( 'rss2' ); + + $this->assertArrayNotHasKey( '', $namespaces ); + $this->assertArrayNotHasKey( 'foo bar', $namespaces ); + $this->assertArrayNotHasKey( '"onload="x"', $namespaces ); + $this->assertArrayNotHasKey( '0numeric', $namespaces ); + $this->assertArrayNotHasKey( 'xmlns', $namespaces ); + $this->assertArrayNotHasKey( 'XML', $namespaces ); + $this->assertArrayNotHasKey( 'empty-uri', $namespaces ); + } + + /** + * A prefix ending in a newline is a distinct array key from the same prefix + * without one, so allowing it through would print the same attribute name + * twice: XML permits whitespace between the name and the `=`. + * + * @ticket 65785 + */ + public function test_should_skip_a_prefix_with_a_trailing_newline() { + add_filter( + 'wp_feed_namespaces', + static function ( array $namespaces ): array { + $namespaces["content\n"] = 'http://example.org/duplicate'; + return $namespaces; + } + ); + + $namespaces = wp_get_feed_namespaces( 'rss2' ); + + $this->assertArrayNotHasKey( "content\n", $namespaces ); + $this->assertSame( 'http://purl.org/rss/1.0/modules/content/', $namespaces['content'] ); + } + + /** + * Prefixes are XML names: mixed case like `creativeCommons` and + * non-ASCII letters are valid and must be preserved. + * + * @ticket 65785 + */ + public function test_should_preserve_valid_prefixes() { + add_filter( + 'wp_feed_namespaces', + static function ( array $namespaces ): array { + $namespaces['creativeCommons'] = 'http://backend.userland.com/creativeCommonsRssModule'; + $namespaces['média'] = 'http://example.org/media'; + $namespaces['tag-uri'] = 'tag:example.org,2004:ns'; + return $namespaces; + } + ); + + $namespaces = wp_get_feed_namespaces( 'rss2' ); + + $this->assertArrayHasKey( 'creativeCommons', $namespaces ); + $this->assertArrayHasKey( 'média', $namespaces ); + // Namespace URIs are identifiers, not links, so non-http schemes must survive. + $this->assertSame( 'tag:example.org,2004:ns', $namespaces['tag-uri'] ); + } + + /** + * @ticket 65785 + */ + public function test_should_return_an_empty_array_for_an_unknown_type() { + $this->assertSame( array(), wp_get_feed_namespaces( 'unknown' ) ); + } + + /** + * @ticket 65785 + */ + public function test_feed_namespaces_should_print_default_namespaces() { + $output = get_echo( 'wp_feed_namespaces', array( 'rss2' ) ); + + $this->assertStringContainsString( 'xmlns:content="http://purl.org/rss/1.0/modules/content/"', $output ); + $this->assertStringContainsString( 'xmlns:slash="http://purl.org/rss/1.0/modules/slash/"', $output ); + } + + /** + * @ticket 65785 + */ + public function test_feed_namespaces_should_escape_the_namespace_uri() { + add_filter( + 'wp_feed_namespaces', + static function ( array $namespaces ): array { + $namespaces['evil'] = 'http://example.org/"> - admin_url( 'admin-ajax.php', 'relative' ), + 'pagenow' => $current_screen->id, + 'typenow' => $current_screen->post_type, + 'adminpage' => $admin_body_class, + 'thousandsSeparator' => $wp_locale->number_format['thousands_sep'], + 'decimalPoint' => $wp_locale->number_format['decimal_point'], + 'isRtl' => (int) is_rtl(), + ), + JSON_HEX_TAG | JSON_UNESCAPED_SLASHES + ) + ) +); /** * Fires when enqueuing scripts for all admin pages. @@ -253,11 +280,13 @@ $admin_body_classes = ltrim( $admin_body_classes . ' ' . $admin_body_class ); ?> - - - - - - admin_url( 'admin-ajax.php', 'relative' ), + 'pagenow' => 'media-upload-popup', + 'adminpage' => 'media-upload-popup', + 'isRtl' => (int) is_rtl(), + ), + JSON_HEX_TAG | JSON_UNESCAPED_SLASHES + ) + ) + ); /** This action is documented in wp-admin/admin-header.php */ do_action( 'admin_enqueue_scripts', 'media-upload-popup' ); @@ -630,18 +656,26 @@ function wp_iframe( $content_func, ...$args ) { ?> class="wp-core-ui no-js "> - - - - post_id = ' . $post_id . ';'; + wp_print_inline_script_tag( + sprintf( 'var post_id = %s;', wp_json_encode( $post_id, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ) ) + ); if ( empty( $_GET['chromeless'] ) ) { echo '
'; @@ -2247,9 +2282,6 @@ function media_upload_form( $errors = null ) { */ $plupload_init = apply_filters( 'plupload_init', $plupload_init ); - ?> -
- + 0 ) { + preloaded.each( function () { + prepareMediaItem( { id: this.id.replace( /[^0-9]/g, '' ) }, '' ); + } ); + } + updateMediaForm(); + } ); + JS + ); + ?>

+ +
@@ -2596,16 +2646,20 @@ function media_upload_gallery_form( $errors ) { $form_class .= ' html-uploader'; } + wp_print_inline_script_tag( + <<<'JS' + jQuery( function ( $ ) { + var preloaded = $( '.media-item.preloaded' ); + if ( preloaded.length > 0 ) { + preloaded.each( function () { + prepareMediaItem( { id: this.id.replace( /[^0-9]/g, '' ) }, '' ); + } ); + updateMediaForm(); + } + } ); + JS + ); ?> -
@@ -2925,15 +2979,21 @@ function media_upload_library_form( $errors ) {
- + 0 ) { + preloaded.each( function () { + prepareMediaItem( { id: this.id.replace( /[^0-9]/g, '' ) }, '' ); + } ); + updateMediaForm(); + } + } ); + JS + ); + ?>
diff --git a/src/wp-admin/includes/template.php b/src/wp-admin/includes/template.php index 418bfd7def697..e7034e1499ecd 100644 --- a/src/wp-admin/includes/template.php +++ b/src/wp-admin/includes/template.php @@ -2140,19 +2140,50 @@ function iframe_header( $title = '', $deprecated = false ) { <?php bloginfo( 'name' ); ?> › <?php echo $title; ?> — <?php _e( 'WordPress' ); ?> - - admin_url( 'admin-ajax.php', 'relative' ), + 'pagenow' => $current_screen->id ?? '', + 'typenow' => $current_screen->post_type ?? '', + 'adminpage' => $admin_body_class, + 'thousandsSeparator' => $wp_locale->number_format['thousands_sep'], + 'decimalPoint' => $wp_locale->number_format['decimal_point'], + 'isRtl' => (int) is_rtl(), + ), + JSON_HEX_TAG | JSON_UNESCAPED_SLASHES + ) + ) + ); + /** This action is documented in wp-admin/admin-header.php */ do_action( 'admin_enqueue_scripts', $hook_suffix ); @@ -2191,14 +2222,12 @@ function tb_close(){var win=window.dialogArguments||opener||parent||top;win.tb_r $admin_body_classes = ltrim( $admin_body_classes . ' ' . $admin_body_class ); ?> class="wp-admin wp-core-ui no-js iframe "> -
- + Date: Fri, 4 Sep 2026 21:45:19 +0000 Subject: [PATCH 384/634] Administration: Fix doubled border on mobile for paused plugins. Update CSS for paused plugins in recovery mode to account for the changes in list table structure in r62958, which did not account for this case on small viewports. Props r1k0, joedolson. Fixes #65985. git-svn-id: https://develop.svn.wordpress.org/trunk@63482 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/css/list-tables.css | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/wp-admin/css/list-tables.css b/src/wp-admin/css/list-tables.css index 2b8103fe7a886..f6abda748bf1a 100644 --- a/src/wp-admin/css/list-tables.css +++ b/src/wp-admin/css/list-tables.css @@ -1980,7 +1980,8 @@ div.action-links, .plugins .active th.check-column, .plugins .active td.check-column, - .plugin-update-tr.active td { + .plugin-update-tr.active td, + .plugins tr.paused td.check-column { border-left: 4px solid transparent; } @@ -1994,6 +1995,10 @@ div.action-links, border-left: 4px solid var(--wp-admin-theme-color); } + .plugins tr.active.paused { + border-left: 4px solid #b32d2e; + } + .wp-list-table .column-primary .toggle-row { display: block; } From 2fbc03a4948160e319c0870a24b035a5996c957a Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Fri, 4 Sep 2026 23:35:50 +0000 Subject: [PATCH 385/634] Code Quality: Remove redundant `parent_post_type` property from template autosaves controller. The `WP_REST_Template_Autosaves_Controller` class redeclared a private `$parent_post_type` property and assigned it in its constructor. Both were dead code. The parent class `WP_REST_Autosaves_Controller` already declares and sets this property, and because it is declared `private`, the child class's copy could never be accessed by the parent's methods, nor was it ever read anywhere within the child class itself. The result was confusing property shadowing without any functional purpose. This change removes the duplicate property declaration and the corresponding assignment in the constructor. Since the property was never read in the child class and was effectively a separate, unused storage slot, there is no change in runtime behavior. Developed in https://github.com/WordPress/wordpress-develop/pull/12295. Follow-up to r56819. Props Soean. See #65818. git-svn-id: https://develop.svn.wordpress.org/trunk@63485 602fd350-edb4-49c9-b593-d223f7449a82 --- .../class-wp-rest-template-autosaves-controller.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-template-autosaves-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-template-autosaves-controller.php index dbdca575089fc..30e7dcdcd38c0 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-template-autosaves-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-template-autosaves-controller.php @@ -15,13 +15,6 @@ * @see WP_REST_Autosaves_Controller */ class WP_REST_Template_Autosaves_Controller extends WP_REST_Autosaves_Controller { - /** - * Parent post type. - * - * @since 6.4.0 - * @var string - */ - private $parent_post_type; /** * Parent post controller. @@ -56,7 +49,6 @@ class WP_REST_Template_Autosaves_Controller extends WP_REST_Autosaves_Controller */ public function __construct( $parent_post_type ) { parent::__construct( $parent_post_type ); - $this->parent_post_type = $parent_post_type; $post_type_object = get_post_type_object( $parent_post_type ); $parent_controller = $post_type_object->get_rest_controller(); From fc5042df91bbbc28b5b36ee9fa907f4c071e748e Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Fri, 4 Sep 2026 23:50:53 +0000 Subject: [PATCH 386/634] Build/Test Tools: Regenerate PHPStan baselines for `property.onlyWritten`. The sole `property.onlyWritten` error identified by PHPStan was [https://github.com/WordPress/wordpress-develop/pull/12295 fixed] without the baselines being regenerated. Follow-up to r63485. See #65817, #65818. git-svn-id: https://develop.svn.wordpress.org/trunk@63486 602fd350-edb4-49c9-b593-d223f7449a82 --- phpstan.neon.dist | 1 - .../baselines/property.onlyWritten.neon | 25 ------------------- 2 files changed, 26 deletions(-) delete mode 100644 tests/phpstan/baselines/property.onlyWritten.neon diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 1ddfb275beeda..cc4579365122b 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -70,7 +70,6 @@ includes: - tests/phpstan/baselines/property.defaultValue.neon - tests/phpstan/baselines/property.nonObject.neon - tests/phpstan/baselines/property.notFound.neon - - tests/phpstan/baselines/property.onlyWritten.neon - tests/phpstan/baselines/property.phpDocType.neon - tests/phpstan/baselines/property.private.neon - tests/phpstan/baselines/property.protected.neon diff --git a/tests/phpstan/baselines/property.onlyWritten.neon b/tests/phpstan/baselines/property.onlyWritten.neon deleted file mode 100644 index f4b740e1bdf02..0000000000000 --- a/tests/phpstan/baselines/property.onlyWritten.neon +++ /dev/null @@ -1,25 +0,0 @@ -# PHPStan baseline for the `property.onlyWritten` errors in WordPress core. -# -# https://phpstan.org/error-identifiers/property.onlyWritten -# -# Each entry is scoped to a single file and carries an exact occurrence count, -# so that a new instance is reported as a new error rather than being absorbed -# silently. Fixing an occurrence therefore means decrementing or removing its -# entry here as part of the same change. -# -# The goal is to empty this file and delete it, along with the `includes` entry -# for it in phpstan.neon.dist. -# -# Generated by `composer phpstan:baselines`. Do not edit by hand; regenerate with -# -# composer phpstan:baselines -- --identifier=property.onlyWritten -# -# which reruns the analysis with this file suppressed so the errors surface again. - -parameters: - ignoreErrors: - - - message: '#^Property WP_REST_Template_Autosaves_Controller\:\:\$parent_post_type is never read, only written\.$#' - identifier: property.onlyWritten - count: 1 - path: ../../../src/wp-includes/rest-api/endpoints/class-wp-rest-template-autosaves-controller.php From 85be7fcba369ad6a2eb9441bc895aaad6de6de4a Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sat, 5 Sep 2026 00:36:18 +0000 Subject: [PATCH 387/634] Code Quality: Refine the dual-mode template tag annotations. * Restore `void` to the `@return` unions of `wpdb::print_error()` and `wpdb::check_database_version()`, which r62177 replaced with `null`. * Add the `null` that fifteen tags describe in prose but omit from a `@return` listing only `string|void`. * Match every falsy spelling of a display flag, and every argument shape reaching a bail, so those calls resolve to `void`; a query string still cannot be read, tracked in #66049. * Narrow the deprecated param for `trackback_url()` so that static analysis catches the obsolete usage. Developed in https://github.com/WordPress/wordpress-develop/pull/13371. Follow-up to r32568, r61766, r61768, r62177, r62178, r63440, r63441. Props marian1, westonruter. See #64703, #64704, #65817, #66049. git-svn-id: https://develop.svn.wordpress.org/trunk@63487 602fd350-edb4-49c9-b593-d223f7449a82 --- .../themes/twentytwenty/inc/template-tags.php | 4 +-- src/wp-includes/author-template.php | 2 +- src/wp-includes/bookmark-template.php | 2 +- src/wp-includes/category-template.php | 8 ++--- src/wp-includes/class-wpdb.php | 8 ++--- src/wp-includes/comment-template.php | 10 +++--- src/wp-includes/functions.php | 4 +-- src/wp-includes/general-template.php | 35 ++++++++++--------- src/wp-includes/l10n.php | 11 ++++-- src/wp-includes/link-template.php | 14 ++++---- src/wp-includes/post-template.php | 14 ++++---- src/wp-includes/user.php | 2 +- 12 files changed, 60 insertions(+), 54 deletions(-) diff --git a/src/wp-content/themes/twentytwenty/inc/template-tags.php b/src/wp-content/themes/twentytwenty/inc/template-tags.php index 28eaad2b4e42d..7987e4c57af3f 100644 --- a/src/wp-content/themes/twentytwenty/inc/template-tags.php +++ b/src/wp-content/themes/twentytwenty/inc/template-tags.php @@ -107,8 +107,8 @@ function twentytwenty_site_logo( $args = array(), $display = true ) { * @since Twenty Twenty 1.0 * * @param bool $display Display or return the HTML. - * @return string|void The HTML when `$display` is false, null when the site has no - * description. Nothing otherwise. + * @return string|null|void The HTML when `$display` is false, null when the site has no + * description. Nothing otherwise. * @phpstan-return ( $display is true ? void : string|null ) */ function twentytwenty_site_description( $display = true ) { diff --git a/src/wp-includes/author-template.php b/src/wp-includes/author-template.php index 77b1adaf96ac0..b27bbf62379d4 100644 --- a/src/wp-includes/author-template.php +++ b/src/wp-includes/author-template.php @@ -453,7 +453,7 @@ function get_author_posts_url( $author_id, $author_nicename = '' ) { * @phpstan-return ( * $args is array{ echo: false|0|''|'0', ... } * ? string - * : ( $args is ''|array ? void : string|null ) + * : ( $args is ''|'0'|array ? void : string|null ) * ) */ function wp_list_authors( $args = '' ) { diff --git a/src/wp-includes/bookmark-template.php b/src/wp-includes/bookmark-template.php index b3f94decef2d2..37d55bf4561f6 100644 --- a/src/wp-includes/bookmark-template.php +++ b/src/wp-includes/bookmark-template.php @@ -210,7 +210,7 @@ function _walk_bookmarks( $bookmarks, $args = '' ) { * @phpstan-return ( * $args is array{ echo: false|0|''|'0', ... } * ? string - * : ( $args is ''|array ? void : string|null ) + * : ( $args is ''|'0'|array ? void : string|null ) * ) */ function wp_list_bookmarks( $args = '' ) { diff --git a/src/wp-includes/category-template.php b/src/wp-includes/category-template.php index 633c8faf81c51..f268f93cbc461 100644 --- a/src/wp-includes/category-template.php +++ b/src/wp-includes/category-template.php @@ -710,15 +710,15 @@ function wp_list_categories( $args = '' ) { * associated with the taxonomy. * @type bool $echo Whether or not to echo the return value. Default true. * } - * @return string|string[]|void Tag cloud as a string, or as an array when the 'format' argument - * is 'array'. Null on failure. Nothing when 'echo' is true and - * 'format' is not 'array'. + * @return string|string[]|null|void Tag cloud as a string, or as an array when the 'format' + * argument is 'array'. Null on failure. Nothing when 'echo' is + * true and 'format' is not 'array'. * @phpstan-return ( * $args is array{ format: 'array', ... } * ? string[]|null * : ( $args is array{ echo: false|0|''|'0', ... } * ? string|null - * : ( $args is ''|array ? void : string|string[]|null ) ) + * : ( $args is ''|'0'|array ? void : string|string[]|null ) ) * ) */ function wp_tag_cloud( $args = '' ) { diff --git a/src/wp-includes/class-wpdb.php b/src/wp-includes/class-wpdb.php index a676d395ee95c..5cf9508f8fbdf 100644 --- a/src/wp-includes/class-wpdb.php +++ b/src/wp-includes/class-wpdb.php @@ -1794,7 +1794,7 @@ public function esc_like( $text ) { * @global array $EZSQL_ERROR Stores error information of query and error string. * * @param string $str The error to display. - * @return null|false Null if the showing of errors is enabled, false if disabled. + * @return void|false Void if the showing of errors is enabled, false if disabled. */ public function print_error( $str = '' ) { global $EZSQL_ERROR; @@ -1855,8 +1855,6 @@ public function print_error( $str = '' ) { $query ); } - - return null; } /** @@ -4068,7 +4066,7 @@ public function close() { * @since 2.5.0 * * @global string $required_mysql_version The minimum required MySQL version string. - * @return WP_Error|null + * @return void|WP_Error Void if the server meets the minimum version, WP_Error if not. */ public function check_database_version() { global $required_mysql_version; @@ -4079,8 +4077,6 @@ public function check_database_version() { /* translators: 1: WordPress version number, 2: Minimum required MySQL version number. */ return new WP_Error( 'database_version', sprintf( __( 'Error: WordPress %1$s requires MySQL %2$s or higher' ), $wp_version, $required_mysql_version ) ); } - - return null; } /** diff --git a/src/wp-includes/comment-template.php b/src/wp-includes/comment-template.php index 68091c5f4c65e..f96cf18f78f13 100644 --- a/src/wp-includes/comment-template.php +++ b/src/wp-includes/comment-template.php @@ -1244,10 +1244,12 @@ function get_trackback_url() { * * @see get_trackback_url() * - * @param bool $deprecated_echo Deprecated. Use {@see get_trackback_url()}. Echo the URL or + * @param true $deprecated_echo Deprecated. Use {@see get_trackback_url()}. Echo the URL or * return it. Default true. * @return string|void The trackback URL when `$deprecated_echo` is false, nothing otherwise. * @phpstan-return ( $deprecated_echo is true ? void : string ) + * + * @phpstan-ignore conditionalType.alwaysTrue (Typed `true` to flag the deprecated argument.) */ function trackback_url( $deprecated_echo = true ) { if ( true !== $deprecated_echo ) { @@ -2233,12 +2235,12 @@ function _get_comment_reply_id( $post = null ) { * @type bool $echo Whether to echo the output or return it. Default true. * } * @param WP_Comment[] $comments Optional. Array of WP_Comment objects. Default null. - * @return string|void HTML list of comments when 'echo' is false, null when there are no - * comments to list. Nothing otherwise. + * @return string|null|void HTML list of comments when 'echo' is false, null when there are + * no comments to list. Nothing otherwise. * @phpstan-return ( * $args is array{ echo: false|0|''|'0', ... } * ? string|null - * : ( $args is ''|array ? void : string|null ) + * : ( $args is ''|'0'|array ? void : string|null ) * ) */ function wp_list_comments( $args = array(), $comments = null ) { diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index dd42e3ad916f6..31de822d2aacd 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -8745,8 +8745,8 @@ function wp_get_default_update_php_url() { * @param string $before Markup to output before the annotation. Default `

`. * @param string $after Markup to output after the annotation. Default `

`. * @param bool $display Whether to echo or return the markup. Default `true` for echo. - * @return string|void Update PHP page annotation when `$display` is false, null when no - * annotation is available. Nothing otherwise. + * @return string|null|void Update PHP page annotation when `$display` is false, null when + * no annotation is available. Nothing otherwise. * @phpstan-return ( $display is true ? void : string|null ) */ function wp_update_php_annotation( $before = '

', $after = '

', $display = true ) { diff --git a/src/wp-includes/general-template.php b/src/wp-includes/general-template.php index e5c65279e52b5..7ba1d623f4631 100644 --- a/src/wp-includes/general-template.php +++ b/src/wp-includes/general-template.php @@ -1705,8 +1705,8 @@ function wp_title( $sep = '»', $display = true, $seplocation = '' ) { * * @param string $prefix Optional. What to display before the title. * @param bool $display Optional. Whether to display or retrieve title. Default true. - * @return string|void Title when retrieving, null on failure. - * Nothing when displaying. + * @return string|null|void Title when retrieving, null on failure. + * Nothing when displaying. * @phpstan-return ( $display is true ? void : string|null ) */ function single_post_title( $prefix = '', $display = true ) { @@ -1743,8 +1743,8 @@ function single_post_title( $prefix = '', $display = true ) { * * @param string $prefix Optional. What to display before the title. * @param bool $display Optional. Whether to display or retrieve title. Default true. - * @return string|void Title when retrieving, null on failure. - * Nothing when displaying. + * @return string|null|void Title when retrieving, null on failure. + * Nothing when displaying. * @phpstan-return ( $display is true ? void : string|null ) */ function post_type_archive_title( $prefix = '', $display = true ) { @@ -1787,8 +1787,8 @@ function post_type_archive_title( $prefix = '', $display = true ) { * * @param string $prefix Optional. What to display before the title. * @param bool $display Optional. Whether to display or retrieve title. Default true. - * @return string|void Title when retrieving, null on failure. - * Nothing when displaying. + * @return string|null|void Title when retrieving, null on failure. + * Nothing when displaying. * @phpstan-return ( $display is true ? void : string|null ) */ function single_cat_title( $prefix = '', $display = true ) { @@ -1810,8 +1810,8 @@ function single_cat_title( $prefix = '', $display = true ) { * * @param string $prefix Optional. What to display before the title. * @param bool $display Optional. Whether to display or retrieve title. Default true. - * @return string|void Title when retrieving, null on failure. - * Nothing when displaying. + * @return string|null|void Title when retrieving, null on failure. + * Nothing when displaying. * @phpstan-return ( $display is true ? void : string|null ) */ function single_tag_title( $prefix = '', $display = true ) { @@ -1833,8 +1833,8 @@ function single_tag_title( $prefix = '', $display = true ) { * * @param string $prefix Optional. What to display before the title. * @param bool $display Optional. Whether to display or retrieve title. Default true. - * @return string|void Title when retrieving, null on failure. - * Nothing when displaying. + * @return string|null|void Title when retrieving, null on failure. + * Nothing when displaying. * @phpstan-return ( $display is true ? void : string|null ) */ function single_term_title( $prefix = '', $display = true ) { @@ -2235,12 +2235,12 @@ function get_archives_link( $url, $text, $format = 'html', $before = '', $after * @type string $day Day. Default current day. * @type string $w Week. Default current week. * } - * @return string|void Archive links when 'echo' is false, null when the post type is - * not viewable. Nothing otherwise. + * @return string|null|void Archive links when 'echo' is false, null when the post type is + * not viewable. Nothing otherwise. * @phpstan-return ( * $args is array{ echo: false|0|''|'0', ... } * ? string|null - * : ( $args is ''|array ? void : string|null ) + * : ( $args is ''|'0'|array ? void : string|null ) * ) */ function wp_get_archives( $args = '' ) { @@ -2511,8 +2511,8 @@ function calendar_week_mod( $num ) { * @type bool $display Whether to display the calendar output. Default true. * @type string $post_type Optional. Post type. Default 'post'. * } - * @return string|void Calendar HTML when `$display` is false, null when the site has - * no posts. Nothing otherwise. + * @return string|null|void Calendar HTML when `$display` is false, null when the site has + * no posts. Nothing otherwise. * @phpstan-return ( $args is array{ display: false|0|''|'0', ... } ? string|null : void ) */ function get_calendar( $args = array() ) { @@ -2927,7 +2927,8 @@ function the_date_xml() { * @param string $before Optional. Output before the date. Default empty. * @param string $after Optional. Output after the date. Default empty. * @param bool $display Optional. Whether to echo the date or return it. Default true. - * @return string|void String if retrieving. + * @return string|void The date when `$display` is false, or an empty string when the post's + * date matches the previously output one. Nothing otherwise. * @phpstan-return ( $display is true ? void : string ) */ function the_date( $format = '', $before = '', $after = '', $display = true ) { @@ -3003,7 +3004,7 @@ function get_the_date( $format = '', $post = null ) { * @param string $before Optional. Output before the date. Default empty. * @param string $after Optional. Output after the date. Default empty. * @param bool $display Optional. Whether to echo the date or return it. Default true. - * @return string|void String if retrieving. + * @return string|void The modified date when `$display` is false, nothing otherwise. * @phpstan-return ( $display is true ? void : string ) */ function the_modified_date( $format = '', $before = '', $after = '', $display = true ) { diff --git a/src/wp-includes/l10n.php b/src/wp-includes/l10n.php index a0be55146f7e6..7b9d2652d41dd 100644 --- a/src/wp-includes/l10n.php +++ b/src/wp-includes/l10n.php @@ -1736,8 +1736,15 @@ function wp_get_l10n_php_file_data( $php_file ) { * instead of an empty value. Default false. * } * @return string|void HTML dropdown list of languages. Always returned, whether or not - * 'echo' is true; nothing is returned when the required `id` or `name` - * argument is missing. + * 'echo' is true; nothing is returned when the 'id' or 'name' + * argument is empty. + * @phpstan-return ( + * $args is array{ id: ''|'0', ... } + * ? void + * : ( $args is array{ name: ''|'0', ... } + * ? void + * : ( $args is array ? string : string|void ) ) + * ) */ function wp_dropdown_languages( $args = array() ) { diff --git a/src/wp-includes/link-template.php b/src/wp-includes/link-template.php index cabb7cedfab21..f4accadb0bf3a 100644 --- a/src/wp-includes/link-template.php +++ b/src/wp-includes/link-template.php @@ -1131,8 +1131,8 @@ function get_edit_term_link( $term, $taxonomy = '', $object_type = '' ) { * @param string $after Optional. Display after edit link. Default empty. * @param int|WP_Term|null $term Optional. Term ID or object. If null, the queried object will be inspected. Default null. * @param bool $display Optional. Whether or not to echo the return. Default true. - * @return string|void HTML content when retrieving, null on failure or without the - * capability to edit the term. Nothing when displaying. + * @return string|null|void HTML content when retrieving, null on failure or without the + * capability to edit the term. Nothing when displaying. * @phpstan-return ( $display is true ? void : string|null ) */ function edit_term_link( $link = '', $before = '', $after = '', $term = null, $display = true ) { @@ -3268,16 +3268,16 @@ function previous_comments_link( $label = '' ) { * @global WP_Rewrite $wp_rewrite WordPress rewrite component. * * @param string|array $args Optional args. See paginate_links(). Default empty array. - * @return string|string[]|void Markup for comment page links, or an array of them when the 'type' - * argument is 'array'. Null if the query is not for an existing single - * post of any post type. Nothing when 'echo' is true and 'type' is not - * 'array'. + * @return string|string[]|null|void Markup for comment page links, or an array of them when + * the 'type' argument is 'array'. Null if the query is not for + * an existing single post of any post type. Nothing when 'echo' + * is true and 'type' is not 'array'. * @phpstan-return ( * $args is array{ type: 'array', ... } * ? string[]|null * : ( $args is array{ echo: false|0|''|'0', ... } * ? string|null - * : ( $args is ''|array ? void : string|string[]|null ) ) + * : ( $args is ''|'0'|array ? void : string|string[]|null ) ) * ) */ function paginate_comments_links( $args = array() ) { diff --git a/src/wp-includes/post-template.php b/src/wp-includes/post-template.php index 0c21f6815a28b..beb53c92b0c46 100644 --- a/src/wp-includes/post-template.php +++ b/src/wp-includes/post-template.php @@ -37,8 +37,8 @@ function get_the_ID() { // phpcs:ignore WordPress.NamingConventions.ValidFunctio * @param string $before Optional. Markup to prepend to the title. Default empty. * @param string $after Optional. Markup to append to the title. Default empty. * @param bool $display Optional. Whether to echo or return the title. Default true for echo. - * @return string|void Current post title when `$display` is false, null when the title - * is empty. Nothing otherwise. + * @return string|null|void Current post title when `$display` is false, null when the + * title is empty. Nothing otherwise. * @phpstan-return ( $display is true ? void : string|null ) */ function the_title( $before = '', $after = '', $display = true ) { @@ -77,12 +77,12 @@ function the_title( $before = '', $after = '', $display = true ) { * @type bool $echo Whether to echo or return the title. Default true for echo. * @type WP_Post $post Current post object to retrieve the title for. * } - * @return string|void The title attribute when 'echo' is false, null when the title is - * empty. Nothing otherwise. + * @return string|null|void The title attribute when 'echo' is false, null when the title + * is empty. Nothing otherwise. * @phpstan-return ( * $args is array{ echo: false|0|''|'0', ... } * ? string|null - * : ( $args is ''|array ? void : string|null ) + * : ( $args is ''|'0'|array ? void : string|null ) * ) */ function the_title_attribute( $args = '' ) { @@ -1309,7 +1309,7 @@ function wp_dropdown_pages( $args = '' ) { * @phpstan-return ( * $args is array{ echo: false|0|''|'0', ... } * ? string - * : ( $args is ''|array ? void : string|null ) + * : ( $args is ''|'0'|array ? void : string|null ) * ) */ function wp_list_pages( $args = '' ) { @@ -1437,7 +1437,7 @@ function wp_list_pages( $args = '' ) { * @phpstan-return ( * $args is array{ echo: false|0|''|'0', ... } * ? string - * : ( $args is ''|array ? void : string|null ) + * : ( $args is ''|'0'|array ? void : string|null ) * ) */ function wp_page_menu( $args = array() ) { diff --git a/src/wp-includes/user.php b/src/wp-includes/user.php index 0a0aed8348073..3e8d76b1e4a3b 100644 --- a/src/wp-includes/user.php +++ b/src/wp-includes/user.php @@ -911,7 +911,7 @@ function get_users( $args = array() ) { * @phpstan-return ( * $args is array{ echo: false|0|''|'0', ... } * ? string - * : ( $args is ''|array ? void : string|null ) + * : ( $args is ''|'0'|array ? void : string|null ) * ) */ function wp_list_users( $args = array() ) { From 823a803768217fe2ac382b5df80cf95c43177a23 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sat, 5 Sep 2026 01:39:01 +0000 Subject: [PATCH 388/634] Taxonomy: Fix `wp_get_object_terms()` when requesting a count. Requesting a count passed the numeric string `get_terms()` returns straight to `array_merge()`, which warns and yields null on PHP 7.4 and throws a `TypeError` on PHP 8.0 and later. The count is now cast before it is merged, and summed once every taxonomy has been queried, so the function returns the numeric string its documentation has described since r49947. An empty object or taxonomy list returns `'0'` for the same reason, rather than the empty array that contradicted the documented type. A taxonomy registered with an `args` array is queried by a separate recursive call, and those results were merged with `array_merge()` unconditionally. For the `id=>` values of `fields` the term IDs are integer array keys, which `array_merge()` renumbers, so such a taxonomy came back keyed from zero. The recursive branch now uses the union operator for those, as the merge for the remaining taxonomies has done since r41809. The functions `get_terms()`, `wp_get_object_terms()`, `wp_count_terms()`, `wp_get_post_categories()`, `wp_get_post_tags()` and `wp_get_post_terms()` each gain a conditional return type that resolves the result from the `fields` value, falling back to what that function's own default answers with, as was done for `WP_Term_Query::query()` in r63358. Developed in https://github.com/WordPress/wordpress-develop/pull/7278. Follow-up to r38667, r40513, r41809, r49947, r63358. Props marian1, westonruter, swissspidy. See #65817, #66049. Fixes #61936. git-svn-id: https://develop.svn.wordpress.org/trunk@63488 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/post.php | 66 ++++- src/wp-includes/taxonomy.php | 98 ++++++-- .../phpstan/baselines/property.nonObject.neon | 10 - .../phpstan/baselines/property.notFound.neon | 10 + tests/phpunit/tests/term.php | 33 +++ tests/phpunit/tests/term/wpGetObjectTerms.php | 229 +++++++++++++++++- 6 files changed, 409 insertions(+), 37 deletions(-) diff --git a/src/wp-includes/post.php b/src/wp-includes/post.php index 26266c04140a2..dca47155a1227 100644 --- a/src/wp-includes/post.php +++ b/src/wp-includes/post.php @@ -4452,10 +4452,28 @@ function wp_untrash_post_comments( $post = null ) { * global $post. Default 0. * @param array $args Optional. Category query parameters. Default empty array. * See WP_Term_Query::__construct() for supported arguments. - * @return array|WP_Error List of categories. If the `$fields` argument passed via `$args` is 'all' or - * 'all_with_object_id', an array of WP_Term objects will be returned. If `$fields` - * is 'ids', an array of category IDs. If `$fields` is 'names', an array of category names. - * WP_Error object if 'category' taxonomy doesn't exist. + * @return int[]|WP_Term[]|string[]|string|WP_Error List of categories. An array of category IDs by + * default, and if the `$fields` argument passed via + * `$args` is 'ids'. If `$fields` is 'all' or + * 'all_with_object_id', an array of WP_Term objects. + * If `$fields` is 'names', an array of category names. + * If `$fields` is 'count', a count thereof as a numeric + * string. WP_Error object if 'category' taxonomy + * doesn't exist. + * + * @phpstan-return ( + * $args is array{ fields: 'count', ... } + * ? numeric-string|WP_Error + * : ( $args is array{ fields: 'id=>parent', ... } + * ? array|WP_Error + * : ( $args is array{ fields: 'names'|'slugs', ... } + * ? string[]|WP_Error + * : ( $args is array{ fields: 'id=>name'|'id=>slug', ... } + * ? array|WP_Error + * : ( $args is array{ fields: 'all'|'all_with_object_id', ... } + * ? WP_Term[]|WP_Error + * : int[]|WP_Error ) ) ) ) + * ) */ function wp_get_post_categories( $post_id = 0, $args = array() ) { $post_id = (int) $post_id; @@ -4480,8 +4498,24 @@ function wp_get_post_categories( $post_id = 0, $args = array() ) { * global $post. Default 0. * @param array $args Optional. Tag query parameters. Default empty array. * See WP_Term_Query::__construct() for supported arguments. - * @return array|WP_Error Array of WP_Term objects on success or empty array if no tags were found. - * WP_Error object if 'post_tag' taxonomy doesn't exist. + * @return WP_Term[]|int[]|string[]|string|WP_Error Array of WP_Term objects on success or empty array if no + * tags were found. A count thereof as a numeric string if + * the `$fields` argument passed via `$args` is 'count'. + * WP_Error object if 'post_tag' taxonomy doesn't exist. + * + * @phpstan-return ( + * $args is array{ fields: 'count', ... } + * ? numeric-string|WP_Error + * : ( $args is array{ fields: 'ids'|'tt_ids', ... } + * ? int[]|WP_Error + * : ( $args is array{ fields: 'id=>parent', ... } + * ? array|WP_Error + * : ( $args is array{ fields: 'names'|'slugs', ... } + * ? string[]|WP_Error + * : ( $args is array{ fields: 'id=>name'|'id=>slug', ... } + * ? array|WP_Error + * : WP_Term[]|WP_Error ) ) ) ) + * ) */ function wp_get_post_tags( $post_id = 0, $args = array() ) { return wp_get_post_terms( $post_id, 'post_tag', $args ); @@ -4501,8 +4535,24 @@ function wp_get_post_tags( $post_id = 0, $args = array() ) { * * @type string $fields Term fields to retrieve. Default 'all'. * } - * @return array|WP_Error Array of WP_Term objects on success or empty array if no terms were found. - * WP_Error object if `$taxonomy` doesn't exist. + * @return WP_Term[]|int[]|string[]|string|WP_Error Array of WP_Term objects on success or empty array if no + * terms were found. A count thereof as a numeric string if + * the `$fields` argument passed via `$args` is 'count'. + * WP_Error object if `$taxonomy` doesn't exist. + * + * @phpstan-return ( + * $args is array{ fields: 'count', ... } + * ? numeric-string|WP_Error + * : ( $args is array{ fields: 'ids'|'tt_ids', ... } + * ? int[]|WP_Error + * : ( $args is array{ fields: 'id=>parent', ... } + * ? array|WP_Error + * : ( $args is array{ fields: 'names'|'slugs', ... } + * ? string[]|WP_Error + * : ( $args is array{ fields: 'id=>name'|'id=>slug', ... } + * ? array|WP_Error + * : WP_Term[]|WP_Error ) ) ) ) + * ) */ function wp_get_post_terms( $post_id = 0, $taxonomy = 'post_tag', $args = array() ) { $post_id = (int) $post_id; diff --git a/src/wp-includes/taxonomy.php b/src/wp-includes/taxonomy.php index 597fdf4118d68..2e264ad4e433f 100644 --- a/src/wp-includes/taxonomy.php +++ b/src/wp-includes/taxonomy.php @@ -1309,15 +1309,35 @@ function get_term_to_edit( $id, $taxonomy ) { * Introduced 'meta_key' and 'meta_value' parameters. Introduced the ability to order results by metadata. * @since 4.8.0 Introduced 'suppress_filter' parameter. * - * @param array|string $args Optional. Array or string of arguments. See WP_Term_Query::__construct() + * @param array|string $args Optional. Array or string of arguments. See {@see WP_Term_Query::__construct()} * for information on accepted arguments. Default empty array. * @param array|string $deprecated Optional. Argument array, when using the legacy function parameter format. * If present, this parameter will be interpreted as `$args`, and the first * function parameter will be parsed as a taxonomy or array of taxonomies. * Default empty. - * @return WP_Term[]|int[]|string[]|string|WP_Error Array of terms, a count thereof as a numeric string, - * or WP_Error if any of the taxonomies do not exist. - * See the function description for more information. + * @return WP_Term[]|int[]|string[]|int|string|WP_Error Array of terms, a count thereof as a numeric string, + * the integer 0 when the queried parent term is not in + * the taxonomy hierarchy, or WP_Error if any of the + * taxonomies do not exist. See the function description + * for more information. + * + * @phpstan-return ( + * $args is array{ fields: 'count', ... } + * ? 0|numeric-string|WP_Error + * : ( $args is array{ fields: 'ids'|'tt_ids', ... } + * ? int[]|WP_Error + * : ( $args is array{ fields: 'id=>parent', ... } + * ? array|WP_Error + * : ( $args is array{ fields: 'names'|'slugs', ... } + * ? string[]|WP_Error + * : ( $args is array{ fields: 'id=>name'|'id=>slug', ... } + * ? array|WP_Error + * : ( $deprecated is '' + * ? ( $args is array + * ? WP_Term[]|WP_Error + * : WP_Term[]|int[]|string[]|int|string|WP_Error ) + * : WP_Term[]|int[]|string[]|int|string|WP_Error ) ) ) ) ) + * ) */ function get_terms( $args = array(), $deprecated = '' ) { $term_query = new WP_Term_Query(); @@ -1957,14 +1977,16 @@ function sanitize_term_field( $field, $value, $term_id, $taxonomy, $context ) { * @since 2.3.0 * @since 5.6.0 Changed the function signature so that the `$args` array can be provided as the first parameter. * - * @param array|string $args Optional. Array or string of arguments. See WP_Term_Query::__construct() + * @param array|string $args Optional. Array or string of arguments. See {@see WP_Term_Query::__construct()} * for information on accepted arguments. Default empty array. * @param array|string $deprecated Optional. Argument array, when using the legacy function parameter format. * If present, this parameter will be interpreted as `$args`, and the first * function parameter will be parsed as a taxonomy or array of taxonomies. * Default empty. - * @return string|WP_Error Numeric string containing the number of terms in that - * taxonomy or WP_Error if the taxonomy does not exist. + * @return string|int|WP_Error Numeric string containing the number of terms in that taxonomy, + * the integer 0 when the queried parent term is not in the taxonomy + * hierarchy, or WP_Error if the taxonomy does not exist. + * @phpstan-return numeric-string|0|WP_Error */ function wp_count_terms( $args = array(), $deprecated = '' ) { $use_legacy_args = false; @@ -1992,7 +2014,10 @@ function wp_count_terms( $args = array(), $deprecated = '' ) { unset( $args['ignore_empty'] ); } - $args['fields'] = 'count'; + $args = array_merge( + $args, + array( 'fields' => 'count' ) + ); return get_terms( $args ); } @@ -2289,16 +2314,40 @@ function wp_delete_category( $cat_id ) { * @since 4.7.0 Refactored to use WP_Term_Query, and to support any WP_Term_Query arguments. * @since 6.3.0 Passing `update_term_meta_cache` argument value false by default resulting in get_terms() to not * prime the term meta cache. + * @since 7.2.0 A count is returned as a numeric string when `$fields` is 'count'. Previously requesting + * a count resulted in an error. * * @param int|int[] $object_ids The ID(s) of the object(s) to retrieve. * @param string|string[] $taxonomies The taxonomy names to retrieve terms from. - * @param array|string $args See WP_Term_Query::__construct() for supported arguments. + * @param array|string $args See {@see WP_Term_Query::__construct()} for supported arguments. * @return WP_Term[]|int[]|string[]|string|WP_Error Array of terms, a count thereof as a numeric string, * or WP_Error if any of the taxonomies do not exist. - * See WP_Term_Query::get_terms() for more information. + * See {@see WP_Term_Query::get_terms()} for more information. + * + * @phpstan-return ( + * $args is array{ fields: 'count', ... } + * ? numeric-string|WP_Error + * : ( $args is array{ fields: 'ids'|'tt_ids', ... } + * ? int[]|WP_Error + * : ( $args is array{ fields: 'id=>parent', ... } + * ? array|WP_Error + * : ( $args is array{ fields: 'names'|'slugs', ... } + * ? string[]|WP_Error + * : ( $args is array{ fields: 'id=>name'|'id=>slug', ... } + * ? array|WP_Error + * : ( $args is array + * ? WP_Term[]|WP_Error + * : WP_Term[]|int[]|string[]|string|WP_Error ) ) ) ) ) + * ) */ function wp_get_object_terms( $object_ids, $taxonomies, $args = array() ) { + $args = wp_parse_args( $args ); + if ( empty( $object_ids ) || empty( $taxonomies ) ) { + if ( isset( $args['fields'] ) && 'count' === $args['fields'] ) { + return '0'; + } + return array(); } @@ -2338,6 +2387,13 @@ function wp_get_object_terms( $object_ids, $taxonomies, $args = array() ) { /* * When one or more queried taxonomies is registered with an 'args' array, * those params override the `$args` passed to this function. + * + * That array is for query modifiers such as 'orderby'. Overriding 'fields' + * there does not work, because callers depend on the shape they asked for: + * get_the_taxonomies() reads `$term->name` off the result, and + * wp_set_object_terms() needs the 'tt_ids' it requested. A taxonomy that + * overrides it also returns a different shape than the taxonomies queried + * below, leaving the two merged into one another here. */ $terms = array(); if ( count( $taxonomies ) > 1 ) { @@ -2345,7 +2401,16 @@ function wp_get_object_terms( $object_ids, $taxonomies, $args = array() ) { $t = get_taxonomy( $taxonomy ); if ( isset( $t->args ) && is_array( $t->args ) && array_merge( $args, $t->args ) != $args ) { unset( $taxonomies[ $index ] ); - $terms = array_merge( $terms, wp_get_object_terms( $object_ids, $taxonomy, array_merge( $args, $t->args ) ) ); + + // Cast because a count is returned as a numeric string. The counts are summed below. + $terms_from_taxonomy = (array) wp_get_object_terms( $object_ids, $taxonomy, array_merge( $args, $t->args ) ); + + // Array keys should be preserved for values of $fields that use term_id for keys. + if ( ! empty( $args['fields'] ) && str_starts_with( $args['fields'], 'id=>' ) ) { + $terms = $terms + $terms_from_taxonomy; + } else { + $terms = array_merge( $terms, $terms_from_taxonomy ); + } } } } else { @@ -2360,7 +2425,8 @@ function wp_get_object_terms( $object_ids, $taxonomies, $args = array() ) { // Taxonomies registered without an 'args' param are handled here. if ( ! empty( $taxonomies ) ) { - $terms_from_remaining_taxonomies = get_terms( $args ); + // Cast because a count is returned as a numeric string. The counts are summed below. + $terms_from_remaining_taxonomies = (array) get_terms( $args ); // Array keys should be preserved for values of $fields that use term_id for keys. if ( ! empty( $args['fields'] ) && str_starts_with( $args['fields'], 'id=>' ) ) { @@ -2370,6 +2436,10 @@ function wp_get_object_terms( $object_ids, $taxonomies, $args = array() ) { } } + if ( isset( $args['fields'] ) && 'count' === $args['fields'] ) { + $terms = (string) array_sum( $terms ); + } + /** * Filters the terms for a given object or objects. * @@ -2379,7 +2449,7 @@ function wp_get_object_terms( $object_ids, $taxonomies, $args = array() ) { * @param int[] $object_ids Array of object IDs for which terms were retrieved. * @param string[] $taxonomies Array of taxonomy names from which terms were retrieved. * @param array $args Array of arguments for retrieving terms for the given - * object(s). See wp_get_object_terms() for details. + * object(s). See {@see wp_get_object_terms()} for details. */ $terms = apply_filters( 'get_object_terms', $terms, $object_ids, $taxonomies, $args ); @@ -2398,7 +2468,7 @@ function wp_get_object_terms( $object_ids, $taxonomies, $args = array() ) { * @param string $object_ids Comma separated list of object IDs for which terms were retrieved. * @param string $taxonomies SQL fragment of taxonomy names from which terms were retrieved. * @param array $args Array of arguments for retrieving terms for the given - * object(s). See wp_get_object_terms() for details. + * object(s). See {@see wp_get_object_terms()} for details. */ return apply_filters( 'wp_get_object_terms', $terms, $object_ids, $taxonomies, $args ); } diff --git a/tests/phpstan/baselines/property.nonObject.neon b/tests/phpstan/baselines/property.nonObject.neon index 13fd1ccf89fc9..d242b9373685b 100644 --- a/tests/phpstan/baselines/property.nonObject.neon +++ b/tests/phpstan/baselines/property.nonObject.neon @@ -23,16 +23,6 @@ parameters: identifier: property.nonObject count: 2 path: ../../../src/wp-admin/includes/ajax-actions.php - - - message: '#^Cannot access property \$id on int\|string\|WP_Term\.$#' - identifier: property.nonObject - count: 1 - path: ../../../src/wp-admin/includes/ajax-actions.php - - - message: '#^Cannot access property \$link on int\|string\|WP_Term\.$#' - identifier: property.nonObject - count: 1 - path: ../../../src/wp-admin/includes/ajax-actions.php - message: '#^Cannot access property \$name on array\|object\.$#' identifier: property.nonObject diff --git a/tests/phpstan/baselines/property.notFound.neon b/tests/phpstan/baselines/property.notFound.neon index b8e86ff092bc7..f4288f6aa6aff 100644 --- a/tests/phpstan/baselines/property.notFound.neon +++ b/tests/phpstan/baselines/property.notFound.neon @@ -18,6 +18,16 @@ parameters: ignoreErrors: + - + message: '#^Access to an undefined property WP_Term\:\:\$id\.$#' + identifier: property.notFound + count: 1 + path: ../../../src/wp-admin/includes/ajax-actions.php + - + message: '#^Access to an undefined property WP_Term\:\:\$link\.$#' + identifier: property.notFound + count: 1 + path: ../../../src/wp-admin/includes/ajax-actions.php - message: '#^Access to an undefined property WP_Upgrader_Skin\:\:\$language_update\.$#' identifier: property.notFound diff --git a/tests/phpunit/tests/term.php b/tests/phpunit/tests/term.php index a9b97c1f36dee..2b236102b710e 100644 --- a/tests/phpunit/tests/term.php +++ b/tests/phpunit/tests/term.php @@ -79,6 +79,39 @@ public function test_wp_count_terms() { $this->assertSame( '1', $count ); } + /** + * Ensures a queried parent term outside the taxonomy hierarchy counts as the integer 0. + * + * Every other outcome is a numeric string, so this is the one case where the return + * type is not a string at all. + * + * @ticket 61936 + * + * @covers ::wp_count_terms + */ + public function test_wp_count_terms_should_return_integer_zero_for_a_parent_outside_the_hierarchy() { + register_taxonomy( 'wptests_tax_hierarchical', 'post', array( 'hierarchical' => true ) ); + + $term_id = self::factory()->term->create( array( 'taxonomy' => 'wptests_tax_hierarchical' ) ); + $this->assertIsInt( $term_id, 'The term was not created.' ); + + $count = wp_count_terms( + array( + 'taxonomy' => 'wptests_tax_hierarchical', + 'parent' => 99999, + ) + ); + $this->assertSame( 0, $count, 'Incorrect count for a parent outside the hierarchy.' ); + + $count = wp_count_terms( + array( + 'taxonomy' => 'wptests_tax_hierarchical', + 'child_of' => 99999, + ) + ); + $this->assertSame( 0, $count, 'Incorrect count for a child_of outside the hierarchy.' ); + } + /** * @ticket 36399 */ diff --git a/tests/phpunit/tests/term/wpGetObjectTerms.php b/tests/phpunit/tests/term/wpGetObjectTerms.php index a8483f8a770a2..c1eb27ea71295 100644 --- a/tests/phpunit/tests/term/wpGetObjectTerms.php +++ b/tests/phpunit/tests/term/wpGetObjectTerms.php @@ -5,16 +5,18 @@ * @covers ::wp_get_object_terms */ class Tests_Term_WpGetObjectTerms extends WP_UnitTestCase { - private $taxonomy = 'wptests_tax'; + /** + * Name of the taxonomy registered for each test. + */ + private string $taxonomy = 'wptests_tax'; /** * Temporary storage for taxonomies for tests using filter callbacks. * * Used in the `test_taxonomies_passed_to_wp_get_object_terms_filter_should_be_quoted()` method. - * - * @var array + * This is a SQL fragment of taxonomy names from which terms were retrieved. */ - private $taxonomies; + private ?string $taxonomies = null; public function set_up() { parent::set_up(); @@ -25,7 +27,7 @@ public function set_up() { * Clean up after each test. */ public function tear_down() { - unset( $this->taxonomies ); + $this->taxonomies = null; parent::tear_down(); } @@ -1012,4 +1014,221 @@ public function test_duplicate_terms_should_not_be_returned_when_passed_multiple $this->assertSameSets( $expected, $actual ); } + + /** + * @ticket 61936 + */ + public function test_should_return_numeric_string_for_fields_count() { + $fields = array( 'fields' => 'count' ); + + $taxonomies = array( 'wptests_tax', 'wptests_tax_2' ); + + register_taxonomy( $taxonomies[0], 'post' ); + register_taxonomy( $taxonomies[1], 'post' ); + + $term_1_id = self::factory()->term->create( array( 'taxonomy' => $taxonomies[0] ) ); + $term_2_id = self::factory()->term->create( array( 'taxonomy' => $taxonomies[1] ) ); + + $post_ids = self::factory()->post->create_many( 2 ); + wp_set_object_terms( $post_ids[0], $term_1_id, $taxonomies[0] ); + wp_set_object_terms( $post_ids[1], $term_1_id, $taxonomies[0] ); + wp_set_object_terms( $post_ids[1], $term_2_id, $taxonomies[1] ); + + $terms_count = wp_get_object_terms( 0, $taxonomies[0], $fields ); + $this->assertSame( '0', $terms_count, 'Incorrect term count with empty object_ids.' ); + + $terms_count = wp_get_object_terms( $post_ids[0], '', $fields ); + $this->assertSame( '0', $terms_count, 'Incorrect term count with empty taxonomies.' ); + + $terms_count = wp_get_object_terms( $post_ids[0], $taxonomies[0], $fields ); + $this->assertSame( '1', $terms_count, 'Incorrect term count with single object_id and single taxonomy.' ); + + $terms_count = wp_get_object_terms( $post_ids[0], $taxonomies, $fields ); + $this->assertSame( '1', $terms_count, 'Incorrect term count with single object_id and multiple taxonomies.' ); + + $terms_count = wp_get_object_terms( $post_ids[1], $taxonomies, $fields ); + $this->assertSame( '2', $terms_count, 'Incorrect term count with single object_id and multiple taxonomies.' ); + + $terms_count = wp_get_object_terms( $post_ids, $taxonomies, $fields ); + $this->assertSame( '3', $terms_count, 'Incorrect term count with multiple object_ids and multiple taxonomies.' ); + } + + /** + * Ensures that a count can be requested with the `$args` parameter in query string form. + * + * An empty object ID or taxonomy list short-circuits before `$args` would otherwise be + * parsed, so the query string has to be parsed up front for the `fields` value to be read. + * + * @ticket 61936 + */ + public function test_should_return_numeric_string_for_fields_count_passed_as_query_string() { + $post_id = self::factory()->post->create(); + $this->assertIsInt( $post_id, 'The post was not created.' ); + + $term_id = self::factory()->term->create( array( 'taxonomy' => $this->taxonomy ) ); + $this->assertIsInt( $term_id, 'The term was not created.' ); + + wp_set_object_terms( $post_id, $term_id, $this->taxonomy ); + + $terms_count = wp_get_object_terms( 0, $this->taxonomy, 'fields=count' ); + $this->assertSame( '0', $terms_count, 'Incorrect term count with empty object_ids.' ); + + $terms_count = wp_get_object_terms( $post_id, '', 'fields=count' ); + $this->assertSame( '0', $terms_count, 'Incorrect term count with empty taxonomies.' ); + + $terms_count = wp_get_object_terms( $post_id, $this->taxonomy, 'fields=count' ); + $this->assertSame( '1', $terms_count, 'Incorrect term count.' ); + } + + /** + * Ensures that a count is summed across a taxonomy registered with an 'args' array. + * + * Such a taxonomy is queried by a recursive call rather than alongside the others, + * and that call returns the count as a numeric string rather than as an array. + * + * @ticket 61936 + */ + public function test_should_return_numeric_string_for_fields_count_with_taxonomy_registered_with_args() { + $taxonomy1 = 'wptests_tax'; + $taxonomy2 = 'wptests_tax_2'; + + // Any non-empty 'args' array sends the taxonomy down the recursive path. + register_taxonomy( $taxonomy1, 'post', array( 'args' => array( 0 ) ) ); + register_taxonomy( $taxonomy2, 'post' ); + + $post_id = self::factory()->post->create(); + $this->assertIsInt( $post_id, 'The post was not created.' ); + + $term_1_id = self::factory()->term->create( array( 'taxonomy' => $taxonomy1 ) ); + $this->assertIsInt( $term_1_id, 'The term in the first taxonomy was not created.' ); + + $term_2_id = self::factory()->term->create( array( 'taxonomy' => $taxonomy2 ) ); + $this->assertIsInt( $term_2_id, 'The term in the second taxonomy was not created.' ); + + wp_set_object_terms( $post_id, $term_1_id, $taxonomy1 ); + wp_set_object_terms( $post_id, $term_2_id, $taxonomy2 ); + + $terms_count = wp_get_object_terms( $post_id, $taxonomy1, array( 'fields' => 'count' ) ); + $this->assertSame( '1', $terms_count, 'Incorrect term count with the single taxonomy registered with args.' ); + + $terms_count = wp_get_object_terms( $post_id, array( $taxonomy1, $taxonomy2 ), array( 'fields' => 'count' ) ); + $this->assertSame( '2', $terms_count, 'Incorrect term count across both taxonomies.' ); + } + + /** + * Verifies that the `id=>` values of the `fields` argument key the results by term ID. + * + * These are the values for which the results are merged with `+` rather than with + * array_merge(), so that the term ID keys survive. + * + * @ticket 61936 + */ + public function test_should_return_terms_keyed_by_term_id_for_id_fields() { + register_taxonomy( 'wptests_tax_hierarchical', 'post', array( 'hierarchical' => true ) ); + + $parent_id = self::factory()->term->create( + array( + 'taxonomy' => 'wptests_tax_hierarchical', + 'name' => 'Parent', + 'slug' => 'parent', + ) + ); + $this->assertIsInt( $parent_id, 'The parent term was not created.' ); + + $child_id = self::factory()->term->create( + array( + 'taxonomy' => 'wptests_tax_hierarchical', + 'name' => 'Child', + 'slug' => 'child', + 'parent' => $parent_id, + ) + ); + $this->assertIsInt( $child_id, 'The child term was not created.' ); + + $post_id = self::factory()->post->create(); + $this->assertIsInt( $post_id, 'The post was not created.' ); + + wp_set_object_terms( $post_id, array( $parent_id, $child_id ), 'wptests_tax_hierarchical' ); + + $expected = array( + 'id=>parent' => array( + $parent_id => 0, + $child_id => $parent_id, + ), + 'id=>name' => array( + $parent_id => 'Parent', + $child_id => 'Child', + ), + 'id=>slug' => array( + $parent_id => 'parent', + $child_id => 'child', + ), + ); + + foreach ( $expected as $fields => $expected_terms ) { + $actual = wp_get_object_terms( + $post_id, + 'wptests_tax_hierarchical', + array( + 'fields' => $fields, + 'orderby' => 'term_id', + 'order' => 'ASC', + ) + ); + + $this->assertSame( $expected_terms, $actual, "Incorrect terms for the '$fields' fields value." ); + } + } + + /** + * Ensures the term ID keys survive for a taxonomy registered with an 'args' array. + * + * Such a taxonomy is queried by a recursive call, and those results were merged with + * array_merge(), which renumbers the integer keys the `id=>` values rely on. + * + * @ticket 61936 + */ + public function test_should_return_terms_keyed_by_term_id_for_id_fields_with_taxonomy_registered_with_args() { + $taxonomy1 = 'wptests_tax'; + $taxonomy2 = 'wptests_tax_2'; + + // Any non-empty 'args' array sends the taxonomy down the recursive path. + register_taxonomy( $taxonomy1, 'post', array( 'args' => array( 0 ) ) ); + register_taxonomy( $taxonomy2, 'post' ); + + $post_id = self::factory()->post->create(); + $this->assertIsInt( $post_id, 'The post was not created.' ); + + $term_1_id = self::factory()->term->create( + array( + 'taxonomy' => $taxonomy1, + 'name' => 'Alpha', + ) + ); + $this->assertIsInt( $term_1_id, 'The term in the first taxonomy was not created.' ); + + $term_2_id = self::factory()->term->create( + array( + 'taxonomy' => $taxonomy2, + 'name' => 'Beta', + ) + ); + $this->assertIsInt( $term_2_id, 'The term in the second taxonomy was not created.' ); + + wp_set_object_terms( $post_id, $term_1_id, $taxonomy1 ); + wp_set_object_terms( $post_id, $term_2_id, $taxonomy2 ); + + $actual = wp_get_object_terms( + $post_id, + array( $taxonomy1, $taxonomy2 ), + array( 'fields' => 'id=>name' ) + ); + + $expected = array( + $term_1_id => 'Alpha', + $term_2_id => 'Beta', + ); + + $this->assertSame( $expected, $actual, 'Terms are not keyed by term ID.' ); + } } From d84095d77bba3dbc360f50b8d04558e759c22469 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sat, 5 Sep 2026 05:56:32 +0000 Subject: [PATCH 389/634] Role/Capability: Ensure `wp_roles()` returns `WP_Roles`. Previously `wp_roles()` only checked whether the `$wp_roles` global was set before returning it, so any code that overwrote that global with another value caused the function to hand back something which is not a `WP_Roles` object. Checking `instanceof` instead guarantees the return type, matching the approach already used by `wp_scripts()` and `wp_styles()`. Developed in https://github.com/WordPress/wordpress-develop/pull/8315. Follow-up to r32541. Props marian1. See #62562. Fixes #62959. git-svn-id: https://develop.svn.wordpress.org/trunk@63490 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/capabilities.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/capabilities.php b/src/wp-includes/capabilities.php index 645ab5588ee5e..6f8b57d50b348 100644 --- a/src/wp-includes/capabilities.php +++ b/src/wp-includes/capabilities.php @@ -1078,10 +1078,10 @@ function user_can_for_site( $user, $site_id, $capability, ...$args ) { * * @return WP_Roles WP_Roles global instance if not already instantiated. */ -function wp_roles() { +function wp_roles(): WP_Roles { global $wp_roles; - if ( ! isset( $wp_roles ) ) { + if ( ! ( $wp_roles instanceof WP_Roles ) ) { $wp_roles = new WP_Roles(); } return $wp_roles; From 235ab8443dc03027356ad91ce666d5dae4d8c093 Mon Sep 17 00:00:00 2001 From: Aki Hamano Date: Sat, 5 Sep 2026 08:44:43 +0000 Subject: [PATCH 390/634] Docs: Align `@param` tag columns in general core API docblocks. Aligns `@param` tag columns in docblocks across the general core APIs per the PHP inline documentation standards. Developed in: https://github.com/WordPress/wordpress-develop/pull/13317 Props mukesh27, wildworks. See #65818. git-svn-id: https://develop.svn.wordpress.org/trunk@63491 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/includes/file.php | 2 +- src/wp-includes/class-wp-fatal-error-handler.php | 4 ++-- src/wp-includes/class-wp-hook.php | 2 +- src/wp-includes/class-wp-http-requests-hooks.php | 6 +++--- src/wp-includes/class-wp-oembed.php | 2 +- src/wp-includes/cron.php | 16 ++++++++-------- src/wp-includes/embed.php | 6 +++--- src/wp-includes/formatting.php | 6 +++--- src/wp-includes/functions.php | 10 +++++----- src/wp-includes/functions.wp-scripts.php | 2 +- src/wp-includes/general-template.php | 2 +- src/wp-includes/link-template.php | 6 +++--- src/wp-includes/load.php | 4 ++-- src/wp-includes/option.php | 2 +- src/wp-includes/pomo/mo.php | 6 +++--- src/wp-includes/pomo/translations.php | 2 +- 16 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/wp-admin/includes/file.php b/src/wp-admin/includes/file.php index 99b9735011bbc..ef5a5025bef22 100644 --- a/src/wp-admin/includes/file.php +++ b/src/wp-admin/includes/file.php @@ -1312,7 +1312,7 @@ function download_url( $url, $timeout = 300, $signature_verification = false ) { * @since 5.2.0 * * @param false|string $signature_url The URL where signatures can be found for a file, or false if none are known. - * @param string $url The URL being verified. + * @param string $url The URL being verified. */ $signature_url = apply_filters( 'wp_signature_url', $signature_url, $url ); diff --git a/src/wp-includes/class-wp-fatal-error-handler.php b/src/wp-includes/class-wp-fatal-error-handler.php index cb09c6fed84c6..3632e372d4393 100644 --- a/src/wp-includes/class-wp-fatal-error-handler.php +++ b/src/wp-includes/class-wp-fatal-error-handler.php @@ -228,8 +228,8 @@ protected function display_default_error_template( $error, $handled ) { * * @since 5.2.0 * - * @param array $args Associative array of arguments passed to `wp_die()`. By default these contain a - * 'response' key, and optionally 'link_url' and 'link_text' keys. + * @param array $args Associative array of arguments passed to `wp_die()`. By default these contain a + * 'response' key, and optionally 'link_url' and 'link_text' keys. * @param array $error Error information retrieved from `error_get_last()`. */ $args = apply_filters( 'wp_php_error_args', $args, $error ); diff --git a/src/wp-includes/class-wp-hook.php b/src/wp-includes/class-wp-hook.php index 5a5874e39cabb..1718878308300 100644 --- a/src/wp-includes/class-wp-hook.php +++ b/src/wp-includes/class-wp-hook.php @@ -526,7 +526,7 @@ public function offsetGet( $offset ) { * @link https://www.php.net/manual/en/arrayaccess.offsetset.php * * @param int|null $offset The offset to assign the value to. - * @param array $value The value to set. + * @param array $value The value to set. * @phpstan-param array $value */ #[ReturnTypeWillChange] diff --git a/src/wp-includes/class-wp-http-requests-hooks.php b/src/wp-includes/class-wp-http-requests-hooks.php index 80e4eb7ef4b9f..f399acc860229 100644 --- a/src/wp-includes/class-wp-http-requests-hooks.php +++ b/src/wp-includes/class-wp-http-requests-hooks.php @@ -68,9 +68,9 @@ public function dispatch( $hook, $parameters = array() ) { * * @since 4.7.0 * - * @param array $parameters Parameters from Requests internal hook. - * @param array $request Request data in WP_Http format. - * @param string $url URL to request. + * @param array $parameters Parameters from Requests internal hook. + * @param array $request Request data in WP_Http format. + * @param string $url URL to request. */ do_action_ref_array( "requests-{$hook}", $parameters, $this->request, $this->url ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores diff --git a/src/wp-includes/class-wp-oembed.php b/src/wp-includes/class-wp-oembed.php index b1a23ff66144d..fa307092d409c 100644 --- a/src/wp-includes/class-wp-oembed.php +++ b/src/wp-includes/class-wp-oembed.php @@ -807,7 +807,7 @@ public function data2html( $data, $url ) { * * @param string|false $html Existing HTML. * @param object $data Data object from WP_oEmbed::data2html() - * @param string $url The original URL passed to oEmbed. + * @param string $url The original URL passed to oEmbed. * @return string|false Possibly modified $html. */ public function _strip_newlines( $html, $data, $url ) { diff --git a/src/wp-includes/cron.php b/src/wp-includes/cron.php index faa5b0fd6681e..82889d7cc7e2f 100644 --- a/src/wp-includes/cron.php +++ b/src/wp-includes/cron.php @@ -787,12 +787,12 @@ function wp_get_scheduled_event( $hook, $args = array(), $timestamp = null ) { * * @since 5.1.0 * - * @param null|false|object $pre Value to return instead. Default null to continue retrieving the event. - * @param string $hook Action hook of the event. - * @param array $args Array containing each separate argument to pass to the hook's callback function. - * Although not passed to a callback, these arguments are used to uniquely identify - * the event. - * @param int|null $timestamp Unix timestamp (UTC) of the event. Null to retrieve next scheduled event. + * @param null|false|object $pre Value to return instead. Default null to continue retrieving the event. + * @param string $hook Action hook of the event. + * @param array $args Array containing each separate argument to pass to the hook's callback function. + * Although not passed to a callback, these arguments are used to uniquely identify + * the event. + * @param int|null $timestamp Unix timestamp (UTC) of the event. Null to retrieve next scheduled event. */ $pre = apply_filters( 'pre_get_scheduled_event', null, $hook, $args, $timestamp ); @@ -966,7 +966,7 @@ function spawn_cron( $gmt_time = 0 ) { * @since 3.5.0 * @since 4.5.0 The `$doing_wp_cron` parameter was added. * - * @param array $cron_request_array { + * @param array $cron_request_array { * An array of cron request URL arguments. * * @type string $url The cron request URL. @@ -979,7 +979,7 @@ function spawn_cron( $gmt_time = 0 ) { * @type bool $sslverify Whether SSL should be verified for the request. Default false. * } * } - * @param string $doing_wp_cron The Unix timestamp (UTC) of the cron lock with microseconds. + * @param string $doing_wp_cron The Unix timestamp (UTC) of the cron lock with microseconds. */ $cron_request = apply_filters( 'cron_request', diff --git a/src/wp-includes/embed.php b/src/wp-includes/embed.php index 003c36cf9de58..e87cf4ec57989 100644 --- a/src/wp-includes/embed.php +++ b/src/wp-includes/embed.php @@ -98,7 +98,7 @@ function wp_embed_defaults( $url = '' ) { * * @see WP_oEmbed * - * @param string $url The URL that should be embedded. + * @param string $url The URL that should be embedded. * @param array|string $args { * Optional. Additional arguments for retrieving embed HTML. Default empty. * @@ -264,8 +264,8 @@ function wp_embed_handler_youtube( $matches, $attr, $url, $rawattr ) { * @since 3.6.0 * * @param array $matches The RegEx matches from the provided regex when calling wp_embed_register_handler(). - * @param array $attr Embed attributes. - * @param string $url The original URL that was matched by the regex. + * @param array $attr Embed attributes. + * @param string $url The original URL that was matched by the regex. * @param array $rawattr The original unmodified attributes. * @return string The embed HTML. */ diff --git a/src/wp-includes/formatting.php b/src/wp-includes/formatting.php index 94f8b3da849cb..1c0b62cf1e14f 100644 --- a/src/wp-includes/formatting.php +++ b/src/wp-includes/formatting.php @@ -3840,9 +3840,9 @@ function sanitize_email( $email ) { * * @since 2.8.0 * - * @param string $sanitized_email The sanitized email address. - * @param string $email The email address, as provided to sanitize_email(). - * @param string|null $message A message to pass to the user. null if email is sanitized. + * @param string $sanitized_email The sanitized email address. + * @param string $email The email address, as provided to sanitize_email(). + * @param string|null $message A message to pass to the user. null if email is sanitized. */ return apply_filters( 'sanitize_email', '', $email, 'email_too_short' ); } diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index 31de822d2aacd..1f29dfb5f29ab 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -3813,7 +3813,7 @@ function wp_nonce_ays( $action ) { * error data with the key 'title' may be used to specify the title. * If `$title` is an integer, then it is treated as the response code. * Default empty string. - * @param string|array|int $args { + * @param string|array|int $args { * Optional. Arguments to control behavior. If `$args` is an integer, then it is treated * as the response code. Default empty array. * @@ -8382,7 +8382,7 @@ function wp_site_admin_email_change_notification( $old_email, $new_email, $optio * * @since 4.9.0 * - * @param array $email_change_email { + * @param array $email_change_email { * Used to build wp_mail(). * * @type string $to The intended recipient. @@ -8395,8 +8395,8 @@ function wp_site_admin_email_change_notification( $old_email, $new_email, $optio * - `###SITEURL###` The URL to the site. * @type string $headers Headers. * } - * @param string $old_email The old site admin email address. - * @param string $new_email The new site admin email address. + * @param string $old_email The old site admin email address. + * @param string $new_email The new site admin email address. */ $email_change_email = apply_filters( 'site_admin_email_change_email', $email_change_email, $old_email, $new_email ); @@ -8941,7 +8941,7 @@ function wp_get_direct_update_https_url() { * @since MU (3.0.0) * @since 5.2.0 $max_execution_time parameter added. * - * @param string $directory Full path of a directory. + * @param string $directory Full path of a directory. * @param int $max_execution_time Maximum time to run before giving up. In seconds. * The timeout is global and is measured from the moment WordPress started to load. * @return int|false|null Size in bytes if a valid directory. False if not. Null if timeout. diff --git a/src/wp-includes/functions.wp-scripts.php b/src/wp-includes/functions.wp-scripts.php index 5e9589252124b..52504b890ad65 100644 --- a/src/wp-includes/functions.wp-scripts.php +++ b/src/wp-includes/functions.wp-scripts.php @@ -445,7 +445,7 @@ function wp_deregister_script( $handle ) { * as a query string for cache busting purposes. If version is set to false, a version * number is automatically added equal to current installed WordPress version. * If set to null, no version is added. - * @param array|bool $args { + * @param array|bool $args { * Optional. An array of extra args for the script. Default empty array. * Otherwise, it may be a boolean in which case it determines whether the script is printed in the footer. Default false. * diff --git a/src/wp-includes/general-template.php b/src/wp-includes/general-template.php index 7ba1d623f4631..63a3aa67123b2 100644 --- a/src/wp-includes/general-template.php +++ b/src/wp-includes/general-template.php @@ -4814,7 +4814,7 @@ function get_language_attributes( $doctype = 'html' ) { * @since 2.5.0 * @since 4.3.0 Added the `$doctype` parameter. * - * @param string $output A space-separated list of language attributes. + * @param string $output A space-separated list of language attributes. * @param string $doctype The type of HTML document (xhtml|html). */ return apply_filters( 'language_attributes', $output, $doctype ); diff --git a/src/wp-includes/link-template.php b/src/wp-includes/link-template.php index f4accadb0bf3a..ed37a83a87506 100644 --- a/src/wp-includes/link-template.php +++ b/src/wp-includes/link-template.php @@ -2007,9 +2007,9 @@ function get_adjacent_post( $in_same_term = false, $excluded_terms = '', $previo * @since 4.9.0 Added the `$order` parameter. * @since 6.9.0 Adds ID sort to ensure deterministic ordering for posts with identical dates. * - * @param string $order_by The `ORDER BY` clause in the SQL. - * @param WP_Post $post WP_Post object. - * @param string $order Sort order. 'DESC' for previous post, 'ASC' for next. + * @param string $order_by The `ORDER BY` clause in the SQL. + * @param WP_Post $post WP_Post object. + * @param string $order Sort order. 'DESC' for previous post, 'ASC' for next. */ $sort = apply_filters( "get_{$adjacent}_post_sort", "ORDER BY p.post_date $order, p.ID $order LIMIT 1", $post, $order ); diff --git a/src/wp-includes/load.php b/src/wp-includes/load.php index 27c58b57dd671..9d407453424c5 100644 --- a/src/wp-includes/load.php +++ b/src/wp-includes/load.php @@ -2042,8 +2042,8 @@ function wp_is_site_protected_by_basic_auth( $context = '' ) { * * @since 5.6.1 * - * @param bool $is_protected Whether the site is protected by Basic Auth. - * @param string $context The context to check for protection. One of 'login', 'admin', or 'front'. + * @param bool $is_protected Whether the site is protected by Basic Auth. + * @param string $context The context to check for protection. One of 'login', 'admin', or 'front'. */ return apply_filters( 'wp_is_site_protected_by_basic_auth', $is_protected, $context ); } diff --git a/src/wp-includes/option.php b/src/wp-includes/option.php index fb808b7ee4df1..5d877e7273f47 100644 --- a/src/wp-includes/option.php +++ b/src/wp-includes/option.php @@ -2978,7 +2978,7 @@ function register_initial_settings() { * @param string $option_group A settings group name. Should correspond to an allowed option key name. * Default allowed option key names include 'general', 'discussion', 'media', * 'reading', 'writing', and 'options'. - * @param string $option_name The name of an option to sanitize and save. + * @param string $option_name The name of an option to sanitize and save. * @param array $args { * Data used to describe the setting when registered. * diff --git a/src/wp-includes/pomo/mo.php b/src/wp-includes/pomo/mo.php index 1bbc40ab65aa2..c519633d8b968 100644 --- a/src/wp-includes/pomo/mo.php +++ b/src/wp-includes/pomo/mo.php @@ -310,10 +310,10 @@ public function import_from_reader( $reader ) { * found in a MO file * * @static - * @param string $original original string to translate from MO file. Might contain - * 0x04 as context separator or 0x00 as singular/plural separator + * @param string $original original string to translate from MO file. Might contain + * 0x04 as context separator or 0x00 as singular/plural separator * @param string $translation translation string from MO file. Might contain - * 0x00 as a plural translations separator + * 0x00 as a plural translations separator * @return Translation_Entry Entry instance. */ public function &make_entry( $original, $translation ) { diff --git a/src/wp-includes/pomo/translations.php b/src/wp-includes/pomo/translations.php index c4a9ba72d6755..64b9295ee6634 100644 --- a/src/wp-includes/pomo/translations.php +++ b/src/wp-includes/pomo/translations.php @@ -91,7 +91,7 @@ public function add_entry_or_merge( $entry ) { * @since 2.8.0 * * @param string $header header name, without trailing : - * @param string $value header value, without trailing \n + * @param string $value header value, without trailing \n */ public function set_header( $header, $value ) { $this->headers[ $header ] = $value; From c97b9967b3b947a84cb1230ebed3b8399f303264 Mon Sep 17 00:00:00 2001 From: Aki Hamano Date: Sat, 5 Sep 2026 08:51:09 +0000 Subject: [PATCH 391/634] Docs: Align `@param` tag columns in administration docblocks. Aligns `@param` tag columns in docblocks across the administration screens per the PHP inline documentation standards. Developed in: https://github.com/WordPress/wordpress-develop/pull/13316 Props mukesh27, wildworks. See #65818. git-svn-id: https://develop.svn.wordpress.org/trunk@63492 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/includes/class-wp-community-events.php | 2 +- src/wp-admin/includes/class-wp-internal-pointers.php | 4 ++-- src/wp-admin/includes/class-wp-list-table.php | 2 +- src/wp-admin/includes/class-wp-posts-list-table.php | 2 +- src/wp-admin/includes/class-wp-terms-list-table.php | 4 ++-- src/wp-admin/includes/list-table.php | 2 +- src/wp-admin/includes/template.php | 2 +- src/wp-includes/class-walker-nav-menu.php | 10 +++++----- src/wp-includes/class-walker-page.php | 2 +- src/wp-includes/class-wp-admin-bar.php | 2 +- src/wp-includes/class-wp-customize-manager.php | 2 +- .../customize/class-wp-customize-selective-refresh.php | 2 +- src/wp-includes/widgets.php | 2 +- 13 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/wp-admin/includes/class-wp-community-events.php b/src/wp-admin/includes/class-wp-community-events.php index a31b3651b9a1c..d6a0c8161add9 100644 --- a/src/wp-admin/includes/class-wp-community-events.php +++ b/src/wp-admin/includes/class-wp-community-events.php @@ -39,7 +39,7 @@ class WP_Community_Events { * * @since 4.8.0 * - * @param int $user_id WP user ID. + * @param int $user_id WP user ID. * @param false|array $user_location { * Stored location data for the user. false to pass no location. * diff --git a/src/wp-admin/includes/class-wp-internal-pointers.php b/src/wp-admin/includes/class-wp-internal-pointers.php index 9a2135b5279fd..22233884b4beb 100644 --- a/src/wp-admin/includes/class-wp-internal-pointers.php +++ b/src/wp-admin/includes/class-wp-internal-pointers.php @@ -109,8 +109,8 @@ public static function enqueue_scripts( $hook_suffix ) { * @since 3.3.0 * * @param string $pointer_id The pointer ID. - * @param string $selector The HTML elements, on which the pointer should be attached. - * @param array $args Arguments to be passed to the pointer JS (see wp-pointer.js). + * @param string $selector The HTML elements, on which the pointer should be attached. + * @param array $args Arguments to be passed to the pointer JS (see wp-pointer.js). */ private static function print_js( $pointer_id, $selector, $args ) { if ( empty( $pointer_id ) || empty( $selector ) || empty( $args ) || empty( $args['content'] ) ) { diff --git a/src/wp-admin/includes/class-wp-list-table.php b/src/wp-admin/includes/class-wp-list-table.php index 17ec0c28f5c1f..df8e71834e0db 100644 --- a/src/wp-admin/includes/class-wp-list-table.php +++ b/src/wp-admin/includes/class-wp-list-table.php @@ -733,7 +733,7 @@ protected function months_dropdown( $post_type ) { * * @since 5.7.0 * - * @param object[]|false $months 'Months' drop-down results. Default false. + * @param object[]|false $months 'Months' drop-down results. Default false. * @param string $post_type The post type. */ $months = apply_filters( 'pre_months_dropdown_query', false, $post_type ); diff --git a/src/wp-admin/includes/class-wp-posts-list-table.php b/src/wp-admin/includes/class-wp-posts-list-table.php index bb8382569dbaa..d3d631b9b4467 100644 --- a/src/wp-admin/includes/class-wp-posts-list-table.php +++ b/src/wp-admin/includes/class-wp-posts-list-table.php @@ -1854,7 +1854,7 @@ public function inline_edit() { * @see wp_dropdown_users() * * @param array $users_opt An array of arguments passed to wp_dropdown_users(). - * @param bool $bulk A flag to denote if it's a bulk action. + * @param bool $bulk A flag to denote if it's a bulk action. */ $users_opt = apply_filters( 'quick_edit_dropdown_authors_args', $users_opt, $bulk ); diff --git a/src/wp-admin/includes/class-wp-terms-list-table.php b/src/wp-admin/includes/class-wp-terms-list-table.php index 561888fed8394..9481f0967a744 100644 --- a/src/wp-admin/includes/class-wp-terms-list-table.php +++ b/src/wp-admin/includes/class-wp-terms-list-table.php @@ -395,8 +395,8 @@ public function column_name( $tag ) { * * @see WP_Terms_List_Table::column_name() * - * @param string $pad_tag_name The term name, padded if not top-level. - * @param WP_Term $tag Term object. + * @param string $pad_tag_name The term name, padded if not top-level. + * @param WP_Term $tag Term object. */ $name = apply_filters( 'term_name', $pad . ' ' . $tag->name, $tag ); diff --git a/src/wp-admin/includes/list-table.php b/src/wp-admin/includes/list-table.php index 1e2c190c80fe9..97dfe4f858c7e 100644 --- a/src/wp-admin/includes/list-table.php +++ b/src/wp-admin/includes/list-table.php @@ -84,7 +84,7 @@ function _get_list_table( $class_name, $args = array() ) { * * @since 2.7.0 * - * @param string $screen The handle for the screen to register column headers for. This is + * @param string $screen The handle for the screen to register column headers for. This is * usually the hook name returned by the `add_*_page()` functions. * @param string[] $columns An array of columns with column IDs as the keys and translated * column names as the values. diff --git a/src/wp-admin/includes/template.php b/src/wp-admin/includes/template.php index e7034e1499ecd..a24aae32cc8dd 100644 --- a/src/wp-admin/includes/template.php +++ b/src/wp-admin/includes/template.php @@ -1808,7 +1808,7 @@ function do_settings_sections( $page ) { * * @global array $wp_settings_fields Storage array of settings fields and their pages/sections. * - * @param string $page Slug title of the admin page whose settings fields you want to show. + * @param string $page Slug title of the admin page whose settings fields you want to show. * @param string $section Slug title of the settings section whose fields you want to show. */ function do_settings_fields( $page, $section ) { diff --git a/src/wp-includes/class-walker-nav-menu.php b/src/wp-includes/class-walker-nav-menu.php index 3d9f442bb8e87..8047047757cea 100644 --- a/src/wp-includes/class-walker-nav-menu.php +++ b/src/wp-includes/class-walker-nav-menu.php @@ -99,13 +99,13 @@ public function start_lvl( &$output, $depth = 0, $args = null ) { * * @since 6.3.0 * - * @param array $atts { + * @param array $atts { * The HTML attributes applied to the `
-
+
div:not(.boot-layout-container):not(#screen-meta) { + body.js #wpbody-content > div:not(#options-connectors-wp-admin-app):not(#screen-meta) { display: none; } body.js #wpfooter { @@ -324,7 +328,7 @@ function wp_options_connectors_wp_admin_render_page() { ); ?>
-
+
{ -}; -var useIsoLayoutEffect = typeof document !== "undefined" ? React4.useLayoutEffect : noop; - // node_modules/@base-ui/utils/warn.mjs var set2; if (true) { @@ -379,17 +373,14 @@ function warn(...messages) { } } -// node_modules/@base-ui/react/internals/direction-context/DirectionContext.mjs -var React5 = __toESM(require_react(), 1); -var DirectionContext = /* @__PURE__ */ React5.createContext(void 0); -if (true) DirectionContext.displayName = "DirectionContext"; -function useDirection() { - const context = React5.useContext(DirectionContext); - return context?.direction ?? "ltr"; -} +// node_modules/@base-ui/utils/useIsoLayoutEffect.mjs +var React3 = __toESM(require_react(), 1); +var noop = () => { +}; +var useIsoLayoutEffect = typeof document !== "undefined" ? React3.useLayoutEffect : noop; // node_modules/@base-ui/react/internals/useRenderElement.mjs -var React8 = __toESM(require_react(), 1); +var React6 = __toESM(require_react(), 1); // node_modules/@base-ui/utils/useMergedRefs.mjs function useMergedRefs(a, b, c, d) { @@ -464,7 +455,7 @@ function update(forkRef, refs) { if (typeof cleanupCallback === "function") { cleanupCallback(); } else { - ref(null); + void ref(null); } break; } @@ -481,18 +472,18 @@ function update(forkRef, refs) { } // node_modules/@base-ui/utils/getReactElementRef.mjs -var React7 = __toESM(require_react(), 1); +var React5 = __toESM(require_react(), 1); // node_modules/@base-ui/utils/reactVersion.mjs -var React6 = __toESM(require_react(), 1); -var majorVersion = parseInt(React6.version, 10); +var React4 = __toESM(require_react(), 1); +var majorVersion = parseInt(React4.version, 10); function isReactVersionAtLeast(reactVersionToCheck) { return majorVersion >= reactVersionToCheck; } // node_modules/@base-ui/utils/getReactElementRef.mjs function getReactElementRef(element) { - if (!/* @__PURE__ */ React7.isValidElement(element)) { + if (!/* @__PURE__ */ React5.isValidElement(element)) { return null; } const reactElement = element; @@ -730,17 +721,17 @@ function useRenderElementProps(componentProps, params = {}) { state = EMPTY_OBJECT, ref, props, - stateAttributesMapping: stateAttributesMapping3, + stateAttributesMapping, enabled = true } = params; const className = enabled ? resolveClassName(classNameProp, state) : void 0; const style = enabled ? resolveStyle(styleProp, state) : void 0; - const stateProps = enabled ? getStateAttributesProps(state, stateAttributesMapping3) : EMPTY_OBJECT; + const stateProps = enabled ? getStateAttributesProps(state, stateAttributesMapping) : EMPTY_OBJECT; const resolvedProps = enabled && props ? resolveRenderFunctionProps(props) : void 0; const outProps = enabled ? mergeObjects(stateProps, resolvedProps) ?? {} : EMPTY_OBJECT; if (typeof document !== "undefined") { if (!enabled) { - useMergedRefs(null, null); + void useMergedRefs(null, null); } else if (Array.isArray(ref)) { outProps.ref = useMergedRefsN([outProps.ref, getReactElementRef(renderProp), ...ref]); } else { @@ -779,15 +770,15 @@ function evaluateRenderProp(element, render, props, state) { mergedProps.ref = props.ref; let newElement = render; if (newElement?.$$typeof === REACT_LAZY_TYPE) { - const children = React8.Children.toArray(render); + const children = React6.Children.toArray(render); newElement = children[0]; } if (true) { - if (!/* @__PURE__ */ React8.isValidElement(newElement)) { + if (!/* @__PURE__ */ React6.isValidElement(newElement)) { throw new Error(["Base UI: The `render` prop was provided an invalid React element as `React.isValidElement(render)` is `false`.", "A valid React element must be provided to the `render` prop because it is cloned with props to replace the default element.", "https://base-ui.com/r/invalid-render-prop"].join("\n")); } } - return /* @__PURE__ */ React8.cloneElement(newElement, mergedProps); + return /* @__PURE__ */ React6.cloneElement(newElement, mergedProps); } if (element) { if (typeof element === "string") { @@ -824,16 +815,16 @@ function renderTag(Tag, props) { key: props.key }); } - return /* @__PURE__ */ React8.createElement(Tag, props); + return /* @__PURE__ */ React6.createElement(Tag, props); } // node_modules/@base-ui/utils/useId.mjs -var React9 = __toESM(require_react(), 1); +var React7 = __toESM(require_react(), 1); var globalId = 0; function useGlobalId(idOverride, prefix = "mui") { - const [defaultId, setDefaultId] = React9.useState(idOverride); + const [defaultId, setDefaultId] = React7.useState(idOverride); const id = idOverride || defaultId; - React9.useEffect(() => { + React7.useEffect(() => { if (defaultId == null) { globalId += 1; setDefaultId(`${prefix}-${globalId}`); @@ -957,17 +948,16 @@ function createChangeEventDetails(reason, event, trigger, customProperties) { } // node_modules/@base-ui/react/internals/useTransitionStatus.mjs -var React11 = __toESM(require_react(), 1); +var React9 = __toESM(require_react(), 1); // node_modules/@base-ui/utils/useOnMount.mjs -var React10 = __toESM(require_react(), 1); -var EMPTY = []; +var React8 = __toESM(require_react(), 1); function useOnMount(fn) { - React10.useEffect(fn, EMPTY); + React8.useEffect(fn, EMPTY_ARRAY); } // node_modules/@base-ui/utils/useAnimationFrame.mjs -var EMPTY2 = null; +var EMPTY = null; var LAST_RAF = globalThis.requestAnimationFrame; var Scheduler = class { /* This implementation uses an array as a backing data-structure for frame callbacks. @@ -1027,21 +1017,21 @@ var AnimationFrame = class _AnimationFrame { static cancel(id) { return scheduler.cancel(id); } - currentId = EMPTY2; + currentId = EMPTY; /** * Executes `fn` after `delay`, clearing any previously scheduled call. */ request(fn) { this.cancel(); this.currentId = scheduler.request(() => { - this.currentId = EMPTY2; + this.currentId = EMPTY; fn(); }); } cancel = () => { - if (this.currentId !== EMPTY2) { + if (this.currentId !== EMPTY) { scheduler.cancel(this.currentId); - this.currentId = EMPTY2; + this.currentId = EMPTY; } }; disposeEffect = () => { @@ -1056,8 +1046,8 @@ function useAnimationFrame() { // node_modules/@base-ui/react/internals/useTransitionStatus.mjs function useTransitionStatus(open, enableIdleState = false, deferEndingState = false) { - const [transitionStatus, setTransitionStatus] = React11.useState(open && enableIdleState ? "idle" : void 0); - const [mounted, setMounted] = React11.useState(open); + const [transitionStatus, setTransitionStatus] = React9.useState(open && enableIdleState ? "idle" : void 0); + const [mounted, setMounted] = React9.useState(open); if (open && !mounted) { setMounted(true); setTransitionStatus("starting"); @@ -1118,10 +1108,10 @@ var TransitionStatusDataAttributes = /* @__PURE__ */ (function(TransitionStatusD return TransitionStatusDataAttributes2; })({}); var STARTING_HOOK = { - [TransitionStatusDataAttributes.startingStyle]: "" + "data-starting-style": "" }; var ENDING_HOOK = { - [TransitionStatusDataAttributes.endingStyle]: "" + "data-ending-style": "" }; var transitionStatusMapping = { transitionStatus(value) { @@ -1136,7 +1126,7 @@ var transitionStatusMapping = { }; // node_modules/@base-ui/react/internals/use-button/useButton.mjs -var React14 = __toESM(require_react(), 1); +var React12 = __toESM(require_react(), 1); // node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.mjs function hasWindow() { @@ -1295,11 +1285,11 @@ function getFrameElement(win) { } // node_modules/@base-ui/react/internals/composite/root/CompositeRootContext.mjs -var React12 = __toESM(require_react(), 1); -var CompositeRootContext = /* @__PURE__ */ React12.createContext(void 0); +var React10 = __toESM(require_react(), 1); +var CompositeRootContext = /* @__PURE__ */ React10.createContext(void 0); if (true) CompositeRootContext.displayName = "CompositeRootContext"; function useCompositeRootContext(optional = false) { - const context = React12.useContext(CompositeRootContext); + const context = React10.useContext(CompositeRootContext); if (context === void 0 && !optional) { throw new Error(true ? "Base UI: CompositeRootContext is missing. Composite parts must be placed within ." : formatErrorMessage_default(16)); } @@ -1307,7 +1297,7 @@ function useCompositeRootContext(optional = false) { } // node_modules/@base-ui/react/utils/useFocusableWhenDisabled.mjs -var React13 = __toESM(require_react(), 1); +var React11 = __toESM(require_react(), 1); function useFocusableWhenDisabled(parameters) { const { focusableWhenDisabled, @@ -1318,7 +1308,7 @@ function useFocusableWhenDisabled(parameters) { } = parameters; const isFocusableComposite = composite && focusableWhenDisabled !== false; const isNonFocusableComposite = composite && focusableWhenDisabled === false; - const props = React13.useMemo(() => { + const props = React11.useMemo(() => { const additionalProps = { // allow Tabbing away from focusableWhenDisabled elements onKeyDown(event) { @@ -1346,6 +1336,27 @@ function useFocusableWhenDisabled(parameters) { }; } +// node_modules/@base-ui/utils/owner.mjs +function ownerDocument(node) { + return node?.ownerDocument || document; +} + +// node_modules/@base-ui/react/utils/dispatchClickWithModifiers.mjs +function dispatchClickWithModifiers(target, sourceEvent, { + detail = 0 +} = {}) { + target.dispatchEvent(new (getWindow(target)).PointerEvent("click", { + bubbles: true, + cancelable: true, + composed: true, + detail, + shiftKey: sourceEvent.shiftKey, + ctrlKey: sourceEvent.ctrlKey, + altKey: sourceEvent.altKey, + metaKey: sourceEvent.metaKey + })); +} + // node_modules/@base-ui/react/internals/use-button/useButton.mjs function useButton(parameters = {}) { const { @@ -1355,7 +1366,7 @@ function useButton(parameters = {}) { native: isNativeButton = true, composite: compositeProp } = parameters; - const elementRef = React14.useRef(null); + const elementRef = React12.useRef(null); const compositeRootContext = useCompositeRootContext(true); const isCompositeItem = compositeProp ?? compositeRootContext !== void 0; const { @@ -1368,7 +1379,7 @@ function useButton(parameters = {}) { isNativeButton }); if (true) { - React14.useEffect(() => { + React12.useEffect(() => { if (!elementRef.current) { return; } @@ -1386,7 +1397,7 @@ function useButton(parameters = {}) { } }, [isNativeButton]); } - const updateDisabled = React14.useCallback(() => { + const updateDisabled = React12.useCallback(() => { const element = elementRef.current; if (!isButtonElement(element)) { return; @@ -1396,7 +1407,7 @@ function useButton(parameters = {}) { } }, [disabled2, focusableWhenDisabledProps.disabled, isCompositeItem]); useIsoLayoutEffect(updateDisabled, [updateDisabled]); - const getButtonProps = React14.useCallback((externalProps = {}) => { + const getButtonProps = React12.useCallback((externalProps = {}) => { const { onClick: externalOnClick, onMouseDown: externalOnMouseDown, @@ -1441,22 +1452,25 @@ function useButton(parameters = {}) { return; } event.preventDefault(); - if (isLink || isNativeButton && isButton) { - currentTarget.click(); - event.preventBaseUIHandler(); - } else if (shouldClick) { - externalOnClick?.(event); + if (!isNativeButton || isButton) { event.preventBaseUIHandler(); + dispatchClickWithModifiers(currentTarget, event); } return; } - if (shouldClick) { - if (!isNativeButton && (isSpaceKey || isEnterKey)) { + if (!shouldClick || isNativeButton || !isSpaceKey && !isEnterKey) { + if (isCurrentTarget && isLink && isSpaceKey) { event.preventDefault(); } - if (!isNativeButton && isEnterKey) { - externalOnClick?.(event); - } + return; + } + if (event.defaultPrevented) { + return; + } + event.preventDefault(); + if (isEnterKey) { + event.preventBaseUIHandler(); + dispatchClickWithModifiers(currentTarget, event); } }, onKeyUp(event) { @@ -1472,8 +1486,9 @@ function useButton(parameters = {}) { if (event.baseUIHandlerPrevented) { return; } - if (event.target === event.currentTarget && !isNativeButton && !isCompositeItem && event.key === " ") { - externalOnClick?.(event); + if (event.target === event.currentTarget && !isNativeButton && !isCompositeItem && !event.defaultPrevented && event.key === " ") { + event.preventBaseUIHandler(); + dispatchClickWithModifiers(event.currentTarget, event); } }, onPointerDown(event) { @@ -1502,7 +1517,7 @@ function isButtonElement(elem) { return isHTMLElement(elem) && elem.tagName === "BUTTON"; } function isValidLinkElement(elem) { - return Boolean(elem?.tagName === "A" && elem?.href); + return isHTMLElement(elem) && elem.tagName === "A" && Boolean(elem.href); } // node_modules/@base-ui/utils/addEventListener.mjs @@ -1531,13 +1546,8 @@ function createLatestRef(value) { return latest; } -// node_modules/@base-ui/utils/owner.mjs -function ownerDocument(node) { - return node?.ownerDocument || document; -} - // node_modules/@base-ui/react/internals/useOpenChangeComplete.mjs -var React15 = __toESM(require_react(), 1); +var React13 = __toESM(require_react(), 1); // node_modules/@base-ui/react/internals/useAnimationsFinished.mjs var ReactDOM = __toESM(require_react_dom(), 1); @@ -1551,7 +1561,7 @@ function resolveRef(maybeRef) { } // node_modules/@base-ui/react/internals/useAnimationsFinished.mjs -function useAnimationsFinished(elementOrRef, waitForStartingStyleRemoved = false, treatAbortedAsFinished = true) { +function useAnimationsFinished(elementOrRef, waitForStartingStyleRemoved = false) { const frame = useAnimationFrame(); return useStableCallback((fnToExecute, signal = null) => { frame.cancel(); @@ -1572,21 +1582,20 @@ function useAnimationsFinished(elementOrRef, waitForStartingStyleRemoved = false if (!signal?.aborted) { done(); } - }).catch(() => { - if (treatAbortedAsFinished) { - if (!signal?.aborted) { - done(); - } + }, () => { + if (signal?.aborted) { return; } const currentAnimations = resolvedElement.getAnimations(); - if (!signal?.aborted && currentAnimations.length > 0 && currentAnimations.some((animation) => animation.pending || animation.playState !== "finished")) { + if (currentAnimations.some((animation) => animation.pending || animation.playState !== "finished")) { exec(); + return; } + done(); }); } if (waitForStartingStyleRemoved) { - const startingStyleAttribute = TransitionStatusDataAttributes.startingStyle; + const startingStyleAttribute = "data-starting-style"; if (!resolvedElement.hasAttribute(startingStyleAttribute)) { frame.request(exec); return; @@ -1619,8 +1628,8 @@ function useOpenChangeComplete(parameters) { onComplete: onCompleteParam } = parameters; const onComplete = useStableCallback(onCompleteParam); - const runOnceAnimationsFinish = useAnimationsFinished(ref, open, false); - React15.useEffect(() => { + const runOnceAnimationsFinish = useAnimationsFinished(ref, open); + React13.useEffect(() => { if (!enabled) { return void 0; } @@ -1632,16 +1641,6 @@ function useOpenChangeComplete(parameters) { }, [enabled, open, onComplete, runOnceAnimationsFinish]); } -// node_modules/@base-ui/utils/useOnFirstRender.mjs -var React16 = __toESM(require_react(), 1); -function useOnFirstRender(fn) { - const ref = React16.useRef(true); - if (ref.current) { - ref.current = false; - fn(); - } -} - // node_modules/@base-ui/utils/platform/parts.mjs var parts_exports = {}; __export(parts_exports, { @@ -1733,29 +1732,29 @@ __export(env_exports, { var jsdom = /jsdom|happydom/.test(lowerUserAgent); // node_modules/@base-ui/utils/useTimeout.mjs -var EMPTY3 = 0; +var EMPTY2 = 0; var Timeout = class _Timeout { static create() { return new _Timeout(); } - currentId = EMPTY3; + currentId = EMPTY2; /** * Executes `fn` after `delay`, clearing any previously scheduled call. */ start(delay, fn) { this.clear(); this.currentId = setTimeout(() => { - this.currentId = EMPTY3; + this.currentId = EMPTY2; fn(); }, delay); } isStarted() { - return this.currentId !== EMPTY3; + return this.currentId !== EMPTY2; } clear = () => { - if (this.currentId !== EMPTY3) { + if (this.currentId !== EMPTY2) { clearTimeout(this.currentId); - this.currentId = EMPTY3; + this.currentId = EMPTY2; } }; disposeEffect = () => { @@ -1769,7 +1768,7 @@ function useTimeout() { } // node_modules/@base-ui/react/floating-ui-react/components/FloatingDelayGroup.mjs -var React17 = __toESM(require_react(), 1); +var React14 = __toESM(require_react(), 1); // node_modules/@base-ui/react/floating-ui-react/utils/event.mjs function isReactEvent(event) { @@ -1903,7 +1902,7 @@ function isHoverOpenEvent(openEventType) { // node_modules/@base-ui/react/floating-ui-react/components/FloatingDelayGroup.mjs var import_jsx_runtime = __toESM(require_jsx_runtime(), 1); -var FloatingDelayGroupContext = /* @__PURE__ */ React17.createContext({ +var FloatingDelayGroupContext = /* @__PURE__ */ React14.createContext({ hasProvider: false, timeoutMs: 0, delayRef: { @@ -1930,10 +1929,10 @@ function FloatingDelayGroup(props) { delay, timeoutMs = 0 } = props; - const delayRef = React17.useRef(delay); - const initialDelayRef = React17.useRef(delay); - const currentIdRef = React17.useRef(null); - const currentContextRef = React17.useRef(null); + const delayRef = React14.useRef(delay); + const initialDelayRef = React14.useRef(delay); + const currentIdRef = React14.useRef(null); + const currentContextRef = React14.useRef(null); const timeout = useTimeout(); useIsoLayoutEffect(() => { initialDelayRef.current = delay; @@ -1947,7 +1946,7 @@ function FloatingDelayGroup(props) { }; }, [delay, currentIdRef, delayRef, initialDelayRef]); return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FloatingDelayGroupContext.Provider, { - value: React17.useMemo(() => ({ + value: React14.useMemo(() => ({ hasProvider: true, delayRef, initialDelayRef, @@ -1967,7 +1966,7 @@ function useDelayGroup(context, options = { } = options; const store2 = "rootStore" in context ? context.rootStore : context; const floatingId = store2.useState("floatingId"); - const groupContext = React17.useContext(FloatingDelayGroupContext); + const groupContext = React14.useContext(FloatingDelayGroupContext); const { currentIdRef, delayRef, @@ -1977,22 +1976,13 @@ function useDelayGroup(context, options = { hasProvider, timeout } = groupContext; - const [isInstantPhase, setIsInstantPhase] = React17.useState(false); - const openRef = React17.useRef(open); - const isUnmountedRef = React17.useRef(false); + const [isInstantPhase, setIsInstantPhase] = React14.useState(false); + const openRef = React14.useRef(open); useIsoLayoutEffect(() => { openRef.current = open; }, [open]); - useIsoLayoutEffect(() => { - return () => { - isUnmountedRef.current = true; - }; - }, []); useIsoLayoutEffect(() => { function unset() { - if (!isUnmountedRef.current) { - setIsInstantPhase(false); - } currentContextRef.current?.setIsInstantPhase(false); currentIdRef.current = null; currentContextRef.current = null; @@ -2060,7 +2050,7 @@ function useDelayGroup(context, options = { } }; }, [currentContextRef, currentIdRef, delayRef, floatingId, initialDelayRef, timeout]); - return React17.useMemo(() => ({ + return React14.useMemo(() => ({ hasProvider, delayRef, isInstantPhase @@ -2080,7 +2070,7 @@ function mergeCleanups(...cleanups) { } // node_modules/@base-ui/react/utils/FocusGuard.mjs -var React18 = __toESM(require_react(), 1); +var React15 = __toESM(require_react(), 1); // node_modules/@base-ui/utils/visuallyHidden.mjs var visuallyHiddenBase = { @@ -2106,8 +2096,8 @@ var visuallyHiddenInput = { // node_modules/@base-ui/react/utils/FocusGuard.mjs var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1); -var FocusGuard = /* @__PURE__ */ React18.forwardRef(function FocusGuard2(props, ref) { - const [role, setRole] = React18.useState(); +var FocusGuard = /* @__PURE__ */ React15.forwardRef(function FocusGuard2(props, ref) { + const [role, setRole] = React15.useState(); useIsoLayoutEffect(() => { if (parts_exports.screenReader.voiceOver && parts_exports.engine.webkit) { setRole("button"); @@ -2130,7 +2120,6 @@ var FocusGuard = /* @__PURE__ */ React18.forwardRef(function FocusGuard2(props, if (true) FocusGuard.displayName = "FocusGuard"; // node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs -var sides = ["top", "right", "bottom", "left"]; var min = Math.min; var max = Math.max; var round = Math.round; @@ -2452,7 +2441,7 @@ function createAttribute(name) { } // node_modules/@base-ui/react/floating-ui-react/components/FloatingPortal.mjs -var React19 = __toESM(require_react(), 1); +var React16 = __toESM(require_react(), 1); var ReactDOM2 = __toESM(require_react_dom(), 1); // node_modules/@base-ui/react/internals/constants.mjs @@ -2477,9 +2466,9 @@ var ownerVisuallyHidden = { // node_modules/@base-ui/react/floating-ui-react/components/FloatingPortal.mjs var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1); -var PortalContext = /* @__PURE__ */ React19.createContext(null); +var PortalContext = /* @__PURE__ */ React16.createContext(null); if (true) PortalContext.displayName = "PortalContext"; -var usePortalContext = () => React19.useContext(PortalContext); +var usePortalContext = () => React16.useContext(PortalContext); var attr = createAttribute("portal"); function useFloatingPortalNode(props = {}) { const { @@ -2491,14 +2480,14 @@ function useFloatingPortalNode(props = {}) { const uniqueId = useId(); const portalContext = usePortalContext(); const parentPortalNode = portalContext?.portalNode; - const [containerElement, setContainerElement] = React19.useState(null); - const [portalNode, setPortalNode] = React19.useState(null); + const [containerElement, setContainerElement] = React16.useState(null); + const [portalNode, setPortalNode] = React16.useState(null); const setPortalNodeRef = useStableCallback((node) => { if (node !== null) { setPortalNode(node); } }); - const containerRef = React19.useRef(null); + const containerRef = React16.useRef(null); useIsoLayoutEffect(() => { if (containerProp === null) { if (containerRef.current) { @@ -2508,9 +2497,6 @@ function useFloatingPortalNode(props = {}) { } return; } - if (uniqueId == null) { - return; - } const resolvedContainer = (containerProp && (isNode(containerProp) ? containerProp : containerProp.current)) ?? parentPortalNode ?? document.body; if (resolvedContainer == null) { if (containerRef.current) { @@ -2525,7 +2511,7 @@ function useFloatingPortalNode(props = {}) { setPortalNode(null); setContainerElement(resolvedContainer); } - }, [containerProp, parentPortalNode, uniqueId]); + }, [containerProp, parentPortalNode]); const portalElement = useRenderElement("div", componentProps, { ref: [ref, setPortalNodeRef], props: [{ @@ -2535,39 +2521,42 @@ function useFloatingPortalNode(props = {}) { }); const portalSubtree = containerElement && portalElement ? /* @__PURE__ */ ReactDOM2.createPortal(portalElement, containerElement) : null; return { - portalNode, - portalSubtree + node: portalNode, + // `id` and `render` props can override or remove the generated ID. Use the exact + // rendered value so `aria-owns` never points at an ID absent from the DOM. + nodeId: /* @__PURE__ */ React16.isValidElement(portalElement) ? portalElement.props.id : void 0, + subtree: portalSubtree }; } -var FloatingPortal = /* @__PURE__ */ React19.forwardRef(function FloatingPortal2(componentProps, forwardedRef) { +var FloatingPortal = /* @__PURE__ */ React16.forwardRef(function FloatingPortal2(componentProps, forwardedRef) { const { render, className, style, children, container, - renderGuards, ...elementProps } = componentProps; const { - portalNode, - portalSubtree + node: portalNode, + nodeId: portalNodeId, + subtree: portalSubtree } = useFloatingPortalNode({ container, ref: forwardedRef, componentProps, elementProps }); - const beforeOutsideRef = React19.useRef(null); - const afterOutsideRef = React19.useRef(null); - const beforeInsideRef = React19.useRef(null); - const afterInsideRef = React19.useRef(null); - const [focusManagerState, setFocusManagerState] = React19.useState(null); - const focusInsideDisabledRef = React19.useRef(false); + const beforeOutsideRef = React16.useRef(null); + const afterOutsideRef = React16.useRef(null); + const beforeInsideRef = React16.useRef(null); + const afterInsideRef = React16.useRef(null); + const [focusManagerState, setFocusManagerState] = React16.useState(null); + const focusInsideDisabledRef = React16.useRef(false); const modal = focusManagerState?.modal; const open = focusManagerState?.open; - const shouldRenderGuards = typeof renderGuards === "boolean" ? renderGuards : !!focusManagerState && !focusManagerState.modal && focusManagerState.open && !!portalNode; - React19.useEffect(() => { + const shouldRenderGuards = !!focusManagerState && !focusManagerState.modal && focusManagerState.open && !!portalNode; + React16.useEffect(() => { if (!portalNode || modal) { return void 0; } @@ -2593,7 +2582,7 @@ var FloatingPortal = /* @__PURE__ */ React19.forwardRef(function FloatingPortal2 enableFocusInside(portalNode); focusInsideDisabledRef.current = false; }, [open, portalNode]); - const portalContextValue = React19.useMemo(() => ({ + const portalContextValue = React16.useMemo(() => ({ beforeOutsideRef, afterOutsideRef, beforeInsideRef, @@ -2601,7 +2590,7 @@ var FloatingPortal = /* @__PURE__ */ React19.forwardRef(function FloatingPortal2 portalNode, setFocusManagerState }), [portalNode]); - return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(React19.Fragment, { + return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(React16.Fragment, { children: [portalSubtree, /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(PortalContext.Provider, { value: portalContextValue, children: [shouldRenderGuards && portalNode && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(FocusGuard, { @@ -2617,7 +2606,7 @@ var FloatingPortal = /* @__PURE__ */ React19.forwardRef(function FloatingPortal2 } } }), shouldRenderGuards && portalNode && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { - "aria-owns": portalNode.id, + "aria-owns": portalNodeId, style: ownerVisuallyHidden }), portalNode && /* @__PURE__ */ ReactDOM2.createPortal(children, portalNode), shouldRenderGuards && portalNode && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(FocusGuard, { "data-type": "outside", @@ -2641,7 +2630,7 @@ var FloatingPortal = /* @__PURE__ */ React19.forwardRef(function FloatingPortal2 if (true) FloatingPortal.displayName = "FloatingPortal"; // node_modules/@base-ui/react/floating-ui-react/components/FloatingTree.mjs -var React20 = __toESM(require_react(), 1); +var React17 = __toESM(require_react(), 1); // node_modules/@base-ui/react/floating-ui-react/utils/createEventEmitter.mjs function createEventEmitter() { @@ -2664,18 +2653,18 @@ function createEventEmitter() { // node_modules/@base-ui/react/floating-ui-react/components/FloatingTree.mjs var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1); -var FloatingNodeContext = /* @__PURE__ */ React20.createContext(null); +var FloatingNodeContext = /* @__PURE__ */ React17.createContext(null); if (true) FloatingNodeContext.displayName = "FloatingNodeContext"; -var FloatingTreeContext = /* @__PURE__ */ React20.createContext(null); +var FloatingTreeContext = /* @__PURE__ */ React17.createContext(null); if (true) FloatingTreeContext.displayName = "FloatingTreeContext"; -var useFloatingParentNodeId = () => React20.useContext(FloatingNodeContext)?.id || null; +var useFloatingParentNodeId = () => React17.useContext(FloatingNodeContext)?.id || null; var useFloatingTree = (externalTree) => { - const contextTree = React20.useContext(FloatingTreeContext); + const contextTree = React17.useContext(FloatingTreeContext); return externalTree ?? contextTree; }; // node_modules/@base-ui/react/floating-ui-react/hooks/useClientPoint.mjs -var React21 = __toESM(require_react(), 1); +var React18 = __toESM(require_react(), 1); function createVirtualElement(domElement, data) { let offsetX = null; let offsetY = null; @@ -2742,10 +2731,10 @@ function useClientPoint(context, props = {}) { const floating = store2.useState("floatingElement"); const domReference = store2.useState("domReferenceElement"); const dataRef = store2.context.dataRef; - const initialRef = React21.useRef(false); - const cleanupListenerRef = React21.useRef(null); - const [pointerType, setPointerType] = React21.useState(); - const [reactive, setReactive] = React21.useState([]); + const initialRef = React18.useRef(false); + const cleanupListenerRef = React18.useRef(null); + const [pointerType, setPointerType] = React18.useState(); + const [reactive, setReactive] = React18.useState([]); const resetReference = useStableCallback((reference2) => { store2.set("positionReference", reference2); }); @@ -2773,7 +2762,7 @@ function useClientPoint(context, props = {}) { } }); const openCheck = isMouseLikePointerType(pointerType) ? floating : open; - React21.useEffect(() => { + React18.useEffect(() => { if (!enabled) { resetReference(domReference); return void 0; @@ -2801,20 +2790,20 @@ function useClientPoint(context, props = {}) { } return cleanupListener; }, [openCheck, enabled, floating, dataRef, domReference, store2, setReference, resetReference, reactive]); - React21.useEffect(() => () => { + React18.useEffect(() => () => { store2.set("positionReference", null); }, [store2]); - React21.useEffect(() => { + React18.useEffect(() => { if (enabled && !floating) { initialRef.current = false; } }, [enabled, floating]); - React21.useEffect(() => { + React18.useEffect(() => { if (!enabled && open) { initialRef.current = true; } }, [enabled, open]); - const reference = React21.useMemo(() => { + const reference = React18.useMemo(() => { function setPointerTypeRef(event) { setPointerType(event.pointerType); } @@ -2825,14 +2814,14 @@ function useClientPoint(context, props = {}) { onMouseEnter: handleReferenceEnterOrMove }; }, [handleReferenceEnterOrMove]); - return React21.useMemo(() => enabled ? { + return React18.useMemo(() => enabled ? { reference, trigger: reference } : {}, [enabled, reference]); } // node_modules/@base-ui/react/floating-ui-react/hooks/useDismiss.mjs -var React22 = __toESM(require_react(), 1); +var React19 = __toESM(require_react(), 1); function alwaysFalse() { return false; } @@ -2867,12 +2856,12 @@ function useDismiss(context, props = {}) { escapeKey: escapeKeyBubbles, outsidePress: outsidePressBubbles } = normalizeProp(bubbles); - const pressStartedInsideRef = React22.useRef(false); - const pressStartPreventedRef = React22.useRef(false); - const suppressNextOutsideClickRef = React22.useRef(false); - const isComposingRef = React22.useRef(false); - const currentPointerTypeRef = React22.useRef(""); - const touchStateRef = React22.useRef(null); + const pressStartedInsideRef = React19.useRef(false); + const pressStartPreventedRef = React19.useRef(false); + const suppressNextOutsideClickRef = React19.useRef(false); + const isComposingRef = React19.useRef(false); + const currentPointerTypeRef = React19.useRef(""); + const touchStateRef = React19.useRef(null); const cancelDismissOnEndTimeout = useTimeout(); const clearInsideReactTreeTimeout = useTimeout(); const clearInsideReactTree = useStableCallback(() => { @@ -2941,9 +2930,9 @@ function useDismiss(context, props = {}) { pressStartPreventedRef.current = true; } }); - React22.useEffect(() => { + React19.useEffect(() => { if (!open || !enabled) { - return void 0; + return clearInsideReactTree; } dataRef.current.__escapeKeyBubbles = escapeKeyBubbles; dataRef.current.__outsidePressBubbles = outsidePressBubbles; @@ -3189,15 +3178,15 @@ function useDismiss(context, props = {}) { preventedPressSuppressionTimeout.clear(); resetPressStartState(); suppressNextOutsideClickRef.current = false; + clearInsideReactTree(); }; }, [dataRef, floatingElement, escapeKey2, outsidePressEnabled, outsidePress2, open, enabled, escapeKeyBubbles, outsidePressBubbles, closeOnEscapeKeyDown, clearInsideReactTree, getOutsidePressEventProp, hasBlockingChild, isEventWithinOwnElements, tree, store2, cancelDismissOnEndTimeout]); - React22.useEffect(clearInsideReactTree, [outsidePress2, clearInsideReactTree]); - const reference = React22.useMemo(() => ({ + const reference = React19.useMemo(() => ({ onKeyDown: closeOnEscapeKeyDown, onPointerDown: closeOnReferencePress, onClick: closeOnReferencePress }), [closeOnEscapeKeyDown, closeOnReferencePress]); - const floating = React22.useMemo(() => ({ + const floating = React19.useMemo(() => ({ onKeyDown: closeOnEscapeKeyDown, // `onMouseDown` may be blocked if `event.preventDefault()` is called in // `onPointerDown`, such as with . @@ -3217,7 +3206,7 @@ function useDismiss(context, props = {}) { onTouchEndCapture: markInsideReactTree, onTouchMoveCapture: markInsideReactTree }), [closeOnEscapeKeyDown, markInsideReactTree, markPressStartedInsideReactTree, markInsidePressStartPrevented]); - return React22.useMemo(() => enabled ? { + return React19.useMemo(() => enabled ? { reference, floating, trigger: reference @@ -3225,7 +3214,7 @@ function useDismiss(context, props = {}) { } // node_modules/@base-ui/react/floating-ui-react/hooks/useFloating.mjs -var React29 = __toESM(require_react(), 1); +var React27 = __toESM(require_react(), 1); // node_modules/@floating-ui/core/dist/floating-ui.core.mjs function computeCoordsFromPlacement(_ref, placement, rtl) { @@ -3529,67 +3518,6 @@ var flip = function(options) { } }; }; -function getSideOffsets(overflow, rect) { - return { - top: overflow.top - rect.height, - right: overflow.right - rect.width, - bottom: overflow.bottom - rect.height, - left: overflow.left - rect.width - }; -} -function isAnySideFullyClipped(overflow) { - return sides.some((side) => overflow[side] >= 0); -} -var hide = function(options) { - if (options === void 0) { - options = {}; - } - return { - name: "hide", - options, - async fn(state) { - const { - rects, - platform: platform3 - } = state; - const { - strategy = "referenceHidden", - ...detectOverflowOptions - } = evaluate(options, state); - switch (strategy) { - case "referenceHidden": { - const overflow = await platform3.detectOverflow(state, { - ...detectOverflowOptions, - elementContext: "reference" - }); - const offsets = getSideOffsets(overflow, rects.reference); - return { - data: { - referenceHiddenOffsets: offsets, - referenceHidden: isAnySideFullyClipped(offsets) - } - }; - } - case "escaped": { - const overflow = await platform3.detectOverflow(state, { - ...detectOverflowOptions, - altBoundary: true - }); - const offsets = getSideOffsets(overflow, rects.floating); - return { - data: { - escapedOffsets: offsets, - escaped: isAnySideFullyClipped(offsets) - } - }; - } - default: { - return {}; - } - } - } - }; -}; var originSides = /* @__PURE__ */ new Set(["left", "top"]); async function convertValueToCoords(state, options) { const { @@ -4456,7 +4384,6 @@ var offset2 = offset; var shift2 = shift; var flip2 = flip; var size2 = size; -var hide2 = hide; var limitShift2 = limitShift; var computePosition2 = (reference, floating, options) => { const cache = /* @__PURE__ */ new Map(); @@ -4473,7 +4400,7 @@ var computePosition2 = (reference, floating, options) => { }; // node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.mjs -var React23 = __toESM(require_react(), 1); +var React20 = __toESM(require_react(), 1); var import_react2 = __toESM(require_react(), 1); var ReactDOM3 = __toESM(require_react_dom(), 1); var isClient = typeof document !== "undefined"; @@ -4539,7 +4466,7 @@ function roundByDPR(element, value) { return Math.round(value * dpr) / dpr; } function useLatestRef(value) { - const ref = React23.useRef(value); + const ref = React20.useRef(value); index(() => { ref.current = value; }); @@ -4562,7 +4489,7 @@ function useFloating(options) { whileElementsMounted, open } = options; - const [data, setData] = React23.useState({ + const [data, setData] = React20.useState({ x: 0, y: 0, strategy, @@ -4570,19 +4497,19 @@ function useFloating(options) { middlewareData: {}, isPositioned: false }); - const [latestMiddleware, setLatestMiddleware] = React23.useState(middleware); + const [latestMiddleware, setLatestMiddleware] = React20.useState(middleware); if (!deepEqual(latestMiddleware, middleware)) { setLatestMiddleware(middleware); } - const [_reference, _setReference] = React23.useState(null); - const [_floating, _setFloating] = React23.useState(null); - const setReference = React23.useCallback((node) => { + const [_reference, _setReference] = React20.useState(null); + const [_floating, _setFloating] = React20.useState(null); + const setReference = React20.useCallback((node) => { if (node !== referenceRef.current) { referenceRef.current = node; _setReference(node); } }, []); - const setFloating = React23.useCallback((node) => { + const setFloating = React20.useCallback((node) => { if (node !== floatingRef.current) { floatingRef.current = node; _setFloating(node); @@ -4590,14 +4517,14 @@ function useFloating(options) { }, []); const referenceEl = externalReference || _reference; const floatingEl = externalFloating || _floating; - const referenceRef = React23.useRef(null); - const floatingRef = React23.useRef(null); - const dataRef = React23.useRef(data); + const referenceRef = React20.useRef(null); + const floatingRef = React20.useRef(null); + const dataRef = React20.useRef(data); const hasWhileElementsMounted = whileElementsMounted != null; const whileElementsMountedRef = useLatestRef(whileElementsMounted); const platformRef = useLatestRef(platform3); const openRef = useLatestRef(open); - const update2 = React23.useCallback(() => { + const update2 = React20.useCallback(() => { if (!referenceRef.current || !floatingRef.current) { return; } @@ -4635,7 +4562,7 @@ function useFloating(options) { })); } }, [open]); - const isMountedRef = React23.useRef(false); + const isMountedRef = React20.useRef(false); index(() => { isMountedRef.current = true; return () => { @@ -4652,17 +4579,17 @@ function useFloating(options) { update2(); } }, [referenceEl, floatingEl, update2, whileElementsMountedRef, hasWhileElementsMounted]); - const refs = React23.useMemo(() => ({ + const refs = React20.useMemo(() => ({ reference: referenceRef, floating: floatingRef, setReference, setFloating }), [setReference, setFloating]); - const elements = React23.useMemo(() => ({ + const elements = React20.useMemo(() => ({ reference: referenceEl, floating: floatingEl }), [referenceEl, floatingEl]); - const floatingStyles = React23.useMemo(() => { + const floatingStyles = React20.useMemo(() => { const initialStyles = { position: strategy, left: 0, @@ -4688,7 +4615,7 @@ function useFloating(options) { top: y }; }, [strategy, transform, elements.floating, data.x, data.y]); - return React23.useMemo(() => ({ + return React20.useMemo(() => ({ ...data, update: update2, refs, @@ -4735,81 +4662,182 @@ var size3 = (options, deps) => { options: [options, deps] }; }; -var hide3 = (options, deps) => { - const result = hide2(options); - return { - name: result.name, - fn: result.fn, - options: [options, deps] - }; + +// node_modules/@base-ui/react/utils/popups/popupHandle.mjs +var BasePopupHandle = class { + /** + * Stores of every root currently using this handle, in attach order. A handle is meant to be used + * by a single mounted root, but roots can transiently overlap (e.g. during an animated route + * transition), so this stack lets `attachStore`'s cleanup restore the previous root instead of + * leaving a still-mounted root uncontrollable when a newer overlapping root detaches first. + */ + attachedStores = []; + /** + * Store of the root that currently controls the handle: the most recently attached one still + * mounted, or `null` when no root is attached. Imperative methods are no-ops while this is `null`. + */ + attachedStoreValue = null; + /** + * Listeners notified when `attachedStore` changes, so detached triggers can follow the store pointer. + */ + storeListeners = /* @__PURE__ */ new Set(); + /** + * Creates a handle backed by the store used while no root is attached. + * + * @param fallbackStore Inert, closed store handed to detached triggers while no root is attached, + * so they can render and register without a mounted root. Triggers register into whichever store + * `store` currently resolves to, so while detached they live in this store's trigger map and + * migrate themselves to the root's store (and back) as it attaches/detaches. + * @param componentName Component name used to prefix dev warnings, e.g. `'Menu'` produces + * `MenuHandle.open()` in warning text. + * @param throwOnMissingTrigger Whether `open(triggerId)` throws when no trigger with that id is + * registered. Anchored popups (Menu, Popover, Tooltip, PreviewCard) need a trigger to anchor to, + * so they throw; Dialog is not anchored and instead opens unassociated with a dev warning. + */ + constructor(fallbackStore, componentName, throwOnMissingTrigger = true) { + this.fallbackStore = fallbackStore; + this.componentName = componentName; + this.throwOnMissingTrigger = throwOnMissingTrigger; + } + get attachedStore() { + return this.attachedStoreValue; + } + /** + * Store that detached triggers read from: the attached root's store, or an inert fallback store + * used while no root is attached. + * @internal + */ + get store() { + return this.attachedStoreValue ?? this.fallbackStore; + } + /** + * Stable fallback store used for server rendering and hydration. Root stores cannot be recorded on + * the handle during render because a handle can be shared by concurrent server-rendered requests. + * @internal + */ + get serverStore() { + return this.fallbackStore; + } + /** + * Subscribes to changes of the attached store pointer so detached triggers re-render and re-bind + * when a root attaches or detaches. Returns a function that removes the listener. + * @internal + */ + subscribeStore(listener) { + this.storeListeners.add(listener); + return () => { + this.storeListeners.delete(listener); + }; + } + /** + * Points the handle at a root's store and notifies subscribers so detached triggers re-render and + * re-register into it (their registration ref re-fires on the store-pointer change). Returns a + * cleanup function that detaches the store again. + * @internal + */ + attachStore(newStore) { + this.attachedStores.push(newStore); + this.setActiveStore(newStore); + if (true) { + if (this.attachedStores.length > 1) { + const dev = this; + (dev.overlapWarningFrame ??= AnimationFrame.create()).request(() => { + if (this.attachedStores.length > 1) { + console.warn("Base UI: A handle is attached to more than one mounted root at the same time. The most recently mounted root takes over and the previous one stops being controlled by the handle. A handle should be used by a single root that stays mounted for the lifetime of the handle."); + } + }); + } + } + return () => { + const index2 = this.attachedStores.lastIndexOf(newStore); + if (index2 !== -1) { + this.attachedStores.splice(index2, 1); + } + this.setActiveStore(this.attachedStores[this.attachedStores.length - 1] ?? null); + }; + } + /** + * Sets the store that currently controls the handle and notifies subscribers when it changes, so + * detached triggers re-render and migrate their registration to the new store. + */ + setActiveStore(store2) { + if (this.attachedStoreValue !== store2) { + this.attachedStoreValue = store2; + this.storeListeners.forEach((listener) => { + listener(); + }); + } + } + /** + * Opens the attached root's store and associates it with the trigger with the given id, or a + * no-op (with a dev warning) while no root is attached. Shared by every concrete handle's public + * `open()` method, which only narrows the parameter type. + * + * When a trigger id is given but no matching trigger is registered, anchored popups throw (see + * `throwOnMissingTrigger`); Dialog opens unassociated with a dev warning instead. + * + * This method should only be called in an event handler or an effect (not during rendering). + * + * @param triggerId ID of the trigger to associate with the popup, or `null`/`undefined` to open + * without associating any trigger. + */ + openByTrigger(triggerId) { + const attachedStore = this.attachedStore; + if (attachedStore === null) { + if (true) { + console.warn(`Base UI: ${this.componentName}Handle.open() was called while no root using this handle is mounted. The call was ignored; mount a root with this handle before opening it imperatively.`); + } + return; + } + let triggerElement; + if (triggerId) { + for (let i = this.attachedStores.length - 1; i >= 0 && !triggerElement; i -= 1) { + triggerElement = this.attachedStores[i].context.triggerElements.getById(triggerId); + } + triggerElement ??= this.fallbackStore.context.triggerElements.getById(triggerId); + } + if (triggerId && !triggerElement) { + if (this.throwOnMissingTrigger) { + throw new Error(true ? `Base UI: ${this.componentName}Handle.open() was called with the trigger id "${triggerId}", but no matching trigger is registered with this handle. An anchored popup cannot open without a trigger to anchor to. Pass the id of a mounted ${this.componentName}.Trigger that has this handle set on its "handle" prop.` : formatErrorMessage_default(99, this.componentName, triggerId, this.componentName)); + } + if (true) { + console.warn(`Base UI: ${this.componentName}Handle.open: No trigger found with id "${triggerId}". The popup will open, but the trigger will not be associated with it.`); + } + } + attachedStore.setOpen(true, createChangeEventDetails(reason_parts_exports.imperativeAction, void 0, triggerElement)); + } + /** + * Closes the popup by setting the attached root's store to closed, or a no-op (with a dev warning) + * while no root is attached. Shared by every concrete handle's public `close()` method. + * + * This method should only be called in an event handler or an effect (not during rendering). + */ + closePopup() { + const attachedStore = this.attachedStore; + if (attachedStore === null) { + if (true) { + console.warn(`Base UI: ${this.componentName}Handle.close() was called while no root using this handle is mounted. The call was ignored.`); + } + return; + } + attachedStore.setOpen(false, createChangeEventDetails(reason_parts_exports.imperativeAction)); + } }; // node_modules/@base-ui/react/utils/popups/popupStoreUtils.mjs -var React28 = __toESM(require_react(), 1); +var React25 = __toESM(require_react(), 1); var ReactDOM4 = __toESM(require_react_dom(), 1); // node_modules/@base-ui/react/floating-ui-react/hooks/useSyncedFloatingRootContext.mjs -var React27 = __toESM(require_react(), 1); - -// node_modules/@base-ui/utils/store/createSelector.mjs -var createSelector = (a, b, c, d, e, f, ...other) => { - if (other.length > 0) { - throw new Error(true ? "Unsupported number of selectors" : formatErrorMessage_default(1)); - } - let selector; - if (a && b && c && d && e && f) { - selector = (state, a1, a2, a3) => { - const va = a(state, a1, a2, a3); - const vb = b(state, a1, a2, a3); - const vc = c(state, a1, a2, a3); - const vd = d(state, a1, a2, a3); - const ve = e(state, a1, a2, a3); - return f(va, vb, vc, vd, ve, a1, a2, a3); - }; - } else if (a && b && c && d && e) { - selector = (state, a1, a2, a3) => { - const va = a(state, a1, a2, a3); - const vb = b(state, a1, a2, a3); - const vc = c(state, a1, a2, a3); - const vd = d(state, a1, a2, a3); - return e(va, vb, vc, vd, a1, a2, a3); - }; - } else if (a && b && c && d) { - selector = (state, a1, a2, a3) => { - const va = a(state, a1, a2, a3); - const vb = b(state, a1, a2, a3); - const vc = c(state, a1, a2, a3); - return d(va, vb, vc, a1, a2, a3); - }; - } else if (a && b && c) { - selector = (state, a1, a2, a3) => { - const va = a(state, a1, a2, a3); - const vb = b(state, a1, a2, a3); - return c(va, vb, a1, a2, a3); - }; - } else if (a && b) { - selector = (state, a1, a2, a3) => { - const va = a(state, a1, a2, a3); - return b(va, a1, a2, a3); - }; - } else if (a) { - selector = a; - } else { - throw ( - /* minify-error-disabled */ - new Error("Missing arguments") - ); - } - return selector; -}; +var React24 = __toESM(require_react(), 1); // node_modules/@base-ui/utils/store/useStore.mjs -var React25 = __toESM(require_react(), 1); +var React22 = __toESM(require_react(), 1); var import_shim = __toESM(require_shim(), 1); var import_with_selector = __toESM(require_with_selector(), 1); // node_modules/@base-ui/utils/fastHooks.mjs -var React24 = __toESM(require_react(), 1); +var React21 = __toESM(require_react(), 1); var hooks = []; var currentInstance = void 0; function getInstance() { @@ -4841,7 +4869,7 @@ function fastComponent(fn) { return FastComponent; } function fastComponentRef(fn) { - return /* @__PURE__ */ React24.forwardRef(fastComponent(fn)); + return /* @__PURE__ */ React21.forwardRef(fastComponent(fn)); } function createInstance() { return { @@ -4856,7 +4884,7 @@ function useStore(store2, selector, a1, a2, a3) { return useStoreImplementation(store2, selector, a1, a2, a3); } function useStoreR19(store2, selector, a1, a2, a3) { - const getSelection = React25.useCallback(() => selector(store2.getSnapshot(), a1, a2, a3), [store2, selector, a1, a2, a3]); + const getSelection = React22.useCallback(() => selector(store2.getSnapshot(), a1, a2, a3), [store2, selector, a1, a2, a3]); return (0, import_shim.useSyncExternalStore)(store2.subscribe, getSelection, getSelection); } register({ @@ -5043,7 +5071,7 @@ var Store = class { }; // node_modules/@base-ui/utils/store/ReactStore.mjs -var React26 = __toESM(require_react(), 1); +var React23 = __toESM(require_react(), 1); var ReactStore = class extends Store { /** * Creates a new ReactStore instance. @@ -5067,7 +5095,7 @@ var ReactStore = class extends Store { * by `useState` is updated before the next render (similarly to React's `useState`). */ useSyncedValue(key, value) { - React26.useDebugValue(key); + React23.useDebugValue(key); const store2 = this; useIsoLayoutEffect(() => { if (store2.state[key] !== value) { @@ -5102,8 +5130,8 @@ var ReactStore = class extends Store { useSyncedValues(statePart) { const store2 = this; if (true) { - React26.useDebugValue(statePart, (p) => Object.keys(p)); - const keys = React26.useRef(Object.keys(statePart)).current; + React23.useDebugValue(statePart, (p) => Object.keys(p)); + const keys = React23.useRef(Object.keys(statePart)).current; const nextKeys = Object.keys(statePart); if (keys.length !== nextKeys.length || keys.some((key, index2) => key !== nextKeys[index2])) { console.error("ReactStore.useSyncedValues expects the same prop keys on every render. Keys should be stable."); @@ -5119,7 +5147,7 @@ var ReactStore = class extends Store { * is non-undefined, the store's state at `key` is updated to match `controlled`. */ useControlledProp(key, controlled) { - React26.useDebugValue(key); + React23.useDebugValue(key); const store2 = this; const isControlled = controlled !== void 0; useIsoLayoutEffect(() => { @@ -5157,7 +5185,7 @@ var ReactStore = class extends Store { * @param key Key of the selector to use. */ useState(key, a1, a2, a3) { - React26.useDebugValue(key); + React23.useDebugValue(key); return useStore(this, this.selectors[key], a1, a2, a3); } /** @@ -5168,7 +5196,7 @@ var ReactStore = class extends Store { * @param fn Function to assign. */ useContextCallback(key, fn) { - React26.useDebugValue(key); + React23.useDebugValue(key); const stableFunction = useStableCallback(fn ?? NOOP); this.context[key] = stableFunction; } @@ -5179,7 +5207,7 @@ var ReactStore = class extends Store { * @param key Key of the state to set. */ useStateSetter(key) { - const ref = React26.useRef(void 0); + const ref = React23.useRef(void 0); if (ref.current === void 0) { ref.current = (value) => { this.set(key, value); @@ -5215,12 +5243,12 @@ var ReactStore = class extends Store { // node_modules/@base-ui/react/floating-ui-react/components/FloatingRootStore.mjs var selectors = { - open: createSelector((state) => state.open), - transitionStatus: createSelector((state) => state.transitionStatus), - domReferenceElement: createSelector((state) => state.domReferenceElement), - referenceElement: createSelector((state) => state.positionReference ?? state.referenceElement), - floatingElement: createSelector((state) => state.floatingElement), - floatingId: createSelector((state) => state.floatingId) + open: (state) => state.open, + transitionStatus: (state) => state.transitionStatus, + domReferenceElement: (state) => state.domReferenceElement, + referenceElement: (state) => state.positionReference ?? state.referenceElement, + floatingElement: (state) => state.floatingElement, + floatingId: (state) => state.floatingId }; var FloatingRootStore = class extends ReactStore { constructor(options) { @@ -5301,7 +5329,7 @@ function useSyncedFloatingRootContext(options) { const floatingElement = popupStore.useState(treatPopupAsFloatingElement ? "popupElement" : "positionerElement"); const triggerElements = popupStore.context.triggerElements; const handleOpenChange = onOpenChange; - const internalStoreRef = React27.useRef(null); + const internalStoreRef = React24.useRef(null); if (floatingRootContextProp === void 0 && internalStoreRef.current === null) { internalStoreRef.current = new FloatingRootStore({ open, @@ -5342,14 +5370,10 @@ var FOCUSABLE_POPUP_PROPS = { tabIndex: -1, [FOCUSABLE_ATTRIBUTE]: "" }; -function usePopupStore(externalStore, createStore, treatPopupAsFloatingElement = false) { +function usePopupRootStore(createStore, treatPopupAsFloatingElement = false) { const floatingId = useId(); const nested = useFloatingParentNodeId() != null; - const internalStoreRef = React28.useRef(null); - if (externalStore === void 0 && internalStoreRef.current === null) { - internalStoreRef.current = createStore(floatingId, nested); - } - const store2 = externalStore ?? internalStoreRef.current; + const store2 = useRefWithInit(() => createStore(floatingId, nested)).current; useSyncedFloatingRootContext({ popupStore: store2, treatPopupAsFloatingElement, @@ -5358,15 +5382,21 @@ function usePopupStore(externalStore, createStore, treatPopupAsFloatingElement = nested, onOpenChange: store2.setOpen }); - return { - store: store2, - internalStore: internalStoreRef.current - }; + return store2; +} +function PopupHandleAttachment({ + handle, + store: store2 +}) { + useIsoLayoutEffect(() => { + return handle.attachStore(store2); + }, [handle, store2]); + return null; } function useTriggerRegistration(id, store2) { - const registeredElementIdRef = React28.useRef(null); - const registeredElementRef = React28.useRef(null); - return React28.useCallback((element) => { + const registeredElementIdRef = React25.useRef(null); + const registeredElementRef = React25.useRef(null); + return React25.useCallback((element) => { if (id === void 0) { return; } @@ -5448,26 +5478,10 @@ function applyPopupOpenChange(store2, nextOpen, eventDetails, options = {}) { changeState(); } } -function useInitialOpenSync(store2, openProp, defaultOpen, defaultTriggerId) { - useOnFirstRender(() => { - if (openProp === void 0 && store2.state.open === false && defaultOpen) { - store2.state = { - ...store2.state, - open: true, - activeTriggerId: defaultTriggerId, - preventUnmountingOnClose: false - }; - } - }); -} function useTriggerDataForwarding(triggerId, triggerElementRef, store2, stateUpdates) { const isMountedByThisTrigger = store2.useState("isMountedByTrigger", triggerId); const baseRegisterTrigger = useTriggerRegistration(triggerId, store2); - const registerTrigger = useStableCallback((element) => { - baseRegisterTrigger(element); - if (!element) { - return; - } + const applyTriggerData = useStableCallback((element) => { const open = store2.select("open"); const activeTriggerId = store2.select("activeTriggerId"); if (activeTriggerId === triggerId) { @@ -5485,6 +5499,12 @@ function useTriggerDataForwarding(triggerId, triggerElementRef, store2, stateUpd }); } }); + const registerTrigger = React25.useCallback((element) => { + baseRegisterTrigger(element); + if (element) { + applyTriggerData(element); + } + }, [baseRegisterTrigger, applyTriggerData]); useIsoLayoutEffect(() => { if (isMountedByThisTrigger) { store2.update({ @@ -5502,10 +5522,14 @@ function useImplicitActiveTrigger(store2, options = {}) { const { closeOnActiveTriggerUnmount = false } = options; + const resolvedActiveTriggerIdRef = React25.useRef(null); const open = store2.useState("open"); const reactiveTriggerCount = store2.useState("triggerCount"); + const activeTriggerId = store2.useState("activeTriggerId"); + const reactiveActiveTriggerElement = store2.useState("activeTriggerElement"); useIsoLayoutEffect(() => { if (!open) { + resolvedActiveTriggerIdRef.current = null; if (store2.state.triggerCount !== 0) { store2.set("triggerCount", 0); } @@ -5516,22 +5540,42 @@ function useImplicitActiveTrigger(store2, options = {}) { if (store2.state.triggerCount !== triggerCount) { stateUpdates.triggerCount = triggerCount; } - const activeTriggerId = store2.select("activeTriggerId"); + const currentActiveTriggerId = store2.select("activeTriggerId"); let lostActiveTriggerId = null; - if (activeTriggerId) { - const activeTriggerElement = store2.context.triggerElements.getById(activeTriggerId); + if (currentActiveTriggerId) { + const activeTriggerElement = store2.context.triggerElements.getById(currentActiveTriggerId); if (!activeTriggerElement) { - lostActiveTriggerId = activeTriggerId; - } else if (activeTriggerElement !== store2.state.activeTriggerElement) { - stateUpdates.activeTriggerElement = activeTriggerElement; - } - } - if (!lostActiveTriggerId && !activeTriggerId && triggerCount === 1) { - const iteratorResult = store2.context.triggerElements.entries().next(); - if (!iteratorResult.done) { + for (const [triggerId, triggerElement] of store2.context.triggerElements.entries()) { + if (triggerElement === store2.state.activeTriggerElement) { + stateUpdates.activeTriggerId = triggerId; + stateUpdates.activeTriggerElement = triggerElement; + resolvedActiveTriggerIdRef.current = triggerId; + break; + } + } + if (stateUpdates.activeTriggerId === void 0) { + if (resolvedActiveTriggerIdRef.current === currentActiveTriggerId) { + lostActiveTriggerId = currentActiveTriggerId; + } else { + resolvedActiveTriggerIdRef.current = null; + } + } + } else { + resolvedActiveTriggerIdRef.current = currentActiveTriggerId; + if (activeTriggerElement !== store2.state.activeTriggerElement) { + stateUpdates.activeTriggerElement = activeTriggerElement; + } + } + } else { + resolvedActiveTriggerIdRef.current = null; + } + if (!lostActiveTriggerId && !currentActiveTriggerId && triggerCount === 1) { + const iteratorResult = store2.context.triggerElements.entries().next(); + if (!iteratorResult.done) { const [implicitTriggerId, implicitTriggerElement] = iteratorResult.value; stateUpdates.activeTriggerId = implicitTriggerId; stateUpdates.activeTriggerElement = implicitTriggerElement; + resolvedActiveTriggerIdRef.current = implicitTriggerId; } } if (stateUpdates.triggerCount !== void 0 || stateUpdates.activeTriggerId !== void 0 || stateUpdates.activeTriggerElement !== void 0) { @@ -5553,7 +5597,7 @@ function useImplicitActiveTrigger(store2, options = {}) { }); } } - }, [open, store2, reactiveTriggerCount, closeOnActiveTriggerUnmount]); + }, [open, store2, reactiveTriggerCount, activeTriggerId, reactiveActiveTriggerElement, closeOnActiveTriggerUnmount]); } function useOpenStateTransitions(open, store2, onUnmount) { const { @@ -5606,9 +5650,18 @@ function usePopupInteractionProps(store2, statePart) { } // node_modules/@base-ui/react/utils/popups/popupTriggerMap.mjs +var devElementIdsByMap; +function getDevElementIds(map) { + devElementIdsByMap ??= /* @__PURE__ */ new WeakMap(); + let elementIds = devElementIdsByMap.get(map); + if (!elementIds) { + elementIds = /* @__PURE__ */ new WeakMap(); + devElementIdsByMap.set(map, elementIds); + } + return elementIds; +} var PopupTriggerMap = class { constructor() { - this.elementsSet = /* @__PURE__ */ new Set(); this.idMap = /* @__PURE__ */ new Map(); } /** @@ -5617,42 +5670,48 @@ var PopupTriggerMap = class { * Note: The provided element is assumed to not be registered under multiple IDs. */ add(id, element) { - const existingElement = this.idMap.get(id); - if (existingElement === element) { - return; - } - if (existingElement !== void 0) { - this.elementsSet.delete(existingElement); - } - this.elementsSet.add(element); - this.idMap.set(id, element); if (true) { - if (this.elementsSet.size !== this.idMap.size) { + const elementIds = getDevElementIds(this); + const existingId = elementIds.get(element); + if (existingId !== void 0 && existingId !== id) { throw new Error("Base UI: A trigger element cannot be registered under multiple IDs in PopupTriggerMap."); } + const previousElement = this.idMap.get(id); + if (previousElement !== void 0 && previousElement !== element) { + elementIds.delete(previousElement); + } + elementIds.set(element, id); } + this.idMap.set(id, element); } /** * Removes the trigger element with the given ID. */ delete(id) { - const element = this.idMap.get(id); - if (element) { - this.elementsSet.delete(element); - this.idMap.delete(id); + if (true) { + const element = this.idMap.get(id); + if (element !== void 0) { + devElementIdsByMap?.get(this)?.delete(element); + } } + this.idMap.delete(id); } /** * Whether the given element is registered as a trigger. */ hasElement(element) { - return this.elementsSet.has(element); + for (const registered of this.idMap.values()) { + if (registered === element) { + return true; + } + } + return false; } /** * Whether there is a registered trigger element matching the given predicate. */ hasMatchingElement(predicate) { - for (const element of this.elementsSet) { + for (const element of this.idMap.values()) { if (predicate(element)) { return true; } @@ -5675,7 +5734,7 @@ var PopupTriggerMap = class { * Returns an iterable of all registered trigger elements. */ elements() { - return this.elementsSet.values(); + return this.idMap.values(); } /** * Returns the number of registered trigger elements. @@ -5735,12 +5794,12 @@ function createPopupFloatingRootContext(triggerElements, floatingId, nested = fa onOpenChange: void 0 }); } -var activeTriggerIdSelector = createSelector((state) => state.triggerIdProp ?? state.activeTriggerId); -var openSelector = createSelector((state) => state.openProp ?? state.open); -var popupIdSelector = createSelector((state) => { +var activeTriggerIdSelector = (state) => state.triggerIdProp ?? state.activeTriggerId; +var openSelector = (state) => state.openProp ?? state.open; +var popupIdSelector = (state) => { const popupId = state.popupElement?.id ?? state.floatingId; return popupId || void 0; -}); +}; function triggerOwnsOpenPopup(state, triggerId) { return triggerId !== void 0 && openSelector(state) && activeTriggerIdSelector(state) === triggerId; } @@ -5752,101 +5811,73 @@ function triggerOwnsOpenPopupOrIsOnlyTrigger(state, triggerId) { } var popupStoreSelectors = { open: openSelector, - mounted: createSelector((state) => state.mounted), - transitionStatus: createSelector((state) => state.transitionStatus), - floatingRootContext: createSelector((state) => state.floatingRootContext), - triggerCount: createSelector((state) => state.triggerCount), - preventUnmountingOnClose: createSelector((state) => state.preventUnmountingOnClose), - payload: createSelector((state) => state.payload), + mounted: (state) => state.mounted, + transitionStatus: (state) => state.transitionStatus, + floatingRootContext: (state) => state.floatingRootContext, + triggerCount: (state) => state.triggerCount, + preventUnmountingOnClose: (state) => state.preventUnmountingOnClose, + payload: (state) => state.payload, activeTriggerId: activeTriggerIdSelector, - activeTriggerElement: createSelector((state) => state.mounted ? state.activeTriggerElement : null), + activeTriggerElement: (state) => state.mounted ? state.activeTriggerElement : null, popupId: popupIdSelector, /** * Whether the trigger with the given ID was used to open the popup. */ - isTriggerActive: createSelector((state, triggerId) => triggerId !== void 0 && activeTriggerIdSelector(state) === triggerId), + isTriggerActive: (state, triggerId) => triggerId !== void 0 && activeTriggerIdSelector(state) === triggerId, /** * Whether the popup is open and was activated by a trigger with the given ID. */ - isOpenedByTrigger: createSelector((state, triggerId) => triggerOwnsOpenPopup(state, triggerId)), + isOpenedByTrigger: (state, triggerId) => triggerOwnsOpenPopup(state, triggerId), /** * Whether the popup is mounted and was activated by a trigger with the given ID. */ - isMountedByTrigger: createSelector((state, triggerId) => triggerId !== void 0 && activeTriggerIdSelector(state) === triggerId && state.mounted), - triggerProps: createSelector((state, isActive) => isActive ? state.activeTriggerProps : state.inactiveTriggerProps), + isMountedByTrigger: (state, triggerId) => triggerId !== void 0 && activeTriggerIdSelector(state) === triggerId && state.mounted, + triggerProps: (state, isActive) => isActive ? state.activeTriggerProps : state.inactiveTriggerProps, /** * Popup id for the trigger that currently owns the open popup. */ - triggerPopupId: createSelector((state, triggerId) => triggerOwnsOpenPopupOrIsOnlyTrigger(state, triggerId) ? popupIdSelector(state) : void 0), - popupProps: createSelector((state) => state.popupProps), - popupElement: createSelector((state) => state.popupElement), - positionerElement: createSelector((state) => state.positionerElement) + triggerPopupId: (state, triggerId) => triggerOwnsOpenPopupOrIsOnlyTrigger(state, triggerId) ? popupIdSelector(state) : void 0, + popupProps: (state) => state.popupProps, + popupElement: (state) => state.popupElement, + positionerElement: (state) => state.positionerElement }; -// node_modules/@base-ui/react/floating-ui-react/hooks/useFloatingRootContext.mjs -function useFloatingRootContext(options) { - const { - open = false, - onOpenChange, - elements = {} - } = options; - const floatingId = useId(); - const nested = useFloatingParentNodeId() != null; - if (true) { - const optionDomReference = elements.reference; - if (optionDomReference && !isElement(optionDomReference)) { - console.error("Cannot pass a virtual element to the `elements.reference` option,", "as it must be a real DOM element. Use `context.setPositionReference()`", "instead."); - } - } - const store2 = useRefWithInit(() => new FloatingRootStore({ - open, - transitionStatus: void 0, - onOpenChange, - referenceElement: elements.reference ?? null, - floatingElement: elements.floating ?? null, - triggerElements: new PopupTriggerMap(), - floatingId, - syncOnly: false, - nested - })).current; - useIsoLayoutEffect(() => { - const valuesToSync = { - open, - floatingId - }; - if (elements.reference !== void 0) { - valuesToSync.referenceElement = elements.reference; - valuesToSync.domReferenceElement = isElement(elements.reference) ? elements.reference : null; - } - if (elements.floating !== void 0) { - valuesToSync.floatingElement = elements.floating; +// node_modules/@base-ui/react/utils/popups/usePopupHandleStore.mjs +var React26 = __toESM(require_react(), 1); +var import_shim2 = __toESM(require_shim(), 1); +function usePopupHandleStore(handle) { + const subscribe = React26.useCallback((listener) => { + if (handle === void 0) { + return NOOP; } - store2.update(valuesToSync); - }, [open, floatingId, elements.reference, elements.floating, store2]); - store2.context.onOpenChange = onOpenChange; - store2.context.nested = nested; - return store2; + return handle.subscribeStore(listener); + }, [handle]); + const getSnapshot = React26.useCallback(() => { + return handle === void 0 ? void 0 : handle.store; + }, [handle]); + return (0, import_shim2.useSyncExternalStore)(subscribe, getSnapshot, () => handle?.serverStore); } // node_modules/@base-ui/react/floating-ui-react/hooks/useFloating.mjs -function useFloating2(options = {}) { +function useBaseUIFloating(options) { + return useFloatingWithStore(options, options.rootContext); +} +function useFloatingWithStore(options, store2) { const { nodeId, externalTree } = options; - const internalStore = useFloatingRootContext(options); - const store2 = options.rootContext || internalStore; const referenceElement = store2.useState("referenceElement"); const floatingElement = store2.useState("floatingElement"); const domReferenceElement = store2.useState("domReferenceElement"); const open = store2.useState("open"); const floatingId = store2.useState("floatingId"); - const [positionReference, setPositionReferenceRaw] = React29.useState(null); - const [localDomReference, setLocalDomReference] = React29.useState(void 0); - const [localFloatingElement, setLocalFloatingElement] = React29.useState(void 0); - const domReferenceRef = React29.useRef(null); + const [positionReference, setPositionReferenceRaw] = React27.useState(null); + const [localDomReference, setLocalDomReference] = React27.useState(void 0); + const [localFloatingElement, setLocalFloatingElement] = React27.useState(void 0); + const domReferenceRef = React27.useRef(null); const tree = useFloatingTree(externalTree); - const storeElements = React29.useMemo(() => ({ + const storeElements = React27.useMemo(() => ({ reference: referenceElement, floating: floatingElement, domReference: domReferenceElement @@ -5865,7 +5896,7 @@ function useFloating2(options = {}) { store2.useSyncedValue("referenceElement", localDomReference ?? null); store2.useSyncedValue("domReferenceElement", localDomReference === void 0 ? domReferenceElement : localDomReferenceElement); store2.useSyncedValue("floatingElement", syncedFloatingElement); - const setPositionReference = React29.useCallback((node) => { + const setPositionReference = React27.useCallback((node) => { const computedPositionReference = isElement(node) ? { getBoundingClientRect: () => node.getBoundingClientRect(), getClientRects: () => node.getClientRects(), @@ -5874,7 +5905,7 @@ function useFloating2(options = {}) { setPositionReferenceRaw(computedPositionReference); position.refs.setReference(computedPositionReference); }, [position.refs]); - const setReference = React29.useCallback((node) => { + const setReference = React27.useCallback((node) => { if (isElement(node) || node === null) { domReferenceRef.current = node; setLocalDomReference(node); @@ -5886,22 +5917,22 @@ function useFloating2(options = {}) { position.refs.setReference(node); } }, [position.refs, setLocalDomReference]); - const setFloating = React29.useCallback((node) => { + const setFloating = React27.useCallback((node) => { setLocalFloatingElement(node); position.refs.setFloating(node); }, [position.refs]); - const refs = React29.useMemo(() => ({ + const refs = React27.useMemo(() => ({ ...position.refs, setReference, setFloating, setPositionReference, domReference: domReferenceRef }), [position.refs, setReference, setFloating, setPositionReference]); - const elements = React29.useMemo(() => ({ + const elements = React27.useMemo(() => ({ ...position.elements, domReference: domReferenceElement }), [position.elements, domReferenceElement]); - const context = React29.useMemo(() => ({ + const context = React27.useMemo(() => ({ ...position, dataRef: store2.context.dataRef, open, @@ -5925,7 +5956,7 @@ function useFloating2(options = {}) { node.context = context; } }); - return React29.useMemo(() => ({ + return React27.useMemo(() => ({ ...position, context, refs, @@ -5935,7 +5966,7 @@ function useFloating2(options = {}) { } // node_modules/@base-ui/react/floating-ui-react/hooks/useFocus.mjs -var React30 = __toESM(require_react(), 1); +var React28 = __toESM(require_react(), 1); var isMacSafari = parts_exports.os.mac && parts_exports.engine.webkit; function useFocus(context, props = {}) { const { @@ -5947,11 +5978,11 @@ function useFocus(context, props = {}) { events, dataRef } = store2.context; - const blockFocusRef = React30.useRef(false); - const blockedReferenceRef = React30.useRef(null); - const keyboardModalityRef = React30.useRef(true); + const blockFocusRef = React28.useRef(false); + const blockedReferenceRef = React28.useRef(null); + const keyboardModalityRef = React28.useRef(true); const timeout = useTimeout(); - React30.useEffect(() => { + React28.useEffect(() => { const domReference = store2.select("domReferenceElement"); if (!enabled) { return void 0; @@ -5971,7 +6002,7 @@ function useFocus(context, props = {}) { } return mergeCleanups(addEventListener(win, "blur", onBlur), isMacSafari && addEventListener(win, "keydown", onKeyDown, true), isMacSafari && addEventListener(win, "pointerdown", onPointerDown, true)); }, [store2, enabled]); - React30.useEffect(() => { + React28.useEffect(() => { if (!enabled) { return void 0; } @@ -5989,7 +6020,7 @@ function useFocus(context, props = {}) { events.off("openchange", onOpenChangeLocal); }; }, [events, enabled, store2]); - const reference = React30.useMemo(() => { + const reference = React28.useMemo(() => { function resetBlockedFocus() { blockFocusRef.current = false; blockedReferenceRef.current = null; @@ -6056,14 +6087,14 @@ function useFocus(context, props = {}) { } }; }, [dataRef, delay, store2, timeout]); - return React30.useMemo(() => enabled ? { + return React28.useMemo(() => enabled ? { reference, trigger: reference } : {}, [enabled, reference]); } // node_modules/@base-ui/react/floating-ui-react/hooks/useHoverFloatingInteraction.mjs -var React31 = __toESM(require_react(), 1); +var React29 = __toESM(require_react(), 1); // node_modules/@base-ui/react/floating-ui-react/hooks/useHoverInteractionSharedState.mjs var HoverInteraction = class _HoverInteraction { @@ -6174,7 +6205,7 @@ function useHoverFloatingInteraction(context, parameters = {}) { clearPointerEvents(); } }, [open, instance, clearPointerEvents]); - React31.useEffect(() => { + React29.useEffect(() => { return clearPointerEvents; }, [clearPointerEvents]); useIsoLayoutEffect(() => { @@ -6203,7 +6234,7 @@ function useHoverFloatingInteraction(context, parameters = {}) { } return void 0; }, [enabled, open, domReferenceElement, floatingElement, instance, isHoverOpen, tree, parentId, clearPointerEvents]); - React31.useEffect(() => { + React29.useEffect(() => { if (!enabled) { return void 0; } @@ -6278,7 +6309,7 @@ function useHoverFloatingInteraction(context, parameters = {}) { } // node_modules/@base-ui/react/floating-ui-react/hooks/useHoverReferenceInteraction.mjs -var React32 = __toESM(require_react(), 1); +var React30 = __toESM(require_react(), 1); var ReactDOM5 = __toESM(require_react_dom(), 1); var EMPTY_REF = { current: null @@ -6296,7 +6327,8 @@ function useHoverReferenceInteraction(context, props = {}) { isActiveTrigger = true, getHandleCloseContext, isClosing, - shouldOpen: shouldOpenProp + shouldOpen: shouldOpenProp, + guardStaleOpen = false } = props; const store2 = "rootStore" in context ? context.rootStore : context; const { @@ -6305,7 +6337,7 @@ function useHoverReferenceInteraction(context, props = {}) { } = store2.context; const tree = useFloatingTree(externalTree); const instance = useHoverInteractionSharedState(store2); - const isHoverCloseActiveRef = React32.useRef(false); + const isHoverCloseActiveRef = React30.useRef(false); const handleCloseRef = useValueAsRef(handleClose); const delayRef = useValueAsRef(delay); const restMsRef = useValueAsRef(restMs); @@ -6343,8 +6375,8 @@ function useHoverReferenceInteraction(context, props = {}) { if (isActiveTrigger) { instance.handleCloseOptions = handleCloseRef.current?.__options; } - React32.useEffect(() => cleanupMouseMoveHandler, [cleanupMouseMoveHandler]); - React32.useEffect(() => { + React30.useEffect(() => cleanupMouseMoveHandler, [cleanupMouseMoveHandler]); + React30.useEffect(() => { if (!enabled) { return void 0; } @@ -6365,7 +6397,7 @@ function useHoverReferenceInteraction(context, props = {}) { events.off("openchange", onOpenChangeLocal); }; }, [enabled, events, instance, cleanupMouseMoveHandler]); - React32.useEffect(() => { + React30.useEffect(() => { if (!enabled) { return void 0; } @@ -6479,14 +6511,23 @@ function useHoverReferenceInteraction(context, props = {}) { closeWithDelay(event); } } + function onMouseOut(event) { + if (contains(trigger, event.relatedTarget)) { + return; + } + instance.openChangeTimeout.clear(); + instance.restTimeout.clear(); + instance.restTimeoutPending = false; + } + const staleOpenGuard = guardStaleOpen ? addEventListener(trigger, "mouseout", onMouseOut) : void 0; if (move) { return mergeCleanups(addEventListener(trigger, "mousemove", onMouseEnter, { once: true - }), addEventListener(trigger, "mouseenter", onMouseEnter), addEventListener(trigger, "mouseleave", onMouseLeave)); + }), addEventListener(trigger, "mouseenter", onMouseEnter), addEventListener(trigger, "mouseleave", onMouseLeave), staleOpenGuard); } - return mergeCleanups(addEventListener(trigger, "mouseenter", onMouseEnter), addEventListener(trigger, "mouseleave", onMouseLeave)); - }, [cleanupMouseMoveHandler, clearPointerEvents, dataRef, delayRef, store2, enabled, handleCloseRef, instance, isActiveTrigger, isOverInactiveTrigger, isClickLikeOpenEvent2, mouseOnly, move, restMsRef, triggerElementRef, tree, enabledRef, getHandleCloseContext, isClosingRef, checkShouldOpen]); - return React32.useMemo(() => { + return mergeCleanups(addEventListener(trigger, "mouseenter", onMouseEnter), addEventListener(trigger, "mouseleave", onMouseLeave), staleOpenGuard); + }, [cleanupMouseMoveHandler, clearPointerEvents, dataRef, delayRef, store2, enabled, handleCloseRef, instance, isActiveTrigger, isOverInactiveTrigger, isClickLikeOpenEvent2, mouseOnly, move, restMsRef, triggerElementRef, tree, enabledRef, getHandleCloseContext, isClosingRef, checkShouldOpen, guardStaleOpen]); + return React30.useMemo(() => { if (!enabled) { return void 0; } @@ -6767,6 +6808,21 @@ function safePolygon(options = {}) { return fn; } +// node_modules/@base-ui/react/utils/NullStore.mjs +var NullStore = class extends ReactStore { + // `update`/`set`/`notifyAll` funnel through `setState` in the base `Store`, so overriding + // `setState` alone would neutralize them today. They are overridden explicitly so the store stays + // inert even if a future base-class change stops routing a mutator through `setState`. + setState(_newState) { + } + update(_changes) { + } + set(_key, _value) { + } + notifyAll() { + } +}; + // node_modules/@base-ui/react/utils/popupStateMapping.mjs var CommonPopupDataAttributes = (function(CommonPopupDataAttributes2) { CommonPopupDataAttributes2["open"] = "data-open"; @@ -6778,26 +6834,17 @@ var CommonPopupDataAttributes = (function(CommonPopupDataAttributes2) { CommonPopupDataAttributes2["align"] = "data-align"; return CommonPopupDataAttributes2; })({}); -var CommonTriggerDataAttributes = /* @__PURE__ */ (function(CommonTriggerDataAttributes2) { - CommonTriggerDataAttributes2["popupOpen"] = "data-popup-open"; - CommonTriggerDataAttributes2["pressed"] = "data-pressed"; - return CommonTriggerDataAttributes2; -})({}); var TRIGGER_HOOK = { - [CommonTriggerDataAttributes.popupOpen]: "" -}; -var PRESSABLE_TRIGGER_HOOK = { - [CommonTriggerDataAttributes.popupOpen]: "", - [CommonTriggerDataAttributes.pressed]: "" + "data-popup-open": "" }; var POPUP_OPEN_HOOK = { - [CommonPopupDataAttributes.open]: "" + "data-open": "" }; var POPUP_CLOSED_HOOK = { - [CommonPopupDataAttributes.closed]: "" + "data-closed": "" }; var ANCHOR_HIDDEN_HOOK = { - [CommonPopupDataAttributes.anchorHidden]: "" + "data-anchor-hidden": "" }; var triggerOpenStateMapping = { open(value) { @@ -6821,6 +6868,10 @@ var popupStateMapping = { return null; } }; +var popupTransitionStateMapping = { + ...popupStateMapping, + ...transitionStatusMapping +}; // node_modules/@base-ui/utils/inertValue.mjs function inertValue(value) { @@ -6830,8 +6881,17 @@ function inertValue(value) { return value ? "true" : void 0; } -// node_modules/@base-ui/react/utils/useAnchorPositioning.mjs -var React33 = __toESM(require_react(), 1); +// node_modules/@base-ui/react/internals/direction-context/DirectionContext.mjs +var React31 = __toESM(require_react(), 1); +var DirectionContext = /* @__PURE__ */ React31.createContext(void 0); +if (true) DirectionContext.displayName = "DirectionContext"; +function useDirection() { + const context = React31.useContext(DirectionContext); + return context?.direction ?? "ltr"; +} + +// node_modules/@base-ui/react/internals/useAnchorPositioning.mjs +var React32 = __toESM(require_react(), 1); // node_modules/@base-ui/react/floating-ui-react/middleware/arrow.mjs var baseArrow = (options) => ({ @@ -6903,7 +6963,6 @@ var arrow4 = (options, deps) => ({ }); // node_modules/@base-ui/react/utils/hideMiddleware.mjs -var nativeHideFn = hide3().fn; var hide4 = { name: "hide", async fn(state) { @@ -6914,88 +6973,27 @@ var hide4 = { y } = state.rects.reference; const anchorHidden = width === 0 && height === 0 && x === 0 && y === 0; - const nativeHideResult = await nativeHideFn(state); + const overflow = await state.platform.detectOverflow(state, { + elementContext: "reference" + }); + const referenceHidden = overflow.top - height >= 0 || overflow.right - width >= 0 || overflow.bottom - height >= 0 || overflow.left - width >= 0; return { data: { - referenceHidden: nativeHideResult.data?.referenceHidden || anchorHidden + referenceHidden: referenceHidden || anchorHidden } }; } }; -// node_modules/@base-ui/react/utils/adaptiveOriginMiddleware.mjs +// node_modules/@base-ui/react/utils/adaptiveOriginConstants.mjs var DEFAULT_SIDES = { sideX: "left", sideY: "top" }; -var adaptiveOrigin = { - name: "adaptiveOrigin", - async fn(state) { - const { - x: rawX, - y: rawY, - rects: { - floating: floatRect - }, - elements: { - floating - }, - platform: platform3, - strategy, - placement - } = state; - const win = getWindow(floating); - const styles = win.getComputedStyle(floating); - const hasTransition = styles.transitionDuration !== "0s" && styles.transitionDuration !== ""; - if (!hasTransition) { - return { - x: rawX, - y: rawY, - data: DEFAULT_SIDES - }; - } - const offsetParent = await platform3.getOffsetParent?.(floating); - let offsetDimensions = { - width: 0, - height: 0 - }; - if (strategy === "fixed" && win?.visualViewport) { - offsetDimensions = { - width: win.visualViewport.width, - height: win.visualViewport.height - }; - } else if (offsetParent === win) { - const doc = ownerDocument(floating); - offsetDimensions = { - width: doc.documentElement.clientWidth, - height: doc.documentElement.clientHeight - }; - } else if (await platform3.isElement?.(offsetParent)) { - offsetDimensions = await platform3.getDimensions(offsetParent); - } - const currentSide = getSide(placement); - let x = rawX; - let y = rawY; - if (currentSide === "left") { - x = offsetDimensions.width - (rawX + floatRect.width); - } - if (currentSide === "top") { - y = offsetDimensions.height - (rawY + floatRect.height); - } - const sideX = currentSide === "left" ? "right" : DEFAULT_SIDES.sideX; - const sideY = currentSide === "top" ? "bottom" : DEFAULT_SIDES.sideY; - return { - x, - y, - data: { - sideX, - sideY - } - }; - } -}; -// node_modules/@base-ui/react/utils/useAnchorPositioning.mjs +// node_modules/@base-ui/react/internals/useAnchorPositioning.mjs +var AVAILABLE_WIDTH_VAR = "--available-width"; +var AVAILABLE_HEIGHT_VAR = "--available-height"; function getLogicalSide(sideParam, renderedSide, isRtl) { const isLogicalSideParam = sideParam === "inline-start" || sideParam === "inline-end"; const logicalRight = isRtl ? "inline-start" : "inline-end"; @@ -7027,6 +7025,9 @@ function getOffsetData(state, sideParam, isRtl) { return data; } function useAnchorPositioning(params) { + return useAnchorPositioningWithHook(params, useBaseUIFloating); +} +function useAnchorPositioningWithHook(params, useFloatingHook) { const { // Public parameters anchor, @@ -7046,19 +7047,21 @@ function useAnchorPositioning(params) { floatingRootContext, mounted, collisionAvoidance, - shiftCrossAxis = false, + shift: shift4, nodeId, adaptiveOrigin: adaptiveOrigin2, lazyFlip = false, externalTree } = params; - const [mountSide, setMountSide] = React33.useState(null); + const [mountSide, setMountSide] = React32.useState(null); if (!mounted && mountSide !== null) { setMountSide(null); } const collisionAvoidanceSide = collisionAvoidance.side || "flip"; const collisionAvoidanceAlign = collisionAvoidance.align || "flip"; const collisionAvoidanceFallbackAxisSide = collisionAvoidance.fallbackAxisSide || "end"; + const shiftCrossAxis = shift4?.crossAxis ?? false; + const shiftRootBoundary = shift4?.rootBoundary; const anchorFn = typeof anchor === "function" ? anchor : void 0; const anchorFnCallback = useStableCallback(anchorFn); const anchorDep = anchorFn ? anchorFnCallback : anchor; @@ -7076,31 +7079,31 @@ function useAnchorPositioning(params) { }[sideParam]; const placement = align === "center" ? side : `${side}-${align}`; let collisionPadding = collisionPaddingParam; - const bias = 1; - const biasTop = sideParam === "bottom" ? bias : 0; - const biasBottom = sideParam === "top" ? bias : 0; - const biasLeft = sideParam === "right" ? bias : 0; - const biasRight = sideParam === "left" ? bias : 0; if (typeof collisionPadding === "number") { collisionPadding = { - top: collisionPadding + biasTop, - right: collisionPadding + biasRight, - bottom: collisionPadding + biasBottom, - left: collisionPadding + biasLeft + top: collisionPadding, + right: collisionPadding, + bottom: collisionPadding, + left: collisionPadding }; } else if (collisionPadding) { collisionPadding = { - top: (collisionPadding.top || 0) + biasTop, - right: (collisionPadding.right || 0) + biasRight, - bottom: (collisionPadding.bottom || 0) + biasBottom, - left: (collisionPadding.left || 0) + biasLeft + top: collisionPadding.top || 0, + right: collisionPadding.right || 0, + bottom: collisionPadding.bottom || 0, + left: collisionPadding.left || 0 }; } + const bias = 1; + const biasTop = sideParam === "bottom" ? bias : 0; + const biasBottom = sideParam === "top" ? bias : 0; + const biasLeft = sideParam === "right" ? bias : 0; + const biasRight = sideParam === "left" ? bias : 0; const commonCollisionProps = { boundary: collisionBoundary === "clipping-ancestors" ? "clippingAncestors" : collisionBoundary, padding: collisionPadding }; - const arrowRef = React33.useRef(null); + const arrowRef = React32.useRef(null); const sideOffsetRef = useValueAsRef(sideOffset); const alignOffsetRef = useValueAsRef(alignOffset); const sideOffsetDep = typeof sideOffset !== "function" ? sideOffset : 0; @@ -7126,46 +7129,37 @@ function useAnchorPositioning(params) { // Ensure the popup flips if it's been limited by its --available-height and it resizes. // Since the size() padding is smaller than the flip() padding, flip() will take precedence. padding: { - top: collisionPadding.top + bias, - right: collisionPadding.right + bias, - bottom: collisionPadding.bottom + bias, - left: collisionPadding.left + bias + top: collisionPadding.top + bias + biasTop, + right: collisionPadding.right + bias + biasRight, + bottom: collisionPadding.bottom + bias + biasBottom, + left: collisionPadding.left + bias + biasLeft }, mainAxis: !shiftCrossAxis && collisionAvoidanceSide === "flip", crossAxis: collisionAvoidanceAlign === "flip" ? "alignment" : false, fallbackAxisSideDirection: collisionAvoidanceFallbackAxisSide }); - const shiftMiddleware = shiftDisabled ? null : shift3((data) => { - const html = ownerDocument(data.elements.floating).documentElement; - return { - ...commonCollisionProps, - // Use the Layout Viewport to avoid shifting around when pinch-zooming - // for context menus. - rootBoundary: shiftCrossAxis ? { - x: 0, - y: 0, - width: html.clientWidth, - height: html.clientHeight - } : void 0, - mainAxis: collisionAvoidanceAlign !== "none", - crossAxis: crossAxisShiftEnabled, - limiter: sticky || shiftCrossAxis ? void 0 : limitShift3((limitData) => { - if (!arrowRef.current) { - return {}; - } - const { - width, - height - } = arrowRef.current.getBoundingClientRect(); - const sideAxis = getSideAxis(getSide(limitData.placement)); - const arrowSize = sideAxis === "y" ? width : height; - const offsetAmount = sideAxis === "y" ? collisionPadding.left + collisionPadding.right : collisionPadding.top + collisionPadding.bottom; - return { - offset: arrowSize / 2 + offsetAmount / 2 - }; - }) - }; - }, [commonCollisionProps, sticky, shiftCrossAxis, collisionPadding, collisionAvoidanceAlign]); + const shiftMiddleware = shiftDisabled ? null : shift3({ + ...commonCollisionProps, + // Use the Layout Viewport to avoid shifting around when pinch-zooming. + rootBoundary: shiftRootBoundary, + mainAxis: collisionAvoidanceAlign !== "none", + crossAxis: crossAxisShiftEnabled, + limiter: sticky || shiftCrossAxis ? void 0 : limitShift3((limitData) => { + if (!arrowRef.current) { + return {}; + } + const { + width, + height + } = arrowRef.current.getBoundingClientRect(); + const sideAxis = getSideAxis(getSide(limitData.placement)); + const arrowSize = sideAxis === "y" ? width : height; + const offsetAmount = sideAxis === "y" ? collisionPadding.left + collisionPadding.right : collisionPadding.top + collisionPadding.bottom; + return { + offset: arrowSize / 2 + offsetAmount / 2 + }; + }) + }, [commonCollisionProps, sticky, shiftCrossAxis, shiftRootBoundary, collisionPadding, collisionAvoidanceAlign]); if (collisionAvoidanceSide === "shift" || collisionAvoidanceAlign === "shift" || align === "center") { middleware.push(shiftMiddleware, flipMiddleware); } else { @@ -7185,8 +7179,8 @@ function useAnchorPositioning(params) { return; } const floatingStyle = floating.style; - floatingStyle.setProperty("--available-width", `${availableWidth}px`); - floatingStyle.setProperty("--available-height", `${availableHeight}px`); + floatingStyle.setProperty(AVAILABLE_WIDTH_VAR, `${availableWidth}px`); + floatingStyle.setProperty(AVAILABLE_HEIGHT_VAR, `${availableHeight}px`); const dpr = getWindow(floating).devicePixelRatio || 1; const { x: x2, @@ -7249,7 +7243,7 @@ function useAnchorPositioning(params) { }); } }, [mounted, floatingRootContext]); - const autoUpdateOptions = React33.useMemo(() => ({ + const autoUpdateOptions = React32.useMemo(() => ({ elementResize: !disableAnchorTracking && typeof ResizeObserver !== "undefined", layoutShift: !disableAnchorTracking && typeof IntersectionObserver !== "undefined" }), [disableAnchorTracking]); @@ -7264,7 +7258,7 @@ function useAnchorPositioning(params) { context, isPositioned, floatingStyles: originalFloatingStyles - } = useFloating2({ + } = useFloatingHook({ rootContext: floatingRootContext, open: keepMounted ? mounted : void 0, placement, @@ -7279,21 +7273,34 @@ function useAnchorPositioning(params) { sideY } = middlewareData.adaptiveOrigin || DEFAULT_SIDES; const resolvedPosition = isPositioned ? positionMethod : "fixed"; - const floatingStyles = React33.useMemo(() => { - const base = adaptiveOrigin2 ? { - position: resolvedPosition, - [sideX]: x, - [sideY]: y - } : { - position: resolvedPosition, - ...originalFloatingStyles - }; + const floatingStyles = React32.useMemo(() => { + let base; + if (!isPositioned) { + base = { + position: resolvedPosition, + top: 0, + left: 0 + }; + } else if (adaptiveOrigin2) { + base = { + position: resolvedPosition, + [sideX]: x, + [sideY]: y + }; + } else { + base = { + ...originalFloatingStyles, + position: resolvedPosition + }; + } + base[AVAILABLE_WIDTH_VAR] = "100vw"; + base[AVAILABLE_HEIGHT_VAR] = "100vh"; if (!isPositioned) { base.opacity = 0; } return base; }, [adaptiveOrigin2, resolvedPosition, sideX, x, sideY, y, originalFloatingStyles, isPositioned]); - const registeredPositionReferenceRef = React33.useRef(null); + const registeredPositionReferenceRef = React32.useRef(null); useIsoLayoutEffect(() => { if (!mounted) { return; @@ -7307,7 +7314,7 @@ function useAnchorPositioning(params) { registeredPositionReferenceRef.current = finalAnchor; } }, [mounted, refs, anchorDep, anchorValueRef]); - React33.useEffect(() => { + React32.useEffect(() => { if (!mounted) { return; } @@ -7320,7 +7327,7 @@ function useAnchorPositioning(params) { registeredPositionReferenceRef.current = anchorValue.current; } }, [mounted, refs, anchorDep, anchorValueRef]); - React33.useEffect(() => { + React32.useEffect(() => { if (keepMounted && mounted && elements.reference && elements.floating) { return autoUpdate(elements.reference, elements.floating, update2, autoUpdateOptions); } @@ -7331,17 +7338,17 @@ function useAnchorPositioning(params) { const renderedAlign = getAlignment(renderedPlacement) || "center"; const anchorHidden = Boolean(middlewareData.hide?.referenceHidden); useIsoLayoutEffect(() => { - if (lazyFlip && mounted && isPositioned) { + if (lazyFlip && mounted && isPositioned && renderedSide !== side) { setMountSide(renderedSide); } - }, [lazyFlip, mounted, isPositioned, renderedSide]); - const arrowStyles = React33.useMemo(() => ({ + }, [lazyFlip, mounted, isPositioned, renderedSide, side]); + const arrowStyles = React32.useMemo(() => ({ position: "absolute", top: middlewareData.arrow?.y, left: middlewareData.arrow?.x }), [middlewareData.arrow]); const arrowUncentered = middlewareData.arrow?.centerOffset !== 0; - return React33.useMemo(() => ({ + return React32.useMemo(() => ({ positionerStyles: floatingStyles, arrowStyles, arrowRef, @@ -7360,7 +7367,7 @@ function isRef(param) { return param != null && "current" in param; } -// node_modules/@base-ui/react/utils/getDisabledMountTransitionStyles.mjs +// node_modules/@base-ui/react/internals/getDisabledMountTransitionStyles.mjs function getDisabledMountTransitionStyles(transitionStatus) { return transitionStatus === "starting" ? DISABLED_TRANSITIONS_STYLE : EMPTY_OBJECT; } @@ -7393,8 +7400,8 @@ function usePositioner(componentProps, state, { } // node_modules/@base-ui/react/button/Button.mjs -var React34 = __toESM(require_react(), 1); -var Button = /* @__PURE__ */ React34.forwardRef(function Button2(componentProps, forwardedRef) { +var React33 = __toESM(require_react(), 1); +var Button = /* @__PURE__ */ React33.forwardRef(function Button2(componentProps, forwardedRef) { const { render, className, @@ -7424,17 +7431,17 @@ var Button = /* @__PURE__ */ React34.forwardRef(function Button2(componentProps, if (true) Button.displayName = "Button"; // node_modules/@base-ui/react/utils/usePopupViewport.mjs -var React38 = __toESM(require_react(), 1); +var React37 = __toESM(require_react(), 1); var ReactDOM6 = __toESM(require_react_dom(), 1); // node_modules/@base-ui/utils/usePreviousValue.mjs -var React35 = __toESM(require_react(), 1); +var React34 = __toESM(require_react(), 1); function usePreviousValue(value) { - const [state, setState] = React35.useState({ + const [state, setState] = React34.useState({ current: value, previous: null }); - if (value !== state.current) { + if (!Object.is(value, state.current)) { setState({ current: value, previous: state.current @@ -7444,7 +7451,7 @@ function usePreviousValue(value) { } // node_modules/@base-ui/react/utils/usePopupAutoResize.mjs -var React36 = __toESM(require_react(), 1); +var React35 = __toESM(require_react(), 1); // node_modules/@base-ui/react/utils/getCssDimensions.mjs function getCssDimensions2(element) { @@ -7477,29 +7484,14 @@ function usePopupAutoResize(parameters) { side, direction } = parameters; - const runOnceAnimationsFinish = useAnimationsFinished(popupElement, true, false); + const runOnceAnimationsFinish = useAnimationsFinished(popupElement, true); const animationFrame = useAnimationFrame(); - const committedDimensionsRef = React36.useRef(null); - const isInitialRenderRef = React36.useRef(true); - const restoreAnchoringStylesRef = React36.useRef(NOOP); + const committedDimensionsRef = React35.useRef(null); + const isInitialRenderRef = React35.useRef(true); + const restoreAnchoringStylesRef = React35.useRef(NOOP); const onMeasureLayout = useStableCallback(onMeasureLayoutParam); const onMeasureLayoutComplete = useStableCallback(onMeasureLayoutCompleteParam); - const anchoringStyles = React36.useMemo(() => { - let isOriginSide = side === "top"; - let isPhysicalLeft = side === "left"; - if (direction === "rtl") { - isOriginSide = isOriginSide || side === "inline-end"; - isPhysicalLeft = isPhysicalLeft || side === "inline-end"; - } else { - isOriginSide = isOriginSide || side === "inline-start"; - isPhysicalLeft = isPhysicalLeft || side === "inline-start"; - } - return isOriginSide ? { - position: "absolute", - [side === "top" ? "bottom" : "top"]: "0", - [isPhysicalLeft ? "right" : "left"]: "0" - } : EMPTY_OBJECT; - }, [side, direction]); + const anchoringStyles = React35.useMemo(() => getPopupAnchoringStyles(side, direction), [side, direction]); useIsoLayoutEffect(() => { if (!mounted) { restoreAnchoringStylesRef.current = NOOP; @@ -7566,6 +7558,18 @@ function usePopupAutoResize(parameters) { }; }, [content, popupElement, positionerElement, runOnceAnimationsFinish, animationFrame, mounted, onMeasureLayout, onMeasureLayoutComplete, anchoringStyles]); } +function getPopupAnchoringStyles(side, direction) { + const isPhysicalTop = side === "top"; + const isPhysicalLeft = side === "left" || side === (direction === "rtl" ? "inline-end" : "inline-start"); + if (!isPhysicalTop && !isPhysicalLeft) { + return EMPTY_OBJECT; + } + return { + position: "absolute", + [isPhysicalTop ? "bottom" : "top"]: "0", + [isPhysicalLeft ? "right" : "left"]: "0" + }; +} function overrideElementStyle(element, property, value) { const originalValue = element.style.getPropertyValue(property); element.style.setProperty(property, value); @@ -7596,13 +7600,13 @@ function setPositionerCssSize(positionerElement, size4) { } // node_modules/@base-ui/react/direction-provider/DirectionProvider.mjs -var React37 = __toESM(require_react(), 1); +var React36 = __toESM(require_react(), 1); var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1); var DirectionProvider = function DirectionProvider2(props) { const { direction = "ltr" } = props; - const contextValue = React37.useMemo(() => ({ + const contextValue = React36.useMemo(() => ({ direction }), [direction]); return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DirectionContext.Provider, { @@ -7612,78 +7616,164 @@ var DirectionProvider = function DirectionProvider2(props) { }; if (true) DirectionProvider.displayName = "DirectionProvider"; -// node_modules/@base-ui/react/utils/usePopupViewport.mjs -var import_jsx_runtime6 = __toESM(require_jsx_runtime(), 1); -function usePopupViewport(parameters) { - const { - store: store2, - side, - cssVars, - children - } = parameters; - const direction = useDirection(); - const activeTrigger = store2.useState("activeTriggerElement"); - const activeTriggerId = store2.useState("activeTriggerId"); - const open = store2.useState("open"); - const payload = store2.useState("payload"); - const mounted = store2.useState("mounted"); - const popupElement = store2.useState("popupElement"); - const positionerElement = store2.useState("positionerElement"); - const previousActiveTrigger = usePreviousValue(open ? activeTrigger : null); - const currentContentKey = usePopupContentKey(activeTriggerId, payload); - const capturedNodeRef = React38.useRef(null); - const [previousContentNode, setPreviousContentNode] = React38.useState(null); - const [newTriggerOffset, setNewTriggerOffset] = React38.useState(null); - const currentContainerRef = React38.useRef(null); - const previousContainerRef = React38.useRef(null); - const onAnimationsFinished = useAnimationsFinished(currentContainerRef, true, false); - const cleanupFrame = useAnimationFrame(); - const [previousContentDimensions, setPreviousContentDimensions] = React38.useState(null); - const [showStartingStyleAttribute, setShowStartingStyleAttribute] = React38.useState(false); - useIsoLayoutEffect(() => { - store2.set("hasViewport", true); - return () => { - store2.set("hasViewport", false); - }; - }, [store2]); - const handleMeasureLayout = useStableCallback(() => { - currentContainerRef.current?.style.setProperty("animation", "none"); - currentContainerRef.current?.style.setProperty("transition", "none"); - previousContainerRef.current?.style.setProperty("display", "none"); - }); - const handleMeasureLayoutComplete = useStableCallback((previousDimensions) => { - currentContainerRef.current?.style.removeProperty("animation"); - currentContainerRef.current?.style.removeProperty("transition"); - previousContainerRef.current?.style.removeProperty("display"); - if (previousDimensions) { - setPreviousContentDimensions(previousDimensions); - } - }); - const lastHandledTriggerRef = React38.useRef(null); - useIsoLayoutEffect(() => { - if (!open || !mounted) { - lastHandledTriggerRef.current = null; - } - }, [open, mounted]); +// node_modules/@base-ui/react/utils/adaptiveOriginMiddleware.mjs +var adaptiveOrigin = { + name: "adaptiveOrigin", + async fn(state) { + const { + x: rawX, + y: rawY, + rects: { + floating: floatRect + }, + elements: { + floating + }, + platform: platform3, + strategy, + placement + } = state; + const win = getWindow(floating); + const styles = win.getComputedStyle(floating); + const hasTransition = styles.transitionDuration !== "0s" && styles.transitionDuration !== ""; + if (!hasTransition) { + return { + x: rawX, + y: rawY, + data: DEFAULT_SIDES + }; + } + const offsetParent = await platform3.getOffsetParent?.(floating); + let offsetDimensions = { + width: 0, + height: 0 + }; + if (strategy === "fixed" && win?.visualViewport) { + offsetDimensions = { + width: win.visualViewport.width, + height: win.visualViewport.height + }; + } else if (offsetParent === win) { + const doc = ownerDocument(floating); + offsetDimensions = { + width: doc.documentElement.clientWidth, + height: doc.documentElement.clientHeight + }; + } else if (await platform3.isElement?.(offsetParent)) { + offsetDimensions = await platform3.getDimensions(offsetParent); + } + const currentSide = getSide(placement); + let x = rawX; + let y = rawY; + if (currentSide === "left") { + x = offsetDimensions.width - (rawX + floatRect.width); + } + if (currentSide === "top") { + y = offsetDimensions.height - (rawY + floatRect.height); + } + const sideX = currentSide === "left" ? "right" : DEFAULT_SIDES.sideX; + const sideY = currentSide === "top" ? "bottom" : DEFAULT_SIDES.sideY; + return { + x, + y, + data: { + sideX, + sideY + } + }; + } +}; + +// node_modules/@base-ui/react/utils/usePopupViewport.mjs +var import_jsx_runtime6 = __toESM(require_jsx_runtime(), 1); +var popupViewportStateMapping = { + activationDirection: (value) => value ? { + "data-activation-direction": value + } : null +}; +function usePopupViewport(parameters) { + const { + store: store2, + side, + children + } = parameters; + const direction = useDirection(); + const activeTrigger = store2.useState("activeTriggerElement"); + const activeTriggerId = store2.useState("activeTriggerId"); + const open = store2.useState("open"); + const payload = store2.useState("payload"); + const mounted = store2.useState("mounted"); + const popupElement = store2.useState("popupElement"); + const positionerElement = store2.useState("positionerElement"); + const previousActiveTrigger = usePreviousValue(open ? activeTrigger : null); + const currentContentKey = usePopupContentKey(activeTriggerId, payload); + const capturedNodeRef = React37.useRef(null); + const [previousContentNode, setPreviousContentNode] = React37.useState(null); + const [newTriggerOffset, setNewTriggerOffset] = React37.useState(null); + const currentContainerRef = React37.useRef(null); + const previousContainerRef = React37.useRef(null); + const onAnimationsFinished = useAnimationsFinished(currentContainerRef, true); + const cleanupFrame = useAnimationFrame(); + const cleanupControllerRef = React37.useRef(null); + const [previousContentDimensions, setPreviousContentDimensions] = React37.useState(null); + const [showStartingStyleAttribute, setShowStartingStyleAttribute] = React37.useState(false); + useIsoLayoutEffect(() => { + store2.set("adaptiveOrigin", adaptiveOrigin); + return () => { + store2.set("adaptiveOrigin", void 0); + }; + }, [store2]); + const handleMeasureLayout = useStableCallback(() => { + currentContainerRef.current?.style.setProperty("animation", "none"); + currentContainerRef.current?.style.setProperty("transition", "none"); + previousContainerRef.current?.style.setProperty("display", "none"); + }); + const handleMeasureLayoutComplete = useStableCallback((previousDimensions) => { + currentContainerRef.current?.style.removeProperty("animation"); + currentContainerRef.current?.style.removeProperty("transition"); + previousContainerRef.current?.style.removeProperty("display"); + if (previousDimensions) { + setPreviousContentDimensions(previousDimensions); + } + }); + const armViewportCleanup = useStableCallback(() => { + cleanupControllerRef.current?.abort(); + const controller = new AbortController(); + cleanupControllerRef.current = controller; + onAnimationsFinished(() => { + setPreviousContentNode(null); + setPreviousContentDimensions(null); + capturedNodeRef.current = null; + }, controller.signal); + }); + const lastHandledTriggerRef = React37.useRef(null); + useIsoLayoutEffect(() => { + if (!open || !mounted) { + lastHandledTriggerRef.current = null; + } + }, [open, mounted]); useIsoLayoutEffect(() => { if (activeTrigger && previousActiveTrigger && activeTrigger !== previousActiveTrigger && lastHandledTriggerRef.current !== activeTrigger && capturedNodeRef.current) { setPreviousContentNode(capturedNodeRef.current); setShowStartingStyleAttribute(true); const offset4 = calculateRelativePosition(previousActiveTrigger, activeTrigger); setNewTriggerOffset(offset4); - cleanupFrame.request(() => { - ReactDOM6.flushSync(() => { - setShowStartingStyleAttribute(false); - }); - onAnimationsFinished(() => { - setPreviousContentNode(null); - setPreviousContentDimensions(null); - capturedNodeRef.current = null; - }); - }); lastHandledTriggerRef.current = activeTrigger; } - }, [activeTrigger, previousActiveTrigger, previousContentNode, onAnimationsFinished, cleanupFrame]); + }, [activeTrigger, previousActiveTrigger]); + useIsoLayoutEffect(() => { + if (previousContentNode == null) { + return; + } + cleanupControllerRef.current?.abort(); + setShowStartingStyleAttribute(true); + cleanupFrame.request(() => { + ReactDOM6.flushSync(() => { + setShowStartingStyleAttribute(false); + }); + armViewportCleanup(); + }); + }, [currentContentKey, previousContentNode, armViewportCleanup, cleanupFrame]); useIsoLayoutEffect(() => { const source = currentContainerRef.current; if (!source) { @@ -7704,15 +7794,15 @@ function usePopupViewport(parameters) { children }, currentContentKey); } else { - childrenToRender = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(React38.Fragment, { + childrenToRender = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(React37.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { "data-previous": true, inert: inertValue(true), ref: previousContainerRef, style: { ...previousContentDimensions ? { - [cssVars.popupWidth]: `${previousContentDimensions.width}px`, - [cssVars.popupHeight]: `${previousContentDimensions.height}px` + "--popup-width": `${previousContentDimensions.width}px`, + "--popup-height": `${previousContentDimensions.height}px` } : null, position: "absolute" }, @@ -7783,10 +7873,10 @@ function calculateRelativePosition(from, to) { }; } function usePopupContentKey(activeTriggerId, payload) { - const [contentKey, setContentKey] = React38.useState(0); - const previousActiveTriggerIdRef = React38.useRef(activeTriggerId); - const previousPayloadRef = React38.useRef(payload); - const pendingPayloadUpdateRef = React38.useRef(false); + const [contentKey, setContentKey] = React37.useState(0); + const previousActiveTriggerIdRef = React37.useRef(activeTriggerId); + const previousPayloadRef = React37.useRef(payload); + const pendingPayloadUpdateRef = React37.useRef(false); useIsoLayoutEffect(() => { const previousActiveTriggerId = previousActiveTriggerIdRef.current; const previousPayload = previousPayloadRef.current; @@ -7806,10 +7896,10 @@ function usePopupContentKey(activeTriggerId, payload) { } // node_modules/@base-ui/react/utils/FloatingPortalLite.mjs -var React39 = __toESM(require_react(), 1); +var React38 = __toESM(require_react(), 1); var ReactDOM7 = __toESM(require_react_dom(), 1); var import_jsx_runtime7 = __toESM(require_jsx_runtime(), 1); -var FloatingPortalLite = /* @__PURE__ */ React39.forwardRef(function FloatingPortalLite2(componentProps, forwardedRef) { +var FloatingPortalLite = /* @__PURE__ */ React38.forwardRef(function FloatingPortalLite2(componentProps, forwardedRef) { const { children, container, @@ -7819,8 +7909,8 @@ var FloatingPortalLite = /* @__PURE__ */ React39.forwardRef(function FloatingPor ...elementProps } = componentProps; const { - portalNode, - portalSubtree + node: portalNode, + subtree: portalSubtree } = useFloatingPortalNode({ container, ref: forwardedRef, @@ -7830,7 +7920,7 @@ var FloatingPortalLite = /* @__PURE__ */ React39.forwardRef(function FloatingPor if (!portalSubtree && !portalNode) { return null; } - return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(React39.Fragment, { + return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(React38.Fragment, { children: [portalSubtree, portalNode && /* @__PURE__ */ ReactDOM7.createPortal(children, portalNode)] }); }); @@ -7852,14 +7942,14 @@ __export(index_parts_exports, { }); // node_modules/@base-ui/react/tooltip/root/TooltipRoot.mjs -var React42 = __toESM(require_react(), 1); +var React41 = __toESM(require_react(), 1); // node_modules/@base-ui/react/tooltip/root/TooltipRootContext.mjs -var React40 = __toESM(require_react(), 1); -var TooltipRootContext = /* @__PURE__ */ React40.createContext(void 0); +var React39 = __toESM(require_react(), 1); +var TooltipRootContext = /* @__PURE__ */ React39.createContext(void 0); if (true) TooltipRootContext.displayName = "TooltipRootContext"; function useTooltipRootContext(optional) { - const context = React40.useContext(TooltipRootContext); + const context = React39.useContext(TooltipRootContext); if (context === void 0 && !optional) { throw new Error(true ? "Base UI: TooltipRootContext is missing. Tooltip parts must be placed within ." : formatErrorMessage_default(72)); } @@ -7867,33 +7957,23 @@ function useTooltipRootContext(optional) { } // node_modules/@base-ui/react/tooltip/store/TooltipStore.mjs -var React41 = __toESM(require_react(), 1); +var React40 = __toESM(require_react(), 1); var selectors2 = { ...popupStoreSelectors, - disabled: createSelector((state) => state.disabled), - instantType: createSelector((state) => state.instantType), - isInstantPhase: createSelector((state) => state.isInstantPhase), - trackCursorAxis: createSelector((state) => state.trackCursorAxis), - disableHoverablePopup: createSelector((state) => state.disableHoverablePopup), - lastOpenChangeReason: createSelector((state) => state.openChangeReason), - closeOnClick: createSelector((state) => state.closeOnClick), - closeDelay: createSelector((state) => state.closeDelay), - hasViewport: createSelector((state) => state.hasViewport) + disabled: (state) => state.disabled, + instantType: (state) => state.instantType, + isInstantPhase: (state) => state.isInstantPhase, + trackCursorAxis: (state) => state.trackCursorAxis, + disableHoverablePopup: (state) => state.disableHoverablePopup, + lastOpenChangeReason: (state) => state.openChangeReason, + closeOnClick: (state) => state.closeOnClick, + closeDelay: (state) => state.closeDelay, + adaptiveOrigin: (state) => state.adaptiveOrigin }; -var TooltipStore = class _TooltipStore extends ReactStore { - constructor(initialState, floatingId, nested = false) { +var TooltipStore = class extends ReactStore { + constructor(initialState, floatingId, nested) { const triggerElements = new PopupTriggerMap(); - const state = { - ...createInitialState(), - ...initialState - }; - state.floatingRootContext = createPopupFloatingRootContext(triggerElements, floatingId, nested); - super(state, { - popupRef: /* @__PURE__ */ React41.createRef(), - onOpenChange: void 0, - onOpenChangeComplete: void 0, - triggerElements - }, selectors2); + super(createInitialState(initialState, triggerElements, floatingId, nested), createInitialContext(triggerElements), selectors2); } setOpen = (nextOpen, eventDetails) => { applyPopupOpenChange(this, nextOpen, eventDetails, { @@ -7906,13 +7986,17 @@ var TooltipStore = class _TooltipStore extends ReactStore { cancelPendingOpen(event) { this.state.floatingRootContext.dispatchOpenChange(false, createChangeEventDetails(reason_parts_exports.triggerPress, event)); } - static useStore(externalStore, initialState) { - const store2 = usePopupStore(externalStore, (floatingId, nested) => new _TooltipStore(initialState, floatingId, nested)).store; - return store2; - } }; -function createInitialState() { - return { +function createNullTooltipStore() { + const triggerElements = new PopupTriggerMap(); + const store2 = new NullStore(Object.freeze(createInitialState(void 0, triggerElements)), Object.freeze(createInitialContext(triggerElements)), selectors2); + return Object.assign(store2, { + setOpen: NOOP, + cancelPendingOpen: NOOP + }); +} +function createInitialState(initialState, triggerElements, floatingId, nested = false) { + const state = { ...createInitialPopupStoreState(), disabled: false, instantType: void 0, @@ -7922,7 +8006,18 @@ function createInitialState() { openChangeReason: null, closeOnClick: true, closeDelay: 0, - hasViewport: false + adaptiveOrigin: void 0, + ...initialState + }; + state.floatingRootContext = createPopupFloatingRootContext(triggerElements, floatingId, nested); + return state; +} +function createInitialContext(triggerElements) { + return { + popupRef: /* @__PURE__ */ React40.createRef(), + onOpenChange: void 0, + onOpenChangeComplete: void 0, + triggerElements }; } @@ -7943,13 +8038,12 @@ var TooltipRoot = fastComponent(function TooltipRoot2(props) { defaultTriggerId: defaultTriggerIdProp = null, children } = props; - const store2 = TooltipStore.useStore(handle?.store, { + const store2 = usePopupRootStore((floatingId, nested) => new TooltipStore({ open: defaultOpen, openProp, activeTriggerId: defaultTriggerIdProp, triggerIdProp - }); - useInitialOpenSync(store2, openProp, defaultOpen, defaultTriggerIdProp); + }, floatingId, nested)); store2.useControlledProp("openProp", openProp); store2.useControlledProp("triggerIdProp", triggerIdProp); store2.useContextCallback("onOpenChange", onOpenChange); @@ -7961,9 +8055,9 @@ var TooltipRoot = fastComponent(function TooltipRoot2(props) { const payload = store2.useState("payload"); store2.useSyncedValues({ trackCursorAxis, - disableHoverablePopup + disableHoverablePopup, + disabled: disabled2 }); - store2.useSyncedValue("disabled", disabled2); useImplicitActiveTrigger(store2, { closeOnActiveTriggerUnmount: true }); @@ -7974,7 +8068,7 @@ var TooltipRoot = fastComponent(function TooltipRoot2(props) { const isInstantPhase = store2.useState("isInstantPhase"); const instantType = store2.useState("instantType"); const lastOpenChangeReason = store2.useState("lastOpenChangeReason"); - const previousInstantTypeRef = React42.useRef(null); + const previousInstantTypeRef = React41.useRef(null); useIsoLayoutEffect(() => { if (openState && disabled2) { store2.setOpen(false, createChangeEventDetails(reason_parts_exports.disabled)); @@ -7998,17 +8092,17 @@ var TooltipRoot = fastComponent(function TooltipRoot2(props) { } } }, [store2, activeTriggerId, open]); - const handleImperativeClose = React42.useCallback(() => { - store2.setOpen(false, createChangeEventDetails(reason_parts_exports.imperativeAction)); - }, [store2]); - React42.useImperativeHandle(actionsRef, () => ({ + React41.useImperativeHandle(actionsRef, () => ({ unmount: forceUnmount, - close: handleImperativeClose - }), [forceUnmount, handleImperativeClose]); + close: () => store2.setOpen(false, createChangeEventDetails(reason_parts_exports.imperativeAction)) + }), [forceUnmount, store2]); const shouldRenderInteractions = open || mounted || !disabled2 && trackCursorAxis !== "none"; return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(TooltipRootContext.Provider, { value: store2, - children: [shouldRenderInteractions && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipInteractions, { + children: [handle && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PopupHandleAttachment, { + handle, + store: store2 + }), shouldRenderInteractions && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipInteractions, { store: store2, disabled: disabled2, trackCursorAxis @@ -8032,35 +8126,26 @@ function TooltipInteractions({ enabled: !disabled2 && trackCursorAxis !== "none", axis: trackCursorAxis === "none" ? void 0 : trackCursorAxis }); - const activeTriggerProps = React42.useMemo(() => mergeProps(clientPoint.reference, dismiss.reference), [clientPoint.reference, dismiss.reference]); - const inactiveTriggerProps = React42.useMemo(() => mergeProps(clientPoint.trigger, dismiss.trigger), [clientPoint.trigger, dismiss.trigger]); - const popupProps = React42.useMemo(() => mergeProps(FOCUSABLE_POPUP_PROPS, clientPoint.floating, dismiss.floating), [clientPoint.floating, dismiss.floating]); + const triggerProps = React41.useMemo(() => mergeProps(clientPoint.reference, dismiss.reference), [clientPoint.reference, dismiss.reference]); usePopupInteractionProps(store2, { - activeTriggerProps, - inactiveTriggerProps, - popupProps + activeTriggerProps: triggerProps, + inactiveTriggerProps: triggerProps, + popupProps: dismiss.floating ?? EMPTY_OBJECT }); return null; } // node_modules/@base-ui/react/tooltip/trigger/TooltipTrigger.mjs -var React44 = __toESM(require_react(), 1); +var React43 = __toESM(require_react(), 1); // node_modules/@base-ui/react/tooltip/provider/TooltipProviderContext.mjs -var React43 = __toESM(require_react(), 1); -var TooltipProviderContext = /* @__PURE__ */ React43.createContext(void 0); +var React42 = __toESM(require_react(), 1); +var TooltipProviderContext = /* @__PURE__ */ React42.createContext(void 0); if (true) TooltipProviderContext.displayName = "TooltipProviderContext"; function useTooltipProviderContext() { - return React43.useContext(TooltipProviderContext); + return React42.useContext(TooltipProviderContext); } -// node_modules/@base-ui/react/tooltip/trigger/TooltipTriggerDataAttributes.mjs -var TooltipTriggerDataAttributes = (function(TooltipTriggerDataAttributes2) { - TooltipTriggerDataAttributes2[TooltipTriggerDataAttributes2["popupOpen"] = CommonTriggerDataAttributes.popupOpen] = "popupOpen"; - TooltipTriggerDataAttributes2["triggerDisabled"] = "data-trigger-disabled"; - return TooltipTriggerDataAttributes2; -})({}); - // node_modules/@base-ui/react/tooltip/utils/constants.mjs var OPEN_DELAY = 600; @@ -8085,13 +8170,9 @@ function getTargetElement(event) { function closestEnabledTooltipTrigger(element) { let current = element; while (current) { - if (current.hasAttribute(TOOLTIP_TRIGGER_IDENTIFIER)) { - return current; - } - const parentElement = current.parentElement; - if (parentElement) { - current = parentElement; - continue; + const trigger = current.closest(`[${TOOLTIP_TRIGGER_IDENTIFIER}]`); + if (trigger) { + return trigger; } const root = current.getRootNode(); current = "host" in root && isElement(root.host) ? root.host : null; @@ -8113,7 +8194,8 @@ var TooltipTrigger = fastComponentRef(function TooltipTrigger2(componentProps, f ...elementProps } = componentProps; const rootContext = useTooltipRootContext(true); - const store2 = handle?.store ?? rootContext; + const handleStore = usePopupHandleStore(handle); + const store2 = handleStore ?? rootContext; if (!store2) { throw new Error(true ? "Base UI: must be either used within a component or provided with a handle." : formatErrorMessage_default(82)); } @@ -8121,7 +8203,7 @@ var TooltipTrigger = fastComponentRef(function TooltipTrigger2(componentProps, f const isTriggerActive = store2.useState("isTriggerActive", thisTriggerId); const isOpenedByThisTrigger = store2.useState("isOpenedByTrigger", thisTriggerId); const floatingRootContext = store2.useState("floatingRootContext"); - const triggerElementRef = React44.useRef(null); + const triggerElementRef = React43.useRef(null); const delayWithDefault = delay ?? OPEN_DELAY; const closeDelayWithDefault = closeDelay ?? 0; const { @@ -8132,7 +8214,7 @@ var TooltipTrigger = fastComponentRef(function TooltipTrigger2(componentProps, f closeOnClick, closeDelay: closeDelayWithDefault }); - const providerContext = useTooltipProviderContext(); + const providerDelay = useTooltipProviderContext(); const { delayRef, isInstantPhase, @@ -8147,21 +8229,14 @@ var TooltipTrigger = fastComponentRef(function TooltipTrigger2(componentProps, f const disabledRef = useValueAsRef(disabled2); const trackCursorAxis = store2.useState("trackCursorAxis"); const disableHoverablePopup = store2.useState("disableHoverablePopup"); - const isNestedTriggerHoveredRef = React44.useRef(false); + const isNestedTriggerHoveredRef = React43.useRef(false); const nestedTriggerOpenTimeout = useTimeout(); - const pointerTypeRef = React44.useRef(void 0); + const pointerTypeRef = React43.useRef(void 0); function getOpenDelay() { - const providerDelay = providerContext?.delay; - const groupOpenValue = typeof delayRef.current === "object" ? delayRef.current.open : void 0; - let computedOpenDelay = delayWithDefault; - if (hasProvider) { - if (groupOpenValue !== 0) { - computedOpenDelay = delay ?? providerDelay ?? delayWithDefault; - } else { - computedOpenDelay = 0; - } + if (!hasProvider) { + return delayWithDefault; } - return computedOpenDelay; + return getDelay(delayRef.current, "open") === 0 ? 0 : delay ?? providerDelay ?? OPEN_DELAY; } function isEnabledNestedTriggerTarget(target) { const triggerEl = triggerElementRef.current; @@ -8189,13 +8264,13 @@ var TooltipTrigger = fastComponentRef(function TooltipTrigger2(componentProps, f handleClose: !disableHoverablePopup && trackCursorAxis !== "both" ? safePolygon() : null, restMs: getOpenDelay, delay() { - const closeValue = typeof delayRef.current === "object" ? delayRef.current.close : void 0; - let computedCloseDelay = closeDelayWithDefault; if (closeDelay == null && hasProvider) { - computedCloseDelay = closeValue; + return { + close: getDelay(delayRef.current, "close") + }; } return { - close: computedCloseDelay + close: closeDelayWithDefault }; }, triggerElementRef, @@ -8272,7 +8347,7 @@ var TooltipTrigger = fastComponentRef(function TooltipTrigger2(componentProps, f } }, id: thisTriggerId, - [TooltipTriggerDataAttributes.triggerDisabled]: disabled2 ? "" : void 0, + "data-trigger-disabled": disabled2 ? "" : void 0, [TOOLTIP_TRIGGER_IDENTIFIER]: disabled2 ? void 0 : "" }, elementProps], stateAttributesMapping: triggerOpenStateMapping @@ -8282,14 +8357,14 @@ var TooltipTrigger = fastComponentRef(function TooltipTrigger2(componentProps, f if (true) TooltipTrigger.displayName = "TooltipTrigger"; // node_modules/@base-ui/react/tooltip/portal/TooltipPortal.mjs -var React46 = __toESM(require_react(), 1); +var React45 = __toESM(require_react(), 1); // node_modules/@base-ui/react/tooltip/portal/TooltipPortalContext.mjs -var React45 = __toESM(require_react(), 1); -var TooltipPortalContext = /* @__PURE__ */ React45.createContext(void 0); +var React44 = __toESM(require_react(), 1); +var TooltipPortalContext = /* @__PURE__ */ React44.createContext(void 0); if (true) TooltipPortalContext.displayName = "TooltipPortalContext"; function useTooltipPortalContext() { - const value = React45.useContext(TooltipPortalContext); + const value = React44.useContext(TooltipPortalContext); if (value === void 0) { throw new Error(true ? "Base UI: is missing." : formatErrorMessage_default(70)); } @@ -8298,7 +8373,7 @@ function useTooltipPortalContext() { // node_modules/@base-ui/react/tooltip/portal/TooltipPortal.mjs var import_jsx_runtime9 = __toESM(require_jsx_runtime(), 1); -var TooltipPortal = /* @__PURE__ */ React46.forwardRef(function TooltipPortal2(props, forwardedRef) { +var TooltipPortal = /* @__PURE__ */ React45.forwardRef(function TooltipPortal2(props, forwardedRef) { const { keepMounted = false, ...portalProps @@ -8320,14 +8395,14 @@ var TooltipPortal = /* @__PURE__ */ React46.forwardRef(function TooltipPortal2(p if (true) TooltipPortal.displayName = "TooltipPortal"; // node_modules/@base-ui/react/tooltip/positioner/TooltipPositioner.mjs -var React48 = __toESM(require_react(), 1); +var React47 = __toESM(require_react(), 1); // node_modules/@base-ui/react/tooltip/positioner/TooltipPositionerContext.mjs -var React47 = __toESM(require_react(), 1); -var TooltipPositionerContext = /* @__PURE__ */ React47.createContext(void 0); +var React46 = __toESM(require_react(), 1); +var TooltipPositionerContext = /* @__PURE__ */ React46.createContext(void 0); if (true) TooltipPositionerContext.displayName = "TooltipPositionerContext"; function useTooltipPositionerContext() { - const context = React47.useContext(TooltipPositionerContext); + const context = React46.useContext(TooltipPositionerContext); if (context === void 0) { throw new Error(true ? "Base UI: TooltipPositionerContext is missing. TooltipPositioner parts must be placed within ." : formatErrorMessage_default(71)); } @@ -8336,7 +8411,7 @@ function useTooltipPositionerContext() { // node_modules/@base-ui/react/tooltip/positioner/TooltipPositioner.mjs var import_jsx_runtime10 = __toESM(require_jsx_runtime(), 1); -var TooltipPositioner = /* @__PURE__ */ React48.forwardRef(function TooltipPositioner2(componentProps, forwardedRef) { +var TooltipPositioner = /* @__PURE__ */ React47.forwardRef(function TooltipPositioner2(componentProps, forwardedRef) { const { render, className, @@ -8364,7 +8439,7 @@ var TooltipPositioner = /* @__PURE__ */ React48.forwardRef(function TooltipPosit const floatingRootContext = store2.useState("floatingRootContext"); const instantType = store2.useState("instantType"); const transitionStatus = store2.useState("transitionStatus"); - const hasViewport = store2.useState("hasViewport"); + const adaptiveOrigin2 = store2.useState("adaptiveOrigin"); const positioning = useAnchorPositioning({ anchor, positionMethod, @@ -8381,9 +8456,9 @@ var TooltipPositioner = /* @__PURE__ */ React48.forwardRef(function TooltipPosit disableAnchorTracking, keepMounted, collisionAvoidance, - adaptiveOrigin: hasViewport ? adaptiveOrigin : void 0 + adaptiveOrigin: adaptiveOrigin2 }); - const state = React48.useMemo(() => ({ + const state = React47.useMemo(() => ({ open, side: positioning.side, align: positioning.align, @@ -8406,12 +8481,8 @@ var TooltipPositioner = /* @__PURE__ */ React48.forwardRef(function TooltipPosit if (true) TooltipPositioner.displayName = "TooltipPositioner"; // node_modules/@base-ui/react/tooltip/popup/TooltipPopup.mjs -var React49 = __toESM(require_react(), 1); -var stateAttributesMapping = { - ...popupStateMapping, - ...transitionStatusMapping -}; -var TooltipPopup = /* @__PURE__ */ React49.forwardRef(function TooltipPopup2(componentProps, forwardedRef) { +var React48 = __toESM(require_react(), 1); +var TooltipPopup = /* @__PURE__ */ React48.forwardRef(function TooltipPopup2(componentProps, forwardedRef) { const { render, className, @@ -8454,16 +8525,16 @@ var TooltipPopup = /* @__PURE__ */ React49.forwardRef(function TooltipPopup2(com const element = useRenderElement("div", componentProps, { state, ref: [forwardedRef, store2.context.popupRef, setPopupElement], - props: [popupProps, getDisabledMountTransitionStyles(transitionStatus), elementProps], - stateAttributesMapping + props: [FOCUSABLE_POPUP_PROPS, popupProps, getDisabledMountTransitionStyles(transitionStatus), elementProps], + stateAttributesMapping: popupTransitionStateMapping }); return element; }); if (true) TooltipPopup.displayName = "TooltipPopup"; // node_modules/@base-ui/react/tooltip/arrow/TooltipArrow.mjs -var React50 = __toESM(require_react(), 1); -var TooltipArrow = /* @__PURE__ */ React50.forwardRef(function TooltipArrow2(componentProps, forwardedRef) { +var React49 = __toESM(require_react(), 1); +var TooltipArrow = /* @__PURE__ */ React49.forwardRef(function TooltipArrow2(componentProps, forwardedRef) { const { render, className, @@ -8501,7 +8572,7 @@ var TooltipArrow = /* @__PURE__ */ React50.forwardRef(function TooltipArrow2(com if (true) TooltipArrow.displayName = "TooltipArrow"; // node_modules/@base-ui/react/tooltip/provider/TooltipProvider.mjs -var React51 = __toESM(require_react(), 1); +var React50 = __toESM(require_react(), 1); var import_jsx_runtime11 = __toESM(require_jsx_runtime(), 1); var TooltipProvider = function TooltipProvider2(props) { const { @@ -8509,16 +8580,12 @@ var TooltipProvider = function TooltipProvider2(props) { closeDelay, timeout = 400 } = props; - const contextValue = React51.useMemo(() => ({ - delay, - closeDelay - }), [delay, closeDelay]); - const delayValue = React51.useMemo(() => ({ + const delayValue = React50.useMemo(() => ({ open: delay, close: closeDelay }), [delay, closeDelay]); return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TooltipProviderContext.Provider, { - value: contextValue, + value: delay, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(FloatingDelayGroup, { delay: delayValue, timeoutMs: timeout, @@ -8529,22 +8596,8 @@ var TooltipProvider = function TooltipProvider2(props) { if (true) TooltipProvider.displayName = "TooltipProvider"; // node_modules/@base-ui/react/tooltip/viewport/TooltipViewport.mjs -var React52 = __toESM(require_react(), 1); - -// node_modules/@base-ui/react/tooltip/viewport/TooltipViewportCssVars.mjs -var TooltipViewportCssVars = /* @__PURE__ */ (function(TooltipViewportCssVars2) { - TooltipViewportCssVars2["popupWidth"] = "--popup-width"; - TooltipViewportCssVars2["popupHeight"] = "--popup-height"; - return TooltipViewportCssVars2; -})({}); - -// node_modules/@base-ui/react/tooltip/viewport/TooltipViewport.mjs -var stateAttributesMapping2 = { - activationDirection: (value) => value ? { - "data-activation-direction": value - } : null -}; -var TooltipViewport = /* @__PURE__ */ React52.forwardRef(function TooltipViewport2(componentProps, forwardedRef) { +var React51 = __toESM(require_react(), 1); +var TooltipViewport = /* @__PURE__ */ React51.forwardRef(function TooltipViewport2(componentProps, forwardedRef) { const { render, className, @@ -8561,7 +8614,6 @@ var TooltipViewport = /* @__PURE__ */ React52.forwardRef(function TooltipViewpor } = usePopupViewport({ store: store2, side: positioner.side, - cssVars: TooltipViewportCssVars, children }); const state = { @@ -8575,46 +8627,40 @@ var TooltipViewport = /* @__PURE__ */ React52.forwardRef(function TooltipViewpor props: [elementProps, { children: childrenToRender }], - stateAttributesMapping: stateAttributesMapping2 + stateAttributesMapping: popupViewportStateMapping }); }); if (true) TooltipViewport.displayName = "TooltipViewport"; // node_modules/@base-ui/react/tooltip/store/TooltipHandle.mjs -var TooltipHandle = class { - /** - * Internal store holding the tooltip state. - * @internal - */ +var TooltipHandle = class extends BasePopupHandle { constructor() { - this.store = new TooltipStore(); + super(createNullTooltipStore(), "Tooltip"); } /** - * Opens the tooltip and associates it with the trigger with the given ID. - * The trigger must be a Tooltip.Trigger component with this handle passed as a prop. + * Opens the tooltip and associates it with the trigger with the given id. * * This method should only be called in an event handler or an effect (not during rendering). * - * @param triggerId ID of the trigger to associate with the tooltip. + * @param triggerId ID of the trigger to associate with the tooltip. The trigger must be a matching + * `Tooltip.Trigger` with this handle passed as a prop. */ open(triggerId) { - const triggerElement = triggerId ? this.store.context.triggerElements.getById(triggerId) : void 0; - if (triggerId && !triggerElement) { - throw new Error(true ? `Base UI: TooltipHandle.open: No trigger found with id "${triggerId}".` : formatErrorMessage_default(81, triggerId)); - } - this.store.setOpen(true, createChangeEventDetails(reason_parts_exports.imperativeAction, void 0, triggerElement)); + this.openByTrigger(triggerId); } /** * Closes the tooltip. + * + * This method should only be called in an event handler or an effect (not during rendering). */ close() { - this.store.setOpen(false, createChangeEventDetails(reason_parts_exports.imperativeAction, void 0, void 0)); + this.closePopup(); } /** - * Indicates whether the tooltip is currently open. + * Whether the tooltip is currently open. Returns `false` while no root is attached to the handle. */ get isOpen() { - return this.store.select("open"); + return this.attachedStore?.select("open") ?? false; } }; function createTooltipHandle() { @@ -8922,7 +8968,7 @@ function registerStyle3(hash, css) { } } if (typeof process === "undefined" || true) { - registerStyle3("b74f1ac304", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._97b0fc33c028be1a__button,.abbb272e2ce49bd6__is-unstyled{appearance:none;padding:0}._97b0fc33c028be1a__button{--wp-ui-button-font-weight:var(--wpds-typography-font-weight-emphasis,600);--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-strong,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-strong-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 93%,#000));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand-strong,#fff);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-strong-active,#fff);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-strong-disabled,#8d8d8d);--wp-ui-button-padding-block:var(--wpds-dimension-padding-xs,4px);--wp-ui-button-padding-inline:var(--wpds-dimension-padding-md,12px);--wp-ui-button-height:var(--wpds-dimension-size-lg,40px);--wp-ui-button-aspect-ratio:auto;--wp-ui-button-font-size:var(--wpds-typography-font-size-md,13px);--wp-ui-button-min-width:calc(4ch + var(--wp-ui-button-padding-inline)*2);--wp-ui-button-icon-margin:calc((var(--wpds-dimension-size-2xs, 16px) - var(--wpds-dimension-size-sm, 24px))/2);--wp-ui-button-border-color:var(--wp-ui-button-background-color);--wp-ui-button-border-color-active:var(--wp-ui-button-background-color-active);--wp-ui-button-border-color-disabled:var(--wp-ui-button-background-color-disabled);--_gcd-button-font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);--_gcd-button-font-size:var(--wp-ui-button-font-size);--_gcd-button-font-weight:var(--wp-ui-button-font-weight);align-items:center;aspect-ratio:var(--wp-ui-button-aspect-ratio);background-clip:border-box;background-color:var(--wp-ui-button-background-color);border-color:var(--wp-ui-button-border-color);border-radius:var(--wpds-border-radius-sm,2px);border-style:solid;border-width:1px;color:var(--wp-ui-button-foreground-color);display:inline-flex;font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wp-ui-button-font-size);font-weight:var(--wp-ui-button-font-weight);gap:var(--wpds-dimension-gap-sm,8px);justify-content:center;line-height:var(--wpds-typography-line-height-sm,20px);max-width:100%;min-height:var(--wp-ui-button-height);min-width:var(--wp-ui-button-min-width);overflow-wrap:anywhere;padding-block:var(--wp-ui-button-padding-block);padding-inline:var(--wp-ui-button-padding-inline);position:relative;text-align:center;text-decoration:none;&:not([data-disabled]){cursor:var(--wpds-cursor-control,pointer)}@media not (prefers-reduced-motion){transition:color .1s ease-out;*{transition:opacity .1s ease-out}}&[href]{cursor:pointer}[href]{color:inherit;text-decoration:inherit}&:not([data-disabled]):is(:hover,:active,:focus){background-color:var(--wp-ui-button-background-color-active);border-color:var(--wp-ui-button-border-color-active);color:var(--wp-ui-button-foreground-color-active)}&[data-disabled]:not(._914b42f315c0e580__is-loading){background-color:var(--wp-ui-button-background-color-disabled);border-color:var(--wp-ui-button-border-color-disabled);color:var(--wp-ui-button-foreground-color-disabled);@media (forced-colors:active){border-bottom-color:GrayText;border-left-color:GrayText;border-right-color:GrayText;border-top-color:GrayText;color:GrayText}}&:before{aspect-ratio:1;border:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid;border-block-end-color:transparent;border-block-start-color:var(--wp-ui-button-foreground-color);border-inline-end-color:var(--wp-ui-button-foreground-color);border-inline-start-color:transparent;border-radius:50%;box-sizing:border-box;content:"";display:block;height:var(--wp-ui-button-font-size);inset-inline-start:50%;opacity:0;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);@media not (prefers-reduced-motion){transition:opacity .1s ease-out}@media (forced-colors:active){border-block-end-style:none;border-bottom-color:ButtonText;border-inline-start-style:none;border-left-color:ButtonText;border-right-color:ButtonText;border-top-color:ButtonText}}}._908205475f9f2a92__is-small{--wp-ui-button-padding-block:0px;--wp-ui-button-padding-inline:var(--wpds-dimension-padding-sm,8px);--wp-ui-button-height:var(--wpds-dimension-size-sm,24px)}._9f6fc6553aeb36fe__icon{margin:var(--wp-ui-button-icon-margin)}.dd460c965226cc77__is-brand{&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 85%,#000));--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-brand-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000)}}.e722a8f96726aa99__is-neutral{&.ad0619a3217c6a5b__is-minimal[aria-pressed=true],&.b50b3358c5fb4d0b__is-solid{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-strong,#2d2d2d);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-strong-active,#1e1e1e);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral-strong,#f0f0f0);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-strong-active,#f0f0f0);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-strong-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d);--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-neutral-active,#6e6e6e);--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-neutral-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000)}}.abbb272e2ce49bd6__is-unstyled{background:none;border:none;min-width:unset}.cf59cf1b69629838__is-compact{--wp-ui-button-height:var(--wpds-dimension-size-md,32px)}._914b42f315c0e580__is-loading:not(.abbb272e2ce49bd6__is-unstyled){color:transparent;&:not([data-disabled]):is(:hover,:active,:focus){color:transparent}@media (forced-colors:active){color:ButtonFace}*{opacity:0}&:before{opacity:1;transition-delay:.05s;@media not (prefers-reduced-motion){animation:_5a1d53da6f830c8d__loading-animation 1s linear infinite}}}}@keyframes _5a1d53da6f830c8d__loading-animation{0%{transform:translate(-50%,-50%) rotate(0deg)}to{transform:translate(-50%,-50%) rotate(1turn)}}}'); + registerStyle3("effc4e3032", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._97b0fc33c028be1a__button,.abbb272e2ce49bd6__is-unstyled{appearance:none;padding:0}._97b0fc33c028be1a__button{--wp-ui-button-font-weight:var(--wpds-typography-font-weight-emphasis,600);--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-strong,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-strong-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 93%,#000));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand-strong,#fff);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-strong-active,#fff);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-strong-disabled,#8d8d8d);--wp-ui-button-padding-block:var(--wpds-dimension-padding-xs,4px);--wp-ui-button-padding-inline:var(--wpds-dimension-padding-md,12px);--wp-ui-button-height:var(--wpds-dimension-size-lg,40px);--wp-ui-button-aspect-ratio:auto;--wp-ui-button-font-size:var(--wpds-typography-font-size-md,13px);--wp-ui-button-min-width:calc(4ch + var(--wp-ui-button-padding-inline)*2);--wp-ui-button-icon-margin:calc((var(--wpds-dimension-size-2xs, 16px) - var(--wpds-dimension-size-sm, 24px))/2);--wp-ui-button-border-color:var(--wp-ui-button-background-color);--wp-ui-button-border-color-active:var(--wp-ui-button-background-color-active);--wp-ui-button-border-color-disabled:var(--wp-ui-button-background-color-disabled);--_gcd-button-font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);--_gcd-button-font-size:var(--wp-ui-button-font-size);--_gcd-button-font-weight:var(--wp-ui-button-font-weight);align-items:center;aspect-ratio:var(--wp-ui-button-aspect-ratio);background-clip:border-box;background-color:var(--wp-ui-button-background-color);border-color:var(--wp-ui-button-border-color);border-radius:var(--wpds-border-radius-sm,2px);border-style:solid;border-width:1px;color:var(--wp-ui-button-foreground-color);display:inline-flex;font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wp-ui-button-font-size);font-weight:var(--wp-ui-button-font-weight);gap:var(--wpds-dimension-gap-sm,8px);justify-content:center;line-height:var(--wpds-typography-line-height-sm,20px);max-width:100%;min-height:var(--wp-ui-button-height);min-width:var(--wp-ui-button-min-width);overflow-wrap:anywhere;padding-block:var(--wp-ui-button-padding-block);padding-inline:var(--wp-ui-button-padding-inline);position:relative;text-align:center;text-decoration:none;&:not([data-disabled]){cursor:var(--wpds-cursor-control,pointer)}@media not (prefers-reduced-motion){transition:color .1s ease-out;*{transition:opacity .1s ease-out}}&[href]{cursor:pointer}[href]{color:inherit;text-decoration:inherit}&:not([data-disabled]):is(:hover,:active,:focus){background-color:var(--wp-ui-button-background-color-active);border-color:var(--wp-ui-button-border-color-active);color:var(--wp-ui-button-foreground-color-active)}&[data-disabled]:not(._914b42f315c0e580__is-loading){background-color:var(--wp-ui-button-background-color-disabled);border-color:var(--wp-ui-button-border-color-disabled);color:var(--wp-ui-button-foreground-color-disabled);@media (forced-colors:active){border-bottom-color:GrayText;border-left-color:GrayText;border-right-color:GrayText;border-top-color:GrayText;color:GrayText}}&:before{aspect-ratio:1;border:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid;border-block-end-color:transparent;border-block-start-color:var(--wp-ui-button-foreground-color);border-inline-end-color:var(--wp-ui-button-foreground-color);border-inline-start-color:transparent;border-radius:50%;box-sizing:border-box;content:"";display:block;height:var(--wp-ui-button-font-size);left:50%;opacity:0;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);@media not (prefers-reduced-motion){transition:opacity .1s ease-out}@media (forced-colors:active){border-block-end-style:none;border-bottom-color:ButtonText;border-inline-start-style:none;border-left-color:ButtonText;border-right-color:ButtonText;border-top-color:ButtonText}}}._908205475f9f2a92__is-small{--wp-ui-button-padding-block:0px;--wp-ui-button-padding-inline:var(--wpds-dimension-padding-sm,8px);--wp-ui-button-height:var(--wpds-dimension-size-sm,24px)}._9f6fc6553aeb36fe__icon{margin:var(--wp-ui-button-icon-margin)}.dd460c965226cc77__is-brand{&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 85%,#000));--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-brand-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000)}}.e722a8f96726aa99__is-neutral{&.ad0619a3217c6a5b__is-minimal[aria-pressed=true],&.b50b3358c5fb4d0b__is-solid{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-strong,#2d2d2d);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-strong-active,#1e1e1e);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral-strong,#f0f0f0);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-strong-active,#f0f0f0);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-strong-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d);--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-neutral-active,#6e6e6e);--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-neutral-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000)}}.abbb272e2ce49bd6__is-unstyled{background:none;border:none;min-width:unset}.cf59cf1b69629838__is-compact{--wp-ui-button-height:var(--wpds-dimension-size-md,32px)}._914b42f315c0e580__is-loading:not(.abbb272e2ce49bd6__is-unstyled){color:transparent;&:not([data-disabled]):is(:hover,:active,:focus){color:transparent}@media (forced-colors:active){color:ButtonFace}*{opacity:0}&:before{opacity:1;transition-delay:.05s;@media not (prefers-reduced-motion){animation:_5a1d53da6f830c8d__loading-animation 1s linear infinite}}}}@keyframes _5a1d53da6f830c8d__loading-animation{0%{transform:translate(-50%,-50%) rotate(0deg)}to{transform:translate(-50%,-50%) rotate(1turn)}}}'); } var style_default3 = { "button": "_97b0fc33c028be1a__button", "is-unstyled": "abbb272e2ce49bd6__is-unstyled", "is-loading": "_914b42f315c0e580__is-loading", "is-small": "_908205475f9f2a92__is-small", "icon": "_9f6fc6553aeb36fe__icon", "is-brand": "dd460c965226cc77__is-brand", "is-outline": "_62d5a778b7b258ee__is-outline", "is-minimal": "ad0619a3217c6a5b__is-minimal", "is-neutral": "e722a8f96726aa99__is-neutral", "is-solid": "b50b3358c5fb4d0b__is-solid", "is-compact": "cf59cf1b69629838__is-compact", "loading-animation": "_5a1d53da6f830c8d__loading-animation" }; if (typeof process === "undefined" || true) { @@ -8930,7 +8976,7 @@ if (typeof process === "undefined" || true) { } var resets_default = { "box-sizing": "_336cd3e4e743482f__box-sizing" }; if (typeof process === "undefined" || true) { - registerStyle3("2ffedd8246", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._64de9947bf305b7a__outset-ring--focus-within-visible:focus-within:has(:focus-visible),.af79fb116edb0dd7__outset-ring--focus:focus,.dfcfdc28396e5d98__outset-ring--focus-visible:focus-visible,.e5cd9ee879f6403a__outset-ring--focus-within:focus-within,:focus-visible ._81935a08e952f267__outset-ring--focus-parent-visible{--focus-color:var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color);outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within,.abc777e9713fa711__outset-ring--focus-except-active:focus{outline:none}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within:not(:has(:active)),.abc777e9713fa711__outset-ring--focus-except-active:focus:not(:active){--focus-color:var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color);outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}}}"); + registerStyle3("96553466c8", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._64de9947bf305b7a__outset-ring--focus-within-visible:focus-within:has(:focus-visible),.af79fb116edb0dd7__outset-ring--focus:focus,.dfcfdc28396e5d98__outset-ring--focus-visible:focus-visible,.e5cd9ee879f6403a__outset-ring--focus-within:focus-within,:focus-visible ._81935a08e952f267__outset-ring--focus-parent-visible{--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within,.abc777e9713fa711__outset-ring--focus-except-active:focus{outline:none}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within:not(:has(:active)),.abc777e9713fa711__outset-ring--focus-except-active:focus:not(:active){--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}}}"); } var focus_module_default = { "outset-ring--focus": "af79fb116edb0dd7__outset-ring--focus", "outset-ring--focus-visible": "dfcfdc28396e5d98__outset-ring--focus-visible", "outset-ring--focus-within": "e5cd9ee879f6403a__outset-ring--focus-within", "outset-ring--focus-within-visible": "_64de9947bf305b7a__outset-ring--focus-within-visible", "outset-ring--focus-parent-visible": "_81935a08e952f267__outset-ring--focus-parent-visible", "outset-ring--focus-except-active": "abc777e9713fa711__outset-ring--focus-except-active", "outset-ring--focus-within-except-active": "_3c9f5ee9fc9c136d__outset-ring--focus-within-except-active" }; if (typeof process === "undefined" || true) { @@ -9083,7 +9129,7 @@ function registerStyle4(hash, css) { } } if (typeof process === "undefined" || true) { - registerStyle4("b74f1ac304", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._97b0fc33c028be1a__button,.abbb272e2ce49bd6__is-unstyled{appearance:none;padding:0}._97b0fc33c028be1a__button{--wp-ui-button-font-weight:var(--wpds-typography-font-weight-emphasis,600);--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-strong,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-strong-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 93%,#000));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand-strong,#fff);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-strong-active,#fff);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-strong-disabled,#8d8d8d);--wp-ui-button-padding-block:var(--wpds-dimension-padding-xs,4px);--wp-ui-button-padding-inline:var(--wpds-dimension-padding-md,12px);--wp-ui-button-height:var(--wpds-dimension-size-lg,40px);--wp-ui-button-aspect-ratio:auto;--wp-ui-button-font-size:var(--wpds-typography-font-size-md,13px);--wp-ui-button-min-width:calc(4ch + var(--wp-ui-button-padding-inline)*2);--wp-ui-button-icon-margin:calc((var(--wpds-dimension-size-2xs, 16px) - var(--wpds-dimension-size-sm, 24px))/2);--wp-ui-button-border-color:var(--wp-ui-button-background-color);--wp-ui-button-border-color-active:var(--wp-ui-button-background-color-active);--wp-ui-button-border-color-disabled:var(--wp-ui-button-background-color-disabled);--_gcd-button-font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);--_gcd-button-font-size:var(--wp-ui-button-font-size);--_gcd-button-font-weight:var(--wp-ui-button-font-weight);align-items:center;aspect-ratio:var(--wp-ui-button-aspect-ratio);background-clip:border-box;background-color:var(--wp-ui-button-background-color);border-color:var(--wp-ui-button-border-color);border-radius:var(--wpds-border-radius-sm,2px);border-style:solid;border-width:1px;color:var(--wp-ui-button-foreground-color);display:inline-flex;font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wp-ui-button-font-size);font-weight:var(--wp-ui-button-font-weight);gap:var(--wpds-dimension-gap-sm,8px);justify-content:center;line-height:var(--wpds-typography-line-height-sm,20px);max-width:100%;min-height:var(--wp-ui-button-height);min-width:var(--wp-ui-button-min-width);overflow-wrap:anywhere;padding-block:var(--wp-ui-button-padding-block);padding-inline:var(--wp-ui-button-padding-inline);position:relative;text-align:center;text-decoration:none;&:not([data-disabled]){cursor:var(--wpds-cursor-control,pointer)}@media not (prefers-reduced-motion){transition:color .1s ease-out;*{transition:opacity .1s ease-out}}&[href]{cursor:pointer}[href]{color:inherit;text-decoration:inherit}&:not([data-disabled]):is(:hover,:active,:focus){background-color:var(--wp-ui-button-background-color-active);border-color:var(--wp-ui-button-border-color-active);color:var(--wp-ui-button-foreground-color-active)}&[data-disabled]:not(._914b42f315c0e580__is-loading){background-color:var(--wp-ui-button-background-color-disabled);border-color:var(--wp-ui-button-border-color-disabled);color:var(--wp-ui-button-foreground-color-disabled);@media (forced-colors:active){border-bottom-color:GrayText;border-left-color:GrayText;border-right-color:GrayText;border-top-color:GrayText;color:GrayText}}&:before{aspect-ratio:1;border:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid;border-block-end-color:transparent;border-block-start-color:var(--wp-ui-button-foreground-color);border-inline-end-color:var(--wp-ui-button-foreground-color);border-inline-start-color:transparent;border-radius:50%;box-sizing:border-box;content:"";display:block;height:var(--wp-ui-button-font-size);inset-inline-start:50%;opacity:0;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);@media not (prefers-reduced-motion){transition:opacity .1s ease-out}@media (forced-colors:active){border-block-end-style:none;border-bottom-color:ButtonText;border-inline-start-style:none;border-left-color:ButtonText;border-right-color:ButtonText;border-top-color:ButtonText}}}._908205475f9f2a92__is-small{--wp-ui-button-padding-block:0px;--wp-ui-button-padding-inline:var(--wpds-dimension-padding-sm,8px);--wp-ui-button-height:var(--wpds-dimension-size-sm,24px)}._9f6fc6553aeb36fe__icon{margin:var(--wp-ui-button-icon-margin)}.dd460c965226cc77__is-brand{&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 85%,#000));--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-brand-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000)}}.e722a8f96726aa99__is-neutral{&.ad0619a3217c6a5b__is-minimal[aria-pressed=true],&.b50b3358c5fb4d0b__is-solid{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-strong,#2d2d2d);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-strong-active,#1e1e1e);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral-strong,#f0f0f0);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-strong-active,#f0f0f0);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-strong-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d);--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-neutral-active,#6e6e6e);--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-neutral-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000)}}.abbb272e2ce49bd6__is-unstyled{background:none;border:none;min-width:unset}.cf59cf1b69629838__is-compact{--wp-ui-button-height:var(--wpds-dimension-size-md,32px)}._914b42f315c0e580__is-loading:not(.abbb272e2ce49bd6__is-unstyled){color:transparent;&:not([data-disabled]):is(:hover,:active,:focus){color:transparent}@media (forced-colors:active){color:ButtonFace}*{opacity:0}&:before{opacity:1;transition-delay:.05s;@media not (prefers-reduced-motion){animation:_5a1d53da6f830c8d__loading-animation 1s linear infinite}}}}@keyframes _5a1d53da6f830c8d__loading-animation{0%{transform:translate(-50%,-50%) rotate(0deg)}to{transform:translate(-50%,-50%) rotate(1turn)}}}'); + registerStyle4("effc4e3032", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._97b0fc33c028be1a__button,.abbb272e2ce49bd6__is-unstyled{appearance:none;padding:0}._97b0fc33c028be1a__button{--wp-ui-button-font-weight:var(--wpds-typography-font-weight-emphasis,600);--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-strong,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-strong-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 93%,#000));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand-strong,#fff);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-strong-active,#fff);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-strong-disabled,#8d8d8d);--wp-ui-button-padding-block:var(--wpds-dimension-padding-xs,4px);--wp-ui-button-padding-inline:var(--wpds-dimension-padding-md,12px);--wp-ui-button-height:var(--wpds-dimension-size-lg,40px);--wp-ui-button-aspect-ratio:auto;--wp-ui-button-font-size:var(--wpds-typography-font-size-md,13px);--wp-ui-button-min-width:calc(4ch + var(--wp-ui-button-padding-inline)*2);--wp-ui-button-icon-margin:calc((var(--wpds-dimension-size-2xs, 16px) - var(--wpds-dimension-size-sm, 24px))/2);--wp-ui-button-border-color:var(--wp-ui-button-background-color);--wp-ui-button-border-color-active:var(--wp-ui-button-background-color-active);--wp-ui-button-border-color-disabled:var(--wp-ui-button-background-color-disabled);--_gcd-button-font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);--_gcd-button-font-size:var(--wp-ui-button-font-size);--_gcd-button-font-weight:var(--wp-ui-button-font-weight);align-items:center;aspect-ratio:var(--wp-ui-button-aspect-ratio);background-clip:border-box;background-color:var(--wp-ui-button-background-color);border-color:var(--wp-ui-button-border-color);border-radius:var(--wpds-border-radius-sm,2px);border-style:solid;border-width:1px;color:var(--wp-ui-button-foreground-color);display:inline-flex;font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wp-ui-button-font-size);font-weight:var(--wp-ui-button-font-weight);gap:var(--wpds-dimension-gap-sm,8px);justify-content:center;line-height:var(--wpds-typography-line-height-sm,20px);max-width:100%;min-height:var(--wp-ui-button-height);min-width:var(--wp-ui-button-min-width);overflow-wrap:anywhere;padding-block:var(--wp-ui-button-padding-block);padding-inline:var(--wp-ui-button-padding-inline);position:relative;text-align:center;text-decoration:none;&:not([data-disabled]){cursor:var(--wpds-cursor-control,pointer)}@media not (prefers-reduced-motion){transition:color .1s ease-out;*{transition:opacity .1s ease-out}}&[href]{cursor:pointer}[href]{color:inherit;text-decoration:inherit}&:not([data-disabled]):is(:hover,:active,:focus){background-color:var(--wp-ui-button-background-color-active);border-color:var(--wp-ui-button-border-color-active);color:var(--wp-ui-button-foreground-color-active)}&[data-disabled]:not(._914b42f315c0e580__is-loading){background-color:var(--wp-ui-button-background-color-disabled);border-color:var(--wp-ui-button-border-color-disabled);color:var(--wp-ui-button-foreground-color-disabled);@media (forced-colors:active){border-bottom-color:GrayText;border-left-color:GrayText;border-right-color:GrayText;border-top-color:GrayText;color:GrayText}}&:before{aspect-ratio:1;border:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid;border-block-end-color:transparent;border-block-start-color:var(--wp-ui-button-foreground-color);border-inline-end-color:var(--wp-ui-button-foreground-color);border-inline-start-color:transparent;border-radius:50%;box-sizing:border-box;content:"";display:block;height:var(--wp-ui-button-font-size);left:50%;opacity:0;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);@media not (prefers-reduced-motion){transition:opacity .1s ease-out}@media (forced-colors:active){border-block-end-style:none;border-bottom-color:ButtonText;border-inline-start-style:none;border-left-color:ButtonText;border-right-color:ButtonText;border-top-color:ButtonText}}}._908205475f9f2a92__is-small{--wp-ui-button-padding-block:0px;--wp-ui-button-padding-inline:var(--wpds-dimension-padding-sm,8px);--wp-ui-button-height:var(--wpds-dimension-size-sm,24px)}._9f6fc6553aeb36fe__icon{margin:var(--wp-ui-button-icon-margin)}.dd460c965226cc77__is-brand{&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 85%,#000));--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-brand-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000)}}.e722a8f96726aa99__is-neutral{&.ad0619a3217c6a5b__is-minimal[aria-pressed=true],&.b50b3358c5fb4d0b__is-solid{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-strong,#2d2d2d);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-strong-active,#1e1e1e);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral-strong,#f0f0f0);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-strong-active,#f0f0f0);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-strong-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d);--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-neutral-active,#6e6e6e);--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-neutral-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000)}}.abbb272e2ce49bd6__is-unstyled{background:none;border:none;min-width:unset}.cf59cf1b69629838__is-compact{--wp-ui-button-height:var(--wpds-dimension-size-md,32px)}._914b42f315c0e580__is-loading:not(.abbb272e2ce49bd6__is-unstyled){color:transparent;&:not([data-disabled]):is(:hover,:active,:focus){color:transparent}@media (forced-colors:active){color:ButtonFace}*{opacity:0}&:before{opacity:1;transition-delay:.05s;@media not (prefers-reduced-motion){animation:_5a1d53da6f830c8d__loading-animation 1s linear infinite}}}}@keyframes _5a1d53da6f830c8d__loading-animation{0%{transform:translate(-50%,-50%) rotate(0deg)}to{transform:translate(-50%,-50%) rotate(1turn)}}}'); } var style_default4 = { "button": "_97b0fc33c028be1a__button", "is-unstyled": "abbb272e2ce49bd6__is-unstyled", "is-loading": "_914b42f315c0e580__is-loading", "is-small": "_908205475f9f2a92__is-small", "icon": "_9f6fc6553aeb36fe__icon", "is-brand": "dd460c965226cc77__is-brand", "is-outline": "_62d5a778b7b258ee__is-outline", "is-minimal": "ad0619a3217c6a5b__is-minimal", "is-neutral": "e722a8f96726aa99__is-neutral", "is-solid": "b50b3358c5fb4d0b__is-solid", "is-compact": "cf59cf1b69629838__is-compact", "loading-animation": "_5a1d53da6f830c8d__loading-animation" }; var ButtonIcon = (0, import_element14.forwardRef)( @@ -9136,41 +9182,16 @@ var import_primitives6 = __toESM(require_primitives(), 1); var import_jsx_runtime20 = __toESM(require_jsx_runtime(), 1); var published_default = /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_primitives6.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_primitives6.Path, { fillRule: "evenodd", clipRule: "evenodd", d: "M12 18.5a6.5 6.5 0 1 1 0-13 6.5 6.5 0 0 1 0 13ZM4 12a8 8 0 1 1 16 0 8 8 0 0 1-16 0Zm11.53-1.47-1.06-1.06L11 12.94l-1.47-1.47-1.06 1.06L11 15.06l4.53-4.53Z" }) }); -// packages/ui/build-module/utils/render-slot-with-children.mjs -var import_element15 = __toESM(require_element(), 1); -function renderSlotWithChildren(slot, defaultSlot, children) { - return (0, import_element15.cloneElement)(slot ?? defaultSlot, { children }); -} - -// packages/ui/build-module/utils/theme-provider.mjs -var theme = __toESM(require_theme(), 1); +// packages/ui/build-module/icon-button/icon-button.mjs +var import_element22 = __toESM(require_element(), 1); -// packages/ui/build-module/lock-unlock.mjs -var import_private_apis = __toESM(require_private_apis(), 1); -var { lock, unlock } = (0, import_private_apis.__dangerousOptInToUnstableAPIsOnlyForCoreModules)( - "I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.", - "@wordpress/ui" -); +// packages/ui/build-module/tooltip/popup.mjs +var import_element18 = __toESM(require_element(), 1); -// packages/ui/build-module/utils/theme-provider.mjs -function getThemeProvider() { - const themePackage = theme; - if (themePackage.ThemeProvider) { - return themePackage.ThemeProvider; - } - if (!themePackage.privateApis) { - throw new Error( - "@wordpress/ui: @wordpress/theme must expose `ThemeProvider` or `privateApis.ThemeProvider`." - ); - } - return unlock( - themePackage.privateApis - ).ThemeProvider; -} -var ThemeProvider = getThemeProvider(); +// packages/ui/build-module/tooltip/portal.mjs +var import_element15 = __toESM(require_element(), 1); -// packages/ui/build-module/stack/stack.mjs -var import_element16 = __toESM(require_element(), 1); +// packages/ui/build-module/utils/wp-compat-overlay-slot.mjs var STYLE_HASH_ATTRIBUTE5 = "data-wp-hash"; function getRuntime5() { const globalScope = globalThis; @@ -9252,126 +9273,7 @@ function registerStyle5(hash, css) { } } if (typeof process === "undefined" || true) { - registerStyle5("32aba35fe1", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._19ce0419607e1896__stack{display:flex}}}"); -} -var style_default5 = { "stack": "_19ce0419607e1896__stack" }; -var gapTokens = { - xs: "var(--wpds-dimension-gap-xs, 4px)", - sm: "var(--wpds-dimension-gap-sm, 8px)", - md: "var(--wpds-dimension-gap-md, 12px)", - lg: "var(--wpds-dimension-gap-lg, 16px)", - xl: "var(--wpds-dimension-gap-xl, 24px)", - "2xl": "var(--wpds-dimension-gap-2xl, 32px)", - "3xl": "var(--wpds-dimension-gap-3xl, 40px)" -}; -var Stack = (0, import_element16.forwardRef)(function Stack2({ direction, gap, align, justify, wrap, render, ...props }, ref) { - const style = { - gap: gap && gapTokens[gap], - alignItems: align, - justifyContent: justify, - flexDirection: direction, - flexWrap: wrap - }; - const element = useRender({ - render, - ref, - props: mergeProps(props, { style, className: style_default5.stack }) - }); - return element; -}); - -// packages/ui/build-module/icon-button/icon-button.mjs -var import_element23 = __toESM(require_element(), 1); - -// packages/ui/build-module/tooltip/popup.mjs -var import_element19 = __toESM(require_element(), 1); - -// packages/ui/build-module/tooltip/portal.mjs -var import_element17 = __toESM(require_element(), 1); - -// packages/ui/build-module/utils/wp-compat-overlay-slot.mjs -var STYLE_HASH_ATTRIBUTE6 = "data-wp-hash"; -function getRuntime6() { - const globalScope = globalThis; - if (globalScope.__wpStyleRuntime) { - return globalScope.__wpStyleRuntime; - } - globalScope.__wpStyleRuntime = { - documents: /* @__PURE__ */ new Map(), - styles: /* @__PURE__ */ new Map(), - injectedStyles: /* @__PURE__ */ new WeakMap() - }; - if (typeof document !== "undefined") { - registerDocument6(document); - } - return globalScope.__wpStyleRuntime; -} -function documentContainsStyleHash6(targetDocument, hash) { - if (!targetDocument.head) { - return false; - } - for (const style of targetDocument.head.querySelectorAll( - `style[${STYLE_HASH_ATTRIBUTE6}]` - )) { - if (style.getAttribute(STYLE_HASH_ATTRIBUTE6) === hash) { - return true; - } - } - return false; -} -function injectStyle6(targetDocument, hash, css) { - if (!targetDocument.head) { - return; - } - const runtime = getRuntime6(); - let injectedStyles = runtime.injectedStyles.get(targetDocument); - if (!injectedStyles) { - injectedStyles = /* @__PURE__ */ new Set(); - runtime.injectedStyles.set(targetDocument, injectedStyles); - } - if (injectedStyles.has(hash)) { - return; - } - if (documentContainsStyleHash6(targetDocument, hash)) { - injectedStyles.add(hash); - return; - } - const style = targetDocument.createElement("style"); - style.setAttribute(STYLE_HASH_ATTRIBUTE6, hash); - style.appendChild(targetDocument.createTextNode(css)); - targetDocument.head.appendChild(style); - injectedStyles.add(hash); -} -function registerDocument6(targetDocument) { - const runtime = getRuntime6(); - runtime.documents.set( - targetDocument, - (runtime.documents.get(targetDocument) ?? 0) + 1 - ); - for (const [hash, css] of runtime.styles) { - injectStyle6(targetDocument, hash, css); - } - return () => { - const count = runtime.documents.get(targetDocument); - if (count === void 0) { - return; - } - if (count <= 1) { - runtime.documents.delete(targetDocument); - return; - } - runtime.documents.set(targetDocument, count - 1); - }; -} -function registerStyle6(hash, css) { - const runtime = getRuntime6(); - runtime.styles.set(hash, css); - for (const targetDocument of runtime.documents.keys()) { - injectStyle6(targetDocument, hash, css); - } -} -if (typeof process === "undefined" || true) { - registerStyle6("be37f31c1e", "._11fc52b637ff8a7e__slot{inset:0;isolation:isolate;pointer-events:none;position:fixed;z-index:1000000003}@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._11fc52b637ff8a7e__slot>*{pointer-events:auto}}}"); + registerStyle5("be37f31c1e", "._11fc52b637ff8a7e__slot{inset:0;isolation:isolate;pointer-events:none;position:fixed;z-index:1000000003}@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._11fc52b637ff8a7e__slot>*{pointer-events:auto}}}"); } var wp_compat_overlay_slot_default = { "slot": "_11fc52b637ff8a7e__slot" }; var WP_COMPAT_OVERLAY_SLOT_ATTRIBUTE = "data-wp-compat-overlay-slot"; @@ -9431,7 +9333,7 @@ function getWpCompatOverlaySlot() { // packages/ui/build-module/tooltip/portal.mjs var import_jsx_runtime21 = __toESM(require_jsx_runtime(), 1); -var Portal = (0, import_element17.forwardRef)( +var Portal = (0, import_element15.forwardRef)( function TooltipPortal3({ container, ...restProps }, ref) { return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)( index_parts_exports.Portal, @@ -9445,10 +9347,10 @@ var Portal = (0, import_element17.forwardRef)( ); // packages/ui/build-module/tooltip/positioner.mjs -var import_element18 = __toESM(require_element(), 1); +var import_element16 = __toESM(require_element(), 1); var import_jsx_runtime22 = __toESM(require_jsx_runtime(), 1); -var STYLE_HASH_ATTRIBUTE7 = "data-wp-hash"; -function getRuntime7() { +var STYLE_HASH_ATTRIBUTE6 = "data-wp-hash"; +function getRuntime6() { const globalScope = globalThis; if (globalScope.__wpStyleRuntime) { return globalScope.__wpStyleRuntime; @@ -9459,28 +9361,28 @@ function getRuntime7() { injectedStyles: /* @__PURE__ */ new WeakMap() }; if (typeof document !== "undefined") { - registerDocument7(document); + registerDocument6(document); } return globalScope.__wpStyleRuntime; } -function documentContainsStyleHash7(targetDocument, hash) { +function documentContainsStyleHash6(targetDocument, hash) { if (!targetDocument.head) { return false; } for (const style of targetDocument.head.querySelectorAll( - `style[${STYLE_HASH_ATTRIBUTE7}]` + `style[${STYLE_HASH_ATTRIBUTE6}]` )) { - if (style.getAttribute(STYLE_HASH_ATTRIBUTE7) === hash) { + if (style.getAttribute(STYLE_HASH_ATTRIBUTE6) === hash) { return true; } } return false; } -function injectStyle7(targetDocument, hash, css) { +function injectStyle6(targetDocument, hash, css) { if (!targetDocument.head) { return; } - const runtime = getRuntime7(); + const runtime = getRuntime6(); let injectedStyles = runtime.injectedStyles.get(targetDocument); if (!injectedStyles) { injectedStyles = /* @__PURE__ */ new Set(); @@ -9489,24 +9391,24 @@ function injectStyle7(targetDocument, hash, css) { if (injectedStyles.has(hash)) { return; } - if (documentContainsStyleHash7(targetDocument, hash)) { + if (documentContainsStyleHash6(targetDocument, hash)) { injectedStyles.add(hash); return; } const style = targetDocument.createElement("style"); - style.setAttribute(STYLE_HASH_ATTRIBUTE7, hash); + style.setAttribute(STYLE_HASH_ATTRIBUTE6, hash); style.appendChild(targetDocument.createTextNode(css)); targetDocument.head.appendChild(style); injectedStyles.add(hash); } -function registerDocument7(targetDocument) { - const runtime = getRuntime7(); +function registerDocument6(targetDocument) { + const runtime = getRuntime6(); runtime.documents.set( targetDocument, (runtime.documents.get(targetDocument) ?? 0) + 1 ); for (const [hash, css] of runtime.styles) { - injectStyle7(targetDocument, hash, css); + injectStyle6(targetDocument, hash, css); } return () => { const count = runtime.documents.get(targetDocument); @@ -9520,22 +9422,22 @@ function registerDocument7(targetDocument) { runtime.documents.set(targetDocument, count - 1); }; } -function registerStyle7(hash, css) { - const runtime = getRuntime7(); +function registerStyle6(hash, css) { + const runtime = getRuntime6(); runtime.styles.set(hash, css); for (const targetDocument of runtime.documents.keys()) { - injectStyle7(targetDocument, hash, css); + injectStyle6(targetDocument, hash, css); } } if (typeof process === "undefined" || true) { - registerStyle7("10f3806643", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}"); + registerStyle6("10f3806643", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}"); } var resets_default2 = { "box-sizing": "_336cd3e4e743482f__box-sizing" }; if (typeof process === "undefined" || true) { - registerStyle7("19fcc06039", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}'); + registerStyle6("19fcc06039", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}'); } -var style_default6 = { "positioner": "_480b748dd3510e64__positioner", "popup": "_50096b232db7709d__popup" }; -var Positioner = (0, import_element18.forwardRef)( +var style_default5 = { "positioner": "_480b748dd3510e64__positioner", "popup": "_50096b232db7709d__popup" }; +var Positioner = (0, import_element16.forwardRef)( function TooltipPositioner3({ align = "center", className, side = "top", sideOffset = 4, ...props }, ref) { return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)( index_parts_exports.Positioner, @@ -9547,7 +9449,7 @@ var Positioner = (0, import_element18.forwardRef)( ...props, className: clsx_default( resets_default2["box-sizing"], - style_default6.positioner, + style_default5.positioner, className ) } @@ -9555,10 +9457,43 @@ var Positioner = (0, import_element18.forwardRef)( } ); +// packages/ui/build-module/utils/render-slot-with-children.mjs +var import_element17 = __toESM(require_element(), 1); +function renderSlotWithChildren(slot, defaultSlot, children) { + return (0, import_element17.cloneElement)(slot ?? defaultSlot, { children }); +} + +// packages/ui/build-module/utils/theme-provider.mjs +var theme = __toESM(require_theme(), 1); + +// packages/ui/build-module/lock-unlock.mjs +var import_private_apis = __toESM(require_private_apis(), 1); +var { lock, unlock } = (0, import_private_apis.__dangerousOptInToUnstableAPIsOnlyForCoreModules)( + "I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.", + "@wordpress/ui" +); + +// packages/ui/build-module/utils/theme-provider.mjs +function getThemeProvider() { + const themePackage = theme; + if (themePackage.ThemeProvider) { + return themePackage.ThemeProvider; + } + if (!themePackage.privateApis) { + throw new Error( + "@wordpress/ui: @wordpress/theme must expose `ThemeProvider` or `privateApis.ThemeProvider`." + ); + } + return unlock( + themePackage.privateApis + ).ThemeProvider; +} +var ThemeProvider = getThemeProvider(); + // packages/ui/build-module/tooltip/popup.mjs var import_jsx_runtime23 = __toESM(require_jsx_runtime(), 1); -var STYLE_HASH_ATTRIBUTE8 = "data-wp-hash"; -function getRuntime8() { +var STYLE_HASH_ATTRIBUTE7 = "data-wp-hash"; +function getRuntime7() { const globalScope = globalThis; if (globalScope.__wpStyleRuntime) { return globalScope.__wpStyleRuntime; @@ -9569,28 +9504,28 @@ function getRuntime8() { injectedStyles: /* @__PURE__ */ new WeakMap() }; if (typeof document !== "undefined") { - registerDocument8(document); + registerDocument7(document); } return globalScope.__wpStyleRuntime; } -function documentContainsStyleHash8(targetDocument, hash) { +function documentContainsStyleHash7(targetDocument, hash) { if (!targetDocument.head) { return false; } for (const style of targetDocument.head.querySelectorAll( - `style[${STYLE_HASH_ATTRIBUTE8}]` + `style[${STYLE_HASH_ATTRIBUTE7}]` )) { - if (style.getAttribute(STYLE_HASH_ATTRIBUTE8) === hash) { + if (style.getAttribute(STYLE_HASH_ATTRIBUTE7) === hash) { return true; } } return false; } -function injectStyle8(targetDocument, hash, css) { +function injectStyle7(targetDocument, hash, css) { if (!targetDocument.head) { return; } - const runtime = getRuntime8(); + const runtime = getRuntime7(); let injectedStyles = runtime.injectedStyles.get(targetDocument); if (!injectedStyles) { injectedStyles = /* @__PURE__ */ new Set(); @@ -9599,24 +9534,24 @@ function injectStyle8(targetDocument, hash, css) { if (injectedStyles.has(hash)) { return; } - if (documentContainsStyleHash8(targetDocument, hash)) { + if (documentContainsStyleHash7(targetDocument, hash)) { injectedStyles.add(hash); return; } const style = targetDocument.createElement("style"); - style.setAttribute(STYLE_HASH_ATTRIBUTE8, hash); + style.setAttribute(STYLE_HASH_ATTRIBUTE7, hash); style.appendChild(targetDocument.createTextNode(css)); targetDocument.head.appendChild(style); injectedStyles.add(hash); } -function registerDocument8(targetDocument) { - const runtime = getRuntime8(); +function registerDocument7(targetDocument) { + const runtime = getRuntime7(); runtime.documents.set( targetDocument, (runtime.documents.get(targetDocument) ?? 0) + 1 ); for (const [hash, css] of runtime.styles) { - injectStyle8(targetDocument, hash, css); + injectStyle7(targetDocument, hash, css); } return () => { const count = runtime.documents.get(targetDocument); @@ -9630,24 +9565,24 @@ function registerDocument8(targetDocument) { runtime.documents.set(targetDocument, count - 1); }; } -function registerStyle8(hash, css) { - const runtime = getRuntime8(); +function registerStyle7(hash, css) { + const runtime = getRuntime7(); runtime.styles.set(hash, css); for (const targetDocument of runtime.documents.keys()) { - injectStyle8(targetDocument, hash, css); + injectStyle7(targetDocument, hash, css); } } if (typeof process === "undefined" || true) { - registerStyle8("19fcc06039", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}'); + registerStyle7("19fcc06039", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}'); } -var style_default7 = { "positioner": "_480b748dd3510e64__positioner", "popup": "_50096b232db7709d__popup" }; +var style_default6 = { "positioner": "_480b748dd3510e64__positioner", "popup": "_50096b232db7709d__popup" }; var POPUP_COLOR = { background: "#1e1e1e" }; -var Popup = (0, import_element19.forwardRef)(function TooltipPopup3({ portal, positioner, children, className, ...props }, ref) { +var Popup = (0, import_element18.forwardRef)(function TooltipPopup3({ portal, positioner, children, className, ...props }, ref) { const popupContent = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ThemeProvider, { color: POPUP_COLOR, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)( index_parts_exports.Popup, { ref, - className: clsx_default(style_default7.popup, className), + className: clsx_default(style_default6.popup, className), ...props, children } @@ -9661,9 +9596,9 @@ var Popup = (0, import_element19.forwardRef)(function TooltipPopup3({ portal, po }); // packages/ui/build-module/tooltip/trigger.mjs -var import_element20 = __toESM(require_element(), 1); +var import_element19 = __toESM(require_element(), 1); var import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1); -var Trigger = (0, import_element20.forwardRef)( +var Trigger = (0, import_element19.forwardRef)( function TooltipTrigger3(props, ref) { return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(index_parts_exports.Trigger, { ref, ...props }); } @@ -9683,13 +9618,13 @@ function Root(props) { } // packages/ui/build-module/utils/keyboard-shortcut.mjs -var import_element22 = __toESM(require_element(), 1); +var import_element21 = __toESM(require_element(), 1); var import_i18n3 = __toESM(require_i18n(), 1); // packages/ui/build-module/visually-hidden/visually-hidden.mjs -var import_element21 = __toESM(require_element(), 1); -var STYLE_HASH_ATTRIBUTE9 = "data-wp-hash"; -function getRuntime9() { +var import_element20 = __toESM(require_element(), 1); +var STYLE_HASH_ATTRIBUTE8 = "data-wp-hash"; +function getRuntime8() { const globalScope = globalThis; if (globalScope.__wpStyleRuntime) { return globalScope.__wpStyleRuntime; @@ -9700,28 +9635,28 @@ function getRuntime9() { injectedStyles: /* @__PURE__ */ new WeakMap() }; if (typeof document !== "undefined") { - registerDocument9(document); + registerDocument8(document); } return globalScope.__wpStyleRuntime; } -function documentContainsStyleHash9(targetDocument, hash) { +function documentContainsStyleHash8(targetDocument, hash) { if (!targetDocument.head) { return false; } for (const style of targetDocument.head.querySelectorAll( - `style[${STYLE_HASH_ATTRIBUTE9}]` + `style[${STYLE_HASH_ATTRIBUTE8}]` )) { - if (style.getAttribute(STYLE_HASH_ATTRIBUTE9) === hash) { + if (style.getAttribute(STYLE_HASH_ATTRIBUTE8) === hash) { return true; } } return false; } -function injectStyle9(targetDocument, hash, css) { +function injectStyle8(targetDocument, hash, css) { if (!targetDocument.head) { return; } - const runtime = getRuntime9(); + const runtime = getRuntime8(); let injectedStyles = runtime.injectedStyles.get(targetDocument); if (!injectedStyles) { injectedStyles = /* @__PURE__ */ new Set(); @@ -9730,24 +9665,24 @@ function injectStyle9(targetDocument, hash, css) { if (injectedStyles.has(hash)) { return; } - if (documentContainsStyleHash9(targetDocument, hash)) { + if (documentContainsStyleHash8(targetDocument, hash)) { injectedStyles.add(hash); return; } const style = targetDocument.createElement("style"); - style.setAttribute(STYLE_HASH_ATTRIBUTE9, hash); + style.setAttribute(STYLE_HASH_ATTRIBUTE8, hash); style.appendChild(targetDocument.createTextNode(css)); targetDocument.head.appendChild(style); injectedStyles.add(hash); } -function registerDocument9(targetDocument) { - const runtime = getRuntime9(); +function registerDocument8(targetDocument) { + const runtime = getRuntime8(); runtime.documents.set( targetDocument, (runtime.documents.get(targetDocument) ?? 0) + 1 ); for (const [hash, css] of runtime.styles) { - injectStyle9(targetDocument, hash, css); + injectStyle8(targetDocument, hash, css); } return () => { const count = runtime.documents.get(targetDocument); @@ -9761,24 +9696,24 @@ function registerDocument9(targetDocument) { runtime.documents.set(targetDocument, count - 1); }; } -function registerStyle9(hash, css) { - const runtime = getRuntime9(); +function registerStyle8(hash, css) { + const runtime = getRuntime8(); runtime.styles.set(hash, css); for (const targetDocument of runtime.documents.keys()) { - injectStyle9(targetDocument, hash, css); + injectStyle8(targetDocument, hash, css); } } if (typeof process === "undefined" || true) { - registerStyle9("fa606a57ae", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.f37b9e2e191ebd66__visually-hidden{word-wrap:normal;border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-break:normal}}}"); + registerStyle8("fa606a57ae", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.f37b9e2e191ebd66__visually-hidden{word-wrap:normal;border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-break:normal}}}"); } -var style_default8 = { "visually-hidden": "f37b9e2e191ebd66__visually-hidden" }; -var VisuallyHidden = (0, import_element21.forwardRef)( +var style_default7 = { "visually-hidden": "f37b9e2e191ebd66__visually-hidden" }; +var VisuallyHidden = (0, import_element20.forwardRef)( function VisuallyHidden2({ render, ...restProps }, ref) { const element = useRender({ render, ref, props: mergeProps( - { className: style_default8["visually-hidden"] }, + { className: style_default7["visually-hidden"] }, restProps, { // @ts-expect-error Arbitrary data-* attributes aren't indexable on the typed div props. Kept hardcoded so consumers can't change or remove it. @@ -9797,7 +9732,7 @@ function useKeyboardShortcutProps({ "aria-keyshortcuts": ariaKeyShortcuts, shortcut }) { - const generatedDescriptionId = (0, import_element22.useId)(); + const generatedDescriptionId = (0, import_element21.useId)(); const descriptionId = shortcut ? generatedDescriptionId : void 0; const describedBy = [ariaDescribedBy, descriptionId].filter(Boolean).join(" "); return { @@ -9808,16 +9743,13 @@ function useKeyboardShortcutProps({ } }; } -function KeyboardShortcutDescription({ - descriptionId, - shortcut -}) { +var KeyboardShortcutDescription = (0, import_element21.forwardRef)(function KeyboardShortcutDescription2({ descriptionId, shortcut }, ref) { return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)( VisuallyHidden, { id: descriptionId, "aria-hidden": "true", - render: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", {}), + render: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { ref }), children: (0, import_i18n3.sprintf)( /* translators: %s: keyboard shortcut. */ (0, import_i18n3.__)("Keyboard shortcut: %s"), @@ -9825,18 +9757,15 @@ function KeyboardShortcutDescription({ ) } ); -} -function KeyboardShortcutDisplay({ - className, - shortcut -}) { - return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { "aria-hidden": "true", className, dir: "ltr", children: shortcut.displayShortcut }); -} +}); +var KeyboardShortcutDisplay = (0, import_element21.forwardRef)(function KeyboardShortcutDisplay2({ className, shortcut }, ref) { + return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { ref, "aria-hidden": "true", className, dir: "ltr", children: shortcut.displayShortcut }); +}); // packages/ui/build-module/icon-button/icon-button.mjs var import_jsx_runtime28 = __toESM(require_jsx_runtime(), 1); -var STYLE_HASH_ATTRIBUTE10 = "data-wp-hash"; -function getRuntime10() { +var STYLE_HASH_ATTRIBUTE9 = "data-wp-hash"; +function getRuntime9() { const globalScope = globalThis; if (globalScope.__wpStyleRuntime) { return globalScope.__wpStyleRuntime; @@ -9847,28 +9776,28 @@ function getRuntime10() { injectedStyles: /* @__PURE__ */ new WeakMap() }; if (typeof document !== "undefined") { - registerDocument10(document); + registerDocument9(document); } return globalScope.__wpStyleRuntime; } -function documentContainsStyleHash10(targetDocument, hash) { +function documentContainsStyleHash9(targetDocument, hash) { if (!targetDocument.head) { return false; } for (const style of targetDocument.head.querySelectorAll( - `style[${STYLE_HASH_ATTRIBUTE10}]` + `style[${STYLE_HASH_ATTRIBUTE9}]` )) { - if (style.getAttribute(STYLE_HASH_ATTRIBUTE10) === hash) { + if (style.getAttribute(STYLE_HASH_ATTRIBUTE9) === hash) { return true; } } return false; } -function injectStyle10(targetDocument, hash, css) { +function injectStyle9(targetDocument, hash, css) { if (!targetDocument.head) { return; } - const runtime = getRuntime10(); + const runtime = getRuntime9(); let injectedStyles = runtime.injectedStyles.get(targetDocument); if (!injectedStyles) { injectedStyles = /* @__PURE__ */ new Set(); @@ -9877,24 +9806,24 @@ function injectStyle10(targetDocument, hash, css) { if (injectedStyles.has(hash)) { return; } - if (documentContainsStyleHash10(targetDocument, hash)) { + if (documentContainsStyleHash9(targetDocument, hash)) { injectedStyles.add(hash); return; } const style = targetDocument.createElement("style"); - style.setAttribute(STYLE_HASH_ATTRIBUTE10, hash); + style.setAttribute(STYLE_HASH_ATTRIBUTE9, hash); style.appendChild(targetDocument.createTextNode(css)); targetDocument.head.appendChild(style); injectedStyles.add(hash); } -function registerDocument10(targetDocument) { - const runtime = getRuntime10(); +function registerDocument9(targetDocument) { + const runtime = getRuntime9(); runtime.documents.set( targetDocument, (runtime.documents.get(targetDocument) ?? 0) + 1 ); for (const [hash, css] of runtime.styles) { - injectStyle10(targetDocument, hash, css); + injectStyle9(targetDocument, hash, css); } return () => { const count = runtime.documents.get(targetDocument); @@ -9908,18 +9837,18 @@ function registerDocument10(targetDocument) { runtime.documents.set(targetDocument, count - 1); }; } -function registerStyle10(hash, css) { - const runtime = getRuntime10(); +function registerStyle9(hash, css) { + const runtime = getRuntime9(); runtime.styles.set(hash, css); for (const targetDocument of runtime.documents.keys()) { - injectStyle10(targetDocument, hash, css); + injectStyle9(targetDocument, hash, css); } } if (typeof process === "undefined" || true) { - registerStyle10("c5cdafb1bc", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer compositions{._28cfdc260e755391__icon-button{--wp-ui-button-aspect-ratio:1;--wp-ui-button-padding-inline:0px;--wp-ui-button-min-width:unset}.f1c70d719989a85a__icon{margin:-1px}}}"); + registerStyle9("c5cdafb1bc", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer compositions{._28cfdc260e755391__icon-button{--wp-ui-button-aspect-ratio:1;--wp-ui-button-padding-inline:0px;--wp-ui-button-min-width:unset}.f1c70d719989a85a__icon{margin:-1px}}}"); } -var style_default9 = { "icon-button": "_28cfdc260e755391__icon-button", "icon": "f1c70d719989a85a__icon" }; -var IconButton = (0, import_element23.forwardRef)( +var style_default8 = { "icon-button": "_28cfdc260e755391__icon-button", "icon": "f1c70d719989a85a__icon" }; +var IconButton = (0, import_element22.forwardRef)( function IconButton2({ label, className, @@ -9935,7 +9864,7 @@ var IconButton = (0, import_element23.forwardRef)( "aria-keyshortcuts": ariaKeyShortcuts, ...restProps }, ref) { - const classes = clsx_default(style_default9["icon-button"], className); + const classes = clsx_default(style_default8["icon-button"], className); const { descriptionId, targetProps } = useKeyboardShortcutProps({ "aria-describedby": ariaDescribedBy, "aria-keyshortcuts": ariaKeyShortcuts, @@ -9960,7 +9889,7 @@ var IconButton = (0, import_element23.forwardRef)( ), className: classes, children: [ - /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Icon, { icon, size: 24, className: style_default9.icon }), + /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Icon, { icon, size: 24, className: style_default8.icon }), shortcut && descriptionId && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)( KeyboardShortcutDescription, { @@ -9982,6 +9911,117 @@ var IconButton = (0, import_element23.forwardRef)( } ); +// packages/ui/build-module/stack/stack.mjs +var import_element23 = __toESM(require_element(), 1); +var STYLE_HASH_ATTRIBUTE10 = "data-wp-hash"; +function getRuntime10() { + const globalScope = globalThis; + if (globalScope.__wpStyleRuntime) { + return globalScope.__wpStyleRuntime; + } + globalScope.__wpStyleRuntime = { + documents: /* @__PURE__ */ new Map(), + styles: /* @__PURE__ */ new Map(), + injectedStyles: /* @__PURE__ */ new WeakMap() + }; + if (typeof document !== "undefined") { + registerDocument10(document); + } + return globalScope.__wpStyleRuntime; +} +function documentContainsStyleHash10(targetDocument, hash) { + if (!targetDocument.head) { + return false; + } + for (const style of targetDocument.head.querySelectorAll( + `style[${STYLE_HASH_ATTRIBUTE10}]` + )) { + if (style.getAttribute(STYLE_HASH_ATTRIBUTE10) === hash) { + return true; + } + } + return false; +} +function injectStyle10(targetDocument, hash, css) { + if (!targetDocument.head) { + return; + } + const runtime = getRuntime10(); + let injectedStyles = runtime.injectedStyles.get(targetDocument); + if (!injectedStyles) { + injectedStyles = /* @__PURE__ */ new Set(); + runtime.injectedStyles.set(targetDocument, injectedStyles); + } + if (injectedStyles.has(hash)) { + return; + } + if (documentContainsStyleHash10(targetDocument, hash)) { + injectedStyles.add(hash); + return; + } + const style = targetDocument.createElement("style"); + style.setAttribute(STYLE_HASH_ATTRIBUTE10, hash); + style.appendChild(targetDocument.createTextNode(css)); + targetDocument.head.appendChild(style); + injectedStyles.add(hash); +} +function registerDocument10(targetDocument) { + const runtime = getRuntime10(); + runtime.documents.set( + targetDocument, + (runtime.documents.get(targetDocument) ?? 0) + 1 + ); + for (const [hash, css] of runtime.styles) { + injectStyle10(targetDocument, hash, css); + } + return () => { + const count = runtime.documents.get(targetDocument); + if (count === void 0) { + return; + } + if (count <= 1) { + runtime.documents.delete(targetDocument); + return; + } + runtime.documents.set(targetDocument, count - 1); + }; +} +function registerStyle10(hash, css) { + const runtime = getRuntime10(); + runtime.styles.set(hash, css); + for (const targetDocument of runtime.documents.keys()) { + injectStyle10(targetDocument, hash, css); + } +} +if (typeof process === "undefined" || true) { + registerStyle10("32aba35fe1", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._19ce0419607e1896__stack{display:flex}}}"); +} +var style_default9 = { "stack": "_19ce0419607e1896__stack" }; +var gapTokens = { + xs: "var(--wpds-dimension-gap-xs, 4px)", + sm: "var(--wpds-dimension-gap-sm, 8px)", + md: "var(--wpds-dimension-gap-md, 12px)", + lg: "var(--wpds-dimension-gap-lg, 16px)", + xl: "var(--wpds-dimension-gap-xl, 24px)", + "2xl": "var(--wpds-dimension-gap-2xl, 32px)", + "3xl": "var(--wpds-dimension-gap-3xl, 40px)" +}; +var Stack = (0, import_element23.forwardRef)(function Stack2({ direction, gap, align, justify, wrap, render, ...props }, ref) { + const style = { + gap: gap && gapTokens[gap], + alignItems: align, + justifyContent: justify, + flexDirection: direction, + flexWrap: wrap + }; + const element = useRender({ + render, + ref, + props: mergeProps(props, { style, className: style_default9.stack }) + }); + return element; +}); + // packages/ui/build-module/link/link.mjs var import_element24 = __toESM(require_element(), 1); var import_i18n4 = __toESM(require_i18n(), 1); @@ -10071,7 +10111,7 @@ if (typeof process === "undefined" || true) { } var resets_default3 = { "box-sizing": "_336cd3e4e743482f__box-sizing" }; if (typeof process === "undefined" || true) { - registerStyle11("2ffedd8246", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._64de9947bf305b7a__outset-ring--focus-within-visible:focus-within:has(:focus-visible),.af79fb116edb0dd7__outset-ring--focus:focus,.dfcfdc28396e5d98__outset-ring--focus-visible:focus-visible,.e5cd9ee879f6403a__outset-ring--focus-within:focus-within,:focus-visible ._81935a08e952f267__outset-ring--focus-parent-visible{--focus-color:var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color);outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within,.abc777e9713fa711__outset-ring--focus-except-active:focus{outline:none}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within:not(:has(:active)),.abc777e9713fa711__outset-ring--focus-except-active:focus:not(:active){--focus-color:var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color);outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}}}"); + registerStyle11("96553466c8", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._64de9947bf305b7a__outset-ring--focus-within-visible:focus-within:has(:focus-visible),.af79fb116edb0dd7__outset-ring--focus:focus,.dfcfdc28396e5d98__outset-ring--focus-visible:focus-visible,.e5cd9ee879f6403a__outset-ring--focus-within:focus-within,:focus-visible ._81935a08e952f267__outset-ring--focus-parent-visible{--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within,.abc777e9713fa711__outset-ring--focus-except-active:focus{outline:none}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within:not(:has(:active)),.abc777e9713fa711__outset-ring--focus-except-active:focus:not(:active){--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}}}"); } var focus_module_default2 = { "outset-ring--focus": "af79fb116edb0dd7__outset-ring--focus", "outset-ring--focus-visible": "dfcfdc28396e5d98__outset-ring--focus-visible", "outset-ring--focus-within": "e5cd9ee879f6403a__outset-ring--focus-within", "outset-ring--focus-within-visible": "_64de9947bf305b7a__outset-ring--focus-within-visible", "outset-ring--focus-parent-visible": "_81935a08e952f267__outset-ring--focus-parent-visible", "outset-ring--focus-except-active": "abc777e9713fa711__outset-ring--focus-except-active", "outset-ring--focus-within-except-active": "_3c9f5ee9fc9c136d__outset-ring--focus-within-except-active" }; if (typeof process === "undefined" || true) { @@ -10944,14 +10984,159 @@ var NavigableRegion = (0, import_element32.forwardRef)( NavigableRegion.displayName = "NavigableRegion"; var navigable_region_default = NavigableRegion; +// packages/admin-ui/build-module/navigation/index.mjs +var import_i18n6 = __toESM(require_i18n(), 1); +var import_jsx_runtime37 = __toESM(require_jsx_runtime(), 1); +var STYLE_HASH_ATTRIBUTE19 = "data-wp-hash"; +function getRuntime19() { + const globalScope = globalThis; + if (globalScope.__wpStyleRuntime) { + return globalScope.__wpStyleRuntime; + } + globalScope.__wpStyleRuntime = { + documents: /* @__PURE__ */ new Map(), + styles: /* @__PURE__ */ new Map(), + injectedStyles: /* @__PURE__ */ new WeakMap() + }; + if (typeof document !== "undefined") { + registerDocument19(document); + } + return globalScope.__wpStyleRuntime; +} +function documentContainsStyleHash19(targetDocument, hash) { + if (!targetDocument.head) { + return false; + } + for (const style of targetDocument.head.querySelectorAll( + `style[${STYLE_HASH_ATTRIBUTE19}]` + )) { + if (style.getAttribute(STYLE_HASH_ATTRIBUTE19) === hash) { + return true; + } + } + return false; +} +function injectStyle19(targetDocument, hash, css) { + if (!targetDocument.head) { + return; + } + const runtime = getRuntime19(); + let injectedStyles = runtime.injectedStyles.get(targetDocument); + if (!injectedStyles) { + injectedStyles = /* @__PURE__ */ new Set(); + runtime.injectedStyles.set(targetDocument, injectedStyles); + } + if (injectedStyles.has(hash)) { + return; + } + if (documentContainsStyleHash19(targetDocument, hash)) { + injectedStyles.add(hash); + return; + } + const style = targetDocument.createElement("style"); + style.setAttribute(STYLE_HASH_ATTRIBUTE19, hash); + style.appendChild(targetDocument.createTextNode(css)); + targetDocument.head.appendChild(style); + injectedStyles.add(hash); +} +function registerDocument19(targetDocument) { + const runtime = getRuntime19(); + runtime.documents.set( + targetDocument, + (runtime.documents.get(targetDocument) ?? 0) + 1 + ); + for (const [hash, css] of runtime.styles) { + injectStyle19(targetDocument, hash, css); + } + return () => { + const count = runtime.documents.get(targetDocument); + if (count === void 0) { + return; + } + if (count <= 1) { + runtime.documents.delete(targetDocument); + return; + } + runtime.documents.set(targetDocument, count - 1); + }; +} +function registerStyle19(hash, css) { + const runtime = getRuntime19(); + runtime.styles.set(hash, css); + for (const targetDocument of runtime.documents.keys()) { + injectStyle19(targetDocument, hash, css); + } +} +if (typeof process === "undefined" || true) { + registerStyle19("72ef022400", ".bfb5a2dd8cceebd3__list{--focus-ring-size:calc(var(--wpds-border-width-focus, var(--wp-admin-border-width-focus, 2px))*2);list-style:none;margin:calc(var(--focus-ring-size)*-1);overflow-x:auto;padding:var(--focus-ring-size);scroll-padding:var(--focus-ring-size)}.a4759b4cb2c8bd92__li{flex-shrink:0}._07da506d3f2d9afe__item{align-items:center;color:var(--wpds-color-foreground-interactive-neutral-weak,#707070);display:flex;font-weight:var(--wpds-typography-font-weight-default,400);min-block-size:44px;min-inline-size:44px;text-decoration:none}._07da506d3f2d9afe__item:hover,._07da506d3f2d9afe__item[aria-current=page]{color:var(--wpds-color-foreground-interactive-neutral-weak-active,#1e1e1e)}._07da506d3f2d9afe__item[aria-current=page]{font-weight:var(--wpds-typography-font-weight-emphasis,600)}"); +} +var style_default18 = { "list": "bfb5a2dd8cceebd3__list", "li": "a4759b4cb2c8bd92__li", "item": "_07da506d3f2d9afe__item" }; +var Navigation = ({ + items, + currentHref, + ariaLabel = (0, import_i18n6.__)("Sections"), + linkComponent, + className +}) => { + if (!items.length) { + return null; + } + const LinkComponent = linkComponent ?? "a"; + if (true) { + const invalidItem = items.find( + (item) => typeof item.href !== "string" + ); + if (invalidItem) { + throw new Error( + `Navigation: item "${invalidItem.label}" is missing an \`href\` prop.` + ); + } + const duplicate = items.find( + (item, index2) => items.findIndex((other) => other.href === item.href) !== index2 + ); + if (duplicate) { + throw new Error( + `Navigation: duplicate \`href\` "${duplicate.href}". Each item must have a unique \`href\` so a single item receives \`aria-current="page"\`.` + ); + } + } + return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("nav", { "aria-label": ariaLabel, className, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)( + Stack, + { + render: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("ul", { role: "list" }), + direction: "row", + align: "center", + gap: "md", + className: style_default18.list, + children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("li", { className: style_default18.li, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)( + Text, + { + variant: "body-md", + className: style_default18.item, + render: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)( + Link, + { + variant: "unstyled", + "aria-current": item.href === currentHref ? "page" : void 0, + render: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(LinkComponent, { href: item.href }) + } + ), + children: item.label + } + ) }, item.href)) + } + ) }); +}; +var navigation_default = Navigation; + // packages/admin-ui/build-module/page/sidebar-toggle-slot.mjs var import_components = __toESM(require_components(), 1); var { Fill: SidebarToggleFill, Slot: SidebarToggleSlot } = (0, import_components.createSlotFill)("SidebarToggle"); // packages/admin-ui/build-module/page/header.mjs -var import_jsx_runtime37 = __toESM(require_jsx_runtime(), 1); -var STYLE_HASH_ATTRIBUTE19 = "data-wp-hash"; -function getRuntime19() { +var import_jsx_runtime38 = __toESM(require_jsx_runtime(), 1); +var STYLE_HASH_ATTRIBUTE20 = "data-wp-hash"; +function getRuntime20() { const globalScope = globalThis; if (globalScope.__wpStyleRuntime) { return globalScope.__wpStyleRuntime; @@ -10962,28 +11147,28 @@ function getRuntime19() { injectedStyles: /* @__PURE__ */ new WeakMap() }; if (typeof document !== "undefined") { - registerDocument19(document); + registerDocument20(document); } return globalScope.__wpStyleRuntime; } -function documentContainsStyleHash19(targetDocument, hash) { +function documentContainsStyleHash20(targetDocument, hash) { if (!targetDocument.head) { return false; } for (const style of targetDocument.head.querySelectorAll( - `style[${STYLE_HASH_ATTRIBUTE19}]` + `style[${STYLE_HASH_ATTRIBUTE20}]` )) { - if (style.getAttribute(STYLE_HASH_ATTRIBUTE19) === hash) { + if (style.getAttribute(STYLE_HASH_ATTRIBUTE20) === hash) { return true; } } return false; } -function injectStyle19(targetDocument, hash, css) { +function injectStyle20(targetDocument, hash, css) { if (!targetDocument.head) { return; } - const runtime = getRuntime19(); + const runtime = getRuntime20(); let injectedStyles = runtime.injectedStyles.get(targetDocument); if (!injectedStyles) { injectedStyles = /* @__PURE__ */ new Set(); @@ -10992,24 +11177,24 @@ function injectStyle19(targetDocument, hash, css) { if (injectedStyles.has(hash)) { return; } - if (documentContainsStyleHash19(targetDocument, hash)) { + if (documentContainsStyleHash20(targetDocument, hash)) { injectedStyles.add(hash); return; } const style = targetDocument.createElement("style"); - style.setAttribute(STYLE_HASH_ATTRIBUTE19, hash); + style.setAttribute(STYLE_HASH_ATTRIBUTE20, hash); style.appendChild(targetDocument.createTextNode(css)); targetDocument.head.appendChild(style); injectedStyles.add(hash); } -function registerDocument19(targetDocument) { - const runtime = getRuntime19(); +function registerDocument20(targetDocument) { + const runtime = getRuntime20(); runtime.documents.set( targetDocument, (runtime.documents.get(targetDocument) ?? 0) + 1 ); for (const [hash, css] of runtime.styles) { - injectStyle19(targetDocument, hash, css); + injectStyle20(targetDocument, hash, css); } return () => { const count = runtime.documents.get(targetDocument); @@ -11023,17 +11208,17 @@ function registerDocument19(targetDocument) { runtime.documents.set(targetDocument, count - 1); }; } -function registerStyle19(hash, css) { - const runtime = getRuntime19(); +function registerStyle20(hash, css) { + const runtime = getRuntime20(); runtime.styles.set(hash, css); for (const targetDocument of runtime.documents.keys()) { - injectStyle19(targetDocument, hash, css); + injectStyle20(targetDocument, hash, css); } } if (typeof process === "undefined" || true) { - registerStyle19("ddd9aab364", "._956b6df0898efed0__page{text-wrap:pretty;background-color:var(--wpds-color-background-surface-neutral,#fcfcfc);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);display:flex;flex-flow:column;height:100%;position:relative;z-index:1}._0625b55e82a0d93d__header{background:var(--wpds-color-background-surface-neutral-strong,#fff);border-block-end:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral-weak,#f0f0f0);inset-block-start:0;padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px);position:sticky;z-index:1}.a43c44d5ae28b2e8__header-content{min-height:var(--wpds-dimension-size-md,32px)}.b7cb5b9daf3a3b25__header-actions{flex-shrink:0}._8113be94e7caf73c__header-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._9a776c7f70996f61__header-visual{display:grid;flex-shrink:0;grid-template-columns:1fr;grid-template-rows:1fr;height:var(--wpds-dimension-size-sm,24px);width:var(--wpds-dimension-size-sm,24px);>*{grid-column:1/-1;grid-row:1/-1;max-height:100%;max-width:100%}}.d5e0920cd15d35bc__sidebar-toggle-slot:empty{display:none}._60fea2f6bf5319cd__header-subtitle{color:var(--wpds-color-foreground-content-neutral-weak,#707070);padding-block-end:var(--wpds-dimension-padding-xs,4px)}.be5e57d029ec4036__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;&._128806d0b26e3a50__has-padding{padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px)}}"); + registerStyle20("1f3750277d", "._956b6df0898efed0__page{text-wrap:pretty;background-color:var(--wpds-color-background-surface-neutral,#fcfcfc);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);display:flex;flex-flow:column;height:100%;position:relative;z-index:1}._0625b55e82a0d93d__header{background:var(--wpds-color-background-surface-neutral-strong,#fff);border-block-end:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral-weak,#f0f0f0);inset-block-start:0;padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px);position:sticky;z-index:1}.a43c44d5ae28b2e8__header-content{min-height:var(--wpds-dimension-size-md,32px)}.b7cb5b9daf3a3b25__header-actions{flex-shrink:0}._8bcd33103b451f30__header-lockup{min-width:0}._8113be94e7caf73c__header-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._9a776c7f70996f61__header-visual{display:grid;flex-shrink:0;grid-template-columns:1fr;grid-template-rows:1fr;height:var(--wpds-dimension-size-sm,24px);width:var(--wpds-dimension-size-sm,24px);>*{grid-column:1/-1;grid-row:1/-1;max-height:100%;max-width:100%}}.d5e0920cd15d35bc__sidebar-toggle-slot:empty{display:none}._60fea2f6bf5319cd__header-subtitle{color:var(--wpds-color-foreground-content-neutral-weak,#707070);padding-block-end:var(--wpds-dimension-padding-xs,4px)}._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation,._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation ._60fea2f6bf5319cd__header-subtitle{padding-block-end:0}._673c99dcbfb58211__header-navigation{margin-block-start:var(--wpds-dimension-gap-md,12px)}.be5e57d029ec4036__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;&._128806d0b26e3a50__has-padding{padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px)}}"); } -var style_default18 = { "page": "_956b6df0898efed0__page", "header": "_0625b55e82a0d93d__header", "header-content": "a43c44d5ae28b2e8__header-content", "header-actions": "b7cb5b9daf3a3b25__header-actions", "header-title": "_8113be94e7caf73c__header-title", "header-visual": "_9a776c7f70996f61__header-visual", "sidebar-toggle-slot": "d5e0920cd15d35bc__sidebar-toggle-slot", "header-subtitle": "_60fea2f6bf5319cd__header-subtitle", "content": "be5e57d029ec4036__content", "has-padding": "_128806d0b26e3a50__has-padding" }; +var style_default19 = { "page": "_956b6df0898efed0__page", "header": "_0625b55e82a0d93d__header", "header-content": "a43c44d5ae28b2e8__header-content", "header-actions": "b7cb5b9daf3a3b25__header-actions", "header-lockup": "_8bcd33103b451f30__header-lockup", "header-title": "_8113be94e7caf73c__header-title", "header-visual": "_9a776c7f70996f61__header-visual", "sidebar-toggle-slot": "d5e0920cd15d35bc__sidebar-toggle-slot", "header-subtitle": "_60fea2f6bf5319cd__header-subtitle", "has-navigation": "_4b0f17e503d11619__has-navigation", "header-navigation": "_673c99dcbfb58211__header-navigation", "content": "be5e57d029ec4036__content", "has-padding": "_128806d0b26e3a50__has-padding" }; function Header({ headingLevel = 1, breadcrumbs, @@ -11042,75 +11227,106 @@ function Header({ title, subTitle, actions, + navigation, + components, showSidebarToggle = true }) { const HeadingTag = `h${headingLevel}`; - return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(Stack, { direction: "column", className: style_default18.header, children: [ - /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)( - Stack, - { - className: style_default18["header-content"], - direction: "row", - gap: "sm", - justify: "space-between", - children: [ - /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(Stack, { direction: "row", gap: "sm", align: "center", justify: "start", children: [ - showSidebarToggle && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)( - SidebarToggleSlot, - { - bubblesVirtually: true, - className: style_default18["sidebar-toggle-slot"] - } - ), - visual && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)( - "div", - { - className: style_default18["header-visual"], - "aria-hidden": "true", - children: visual - } - ), - title && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)( - Text, - { - className: style_default18["header-title"], - render: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(HeadingTag, {}), - variant: "heading-lg", - children: title - } - ), - breadcrumbs, - badges - ] }), - actions && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)( - Stack, - { - align: "center", - className: style_default18["header-actions"], - direction: "row", - gap: "sm", - children: actions - } - ) - ] - } - ), - subTitle && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)( - Text, - { - render: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", {}), - variant: "body-md", - className: style_default18["header-subtitle"], - children: subTitle - } - ) - ] }); + const hasNavigation = !!navigation?.items?.length; + return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)( + Stack, + { + direction: "column", + className: clsx_default( + style_default19.header, + hasNavigation && style_default19["has-navigation"] + ), + children: [ + /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)( + Stack, + { + className: style_default19["header-content"], + direction: "row", + gap: "sm", + justify: "space-between", + children: [ + /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)( + Stack, + { + direction: "row", + gap: "sm", + align: "center", + justify: "start", + className: style_default19["header-lockup"], + children: [ + showSidebarToggle && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)( + SidebarToggleSlot, + { + bubblesVirtually: true, + className: style_default19["sidebar-toggle-slot"] + } + ), + visual && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)( + "div", + { + className: style_default19["header-visual"], + "aria-hidden": "true", + children: visual + } + ), + title && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)( + Text, + { + className: style_default19["header-title"], + render: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(HeadingTag, {}), + variant: "heading-lg", + children: title + } + ), + breadcrumbs, + badges + ] + } + ), + actions && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)( + Stack, + { + align: "center", + className: style_default19["header-actions"], + direction: "row", + gap: "sm", + children: actions + } + ) + ] + } + ), + subTitle && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)( + Text, + { + render: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("p", {}), + variant: "body-md", + className: style_default19["header-subtitle"], + children: subTitle + } + ), + hasNavigation && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)( + navigation_default, + { + ...navigation, + linkComponent: components?.link, + className: style_default19["header-navigation"] + } + ) + ] + } + ); } // packages/admin-ui/build-module/page/index.mjs -var import_jsx_runtime38 = __toESM(require_jsx_runtime(), 1); -var STYLE_HASH_ATTRIBUTE20 = "data-wp-hash"; -function getRuntime20() { +var import_jsx_runtime39 = __toESM(require_jsx_runtime(), 1); +var STYLE_HASH_ATTRIBUTE21 = "data-wp-hash"; +function getRuntime21() { const globalScope = globalThis; if (globalScope.__wpStyleRuntime) { return globalScope.__wpStyleRuntime; @@ -11121,28 +11337,28 @@ function getRuntime20() { injectedStyles: /* @__PURE__ */ new WeakMap() }; if (typeof document !== "undefined") { - registerDocument20(document); + registerDocument21(document); } return globalScope.__wpStyleRuntime; } -function documentContainsStyleHash20(targetDocument, hash) { +function documentContainsStyleHash21(targetDocument, hash) { if (!targetDocument.head) { return false; } for (const style of targetDocument.head.querySelectorAll( - `style[${STYLE_HASH_ATTRIBUTE20}]` + `style[${STYLE_HASH_ATTRIBUTE21}]` )) { - if (style.getAttribute(STYLE_HASH_ATTRIBUTE20) === hash) { + if (style.getAttribute(STYLE_HASH_ATTRIBUTE21) === hash) { return true; } } return false; } -function injectStyle20(targetDocument, hash, css) { +function injectStyle21(targetDocument, hash, css) { if (!targetDocument.head) { return; } - const runtime = getRuntime20(); + const runtime = getRuntime21(); let injectedStyles = runtime.injectedStyles.get(targetDocument); if (!injectedStyles) { injectedStyles = /* @__PURE__ */ new Set(); @@ -11151,24 +11367,24 @@ function injectStyle20(targetDocument, hash, css) { if (injectedStyles.has(hash)) { return; } - if (documentContainsStyleHash20(targetDocument, hash)) { + if (documentContainsStyleHash21(targetDocument, hash)) { injectedStyles.add(hash); return; } const style = targetDocument.createElement("style"); - style.setAttribute(STYLE_HASH_ATTRIBUTE20, hash); + style.setAttribute(STYLE_HASH_ATTRIBUTE21, hash); style.appendChild(targetDocument.createTextNode(css)); targetDocument.head.appendChild(style); injectedStyles.add(hash); } -function registerDocument20(targetDocument) { - const runtime = getRuntime20(); +function registerDocument21(targetDocument) { + const runtime = getRuntime21(); runtime.documents.set( targetDocument, (runtime.documents.get(targetDocument) ?? 0) + 1 ); for (const [hash, css] of runtime.styles) { - injectStyle20(targetDocument, hash, css); + injectStyle21(targetDocument, hash, css); } return () => { const count = runtime.documents.get(targetDocument); @@ -11182,17 +11398,17 @@ function registerDocument20(targetDocument) { runtime.documents.set(targetDocument, count - 1); }; } -function registerStyle20(hash, css) { - const runtime = getRuntime20(); +function registerStyle21(hash, css) { + const runtime = getRuntime21(); runtime.styles.set(hash, css); for (const targetDocument of runtime.documents.keys()) { - injectStyle20(targetDocument, hash, css); + injectStyle21(targetDocument, hash, css); } } if (typeof process === "undefined" || true) { - registerStyle20("ddd9aab364", "._956b6df0898efed0__page{text-wrap:pretty;background-color:var(--wpds-color-background-surface-neutral,#fcfcfc);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);display:flex;flex-flow:column;height:100%;position:relative;z-index:1}._0625b55e82a0d93d__header{background:var(--wpds-color-background-surface-neutral-strong,#fff);border-block-end:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral-weak,#f0f0f0);inset-block-start:0;padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px);position:sticky;z-index:1}.a43c44d5ae28b2e8__header-content{min-height:var(--wpds-dimension-size-md,32px)}.b7cb5b9daf3a3b25__header-actions{flex-shrink:0}._8113be94e7caf73c__header-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._9a776c7f70996f61__header-visual{display:grid;flex-shrink:0;grid-template-columns:1fr;grid-template-rows:1fr;height:var(--wpds-dimension-size-sm,24px);width:var(--wpds-dimension-size-sm,24px);>*{grid-column:1/-1;grid-row:1/-1;max-height:100%;max-width:100%}}.d5e0920cd15d35bc__sidebar-toggle-slot:empty{display:none}._60fea2f6bf5319cd__header-subtitle{color:var(--wpds-color-foreground-content-neutral-weak,#707070);padding-block-end:var(--wpds-dimension-padding-xs,4px)}.be5e57d029ec4036__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;&._128806d0b26e3a50__has-padding{padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px)}}"); + registerStyle21("1f3750277d", "._956b6df0898efed0__page{text-wrap:pretty;background-color:var(--wpds-color-background-surface-neutral,#fcfcfc);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);display:flex;flex-flow:column;height:100%;position:relative;z-index:1}._0625b55e82a0d93d__header{background:var(--wpds-color-background-surface-neutral-strong,#fff);border-block-end:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral-weak,#f0f0f0);inset-block-start:0;padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px);position:sticky;z-index:1}.a43c44d5ae28b2e8__header-content{min-height:var(--wpds-dimension-size-md,32px)}.b7cb5b9daf3a3b25__header-actions{flex-shrink:0}._8bcd33103b451f30__header-lockup{min-width:0}._8113be94e7caf73c__header-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._9a776c7f70996f61__header-visual{display:grid;flex-shrink:0;grid-template-columns:1fr;grid-template-rows:1fr;height:var(--wpds-dimension-size-sm,24px);width:var(--wpds-dimension-size-sm,24px);>*{grid-column:1/-1;grid-row:1/-1;max-height:100%;max-width:100%}}.d5e0920cd15d35bc__sidebar-toggle-slot:empty{display:none}._60fea2f6bf5319cd__header-subtitle{color:var(--wpds-color-foreground-content-neutral-weak,#707070);padding-block-end:var(--wpds-dimension-padding-xs,4px)}._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation,._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation ._60fea2f6bf5319cd__header-subtitle{padding-block-end:0}._673c99dcbfb58211__header-navigation{margin-block-start:var(--wpds-dimension-gap-md,12px)}.be5e57d029ec4036__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;&._128806d0b26e3a50__has-padding{padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px)}}"); } -var style_default19 = { "page": "_956b6df0898efed0__page", "header": "_0625b55e82a0d93d__header", "header-content": "a43c44d5ae28b2e8__header-content", "header-actions": "b7cb5b9daf3a3b25__header-actions", "header-title": "_8113be94e7caf73c__header-title", "header-visual": "_9a776c7f70996f61__header-visual", "sidebar-toggle-slot": "d5e0920cd15d35bc__sidebar-toggle-slot", "header-subtitle": "_60fea2f6bf5319cd__header-subtitle", "content": "be5e57d029ec4036__content", "has-padding": "_128806d0b26e3a50__has-padding" }; +var style_default20 = { "page": "_956b6df0898efed0__page", "header": "_0625b55e82a0d93d__header", "header-content": "a43c44d5ae28b2e8__header-content", "header-actions": "b7cb5b9daf3a3b25__header-actions", "header-lockup": "_8bcd33103b451f30__header-lockup", "header-title": "_8113be94e7caf73c__header-title", "header-visual": "_9a776c7f70996f61__header-visual", "sidebar-toggle-slot": "d5e0920cd15d35bc__sidebar-toggle-slot", "header-subtitle": "_60fea2f6bf5319cd__header-subtitle", "has-navigation": "_4b0f17e503d11619__has-navigation", "header-navigation": "_673c99dcbfb58211__header-navigation", "content": "be5e57d029ec4036__content", "has-padding": "_128806d0b26e3a50__has-padding" }; function Page({ headingLevel, breadcrumbs, @@ -11203,14 +11419,16 @@ function Page({ children, className, actions, + navigation, + components, ariaLabel, hasPadding = false, showSidebarToggle = true }) { - const classes = clsx_default(style_default19.page, className); + const classes = clsx_default(style_default20.page, className); const effectiveAriaLabel = ariaLabel ?? (typeof title === "string" ? title : ""); - return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(navigable_region_default, { className: classes, ariaLabel: effectiveAriaLabel, children: [ - (title || breadcrumbs || badges || actions || visual) && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)( + return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(navigable_region_default, { className: classes, ariaLabel: effectiveAriaLabel, children: [ + (title || breadcrumbs || badges || actions || visual || !!navigation?.items?.length) && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)( Header, { headingLevel, @@ -11220,15 +11438,17 @@ function Page({ title, subTitle, actions, + navigation, + components, showSidebarToggle } ), - hasPadding ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)( + hasPadding ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)( "div", { className: clsx_default( - style_default19.content, - style_default19["has-padding"] + style_default20.content, + style_default20["has-padding"] ), children } @@ -11242,7 +11462,7 @@ var page_default = Page; var import_components4 = __toESM(require_components()); var import_data4 = __toESM(require_data()); var import_element36 = __toESM(require_element()); -var import_i18n9 = __toESM(require_i18n()); +var import_i18n10 = __toESM(require_i18n()); var import_core_data3 = __toESM(require_core_data()); import { privateApis as connectorsPrivateApis2 @@ -11268,7 +11488,7 @@ var import_components3 = __toESM(require_components()); var import_core_data2 = __toESM(require_core_data()); var import_data3 = __toESM(require_data()); var import_element35 = __toESM(require_element()); -var import_i18n8 = __toESM(require_i18n()); +var import_i18n9 = __toESM(require_i18n()); var import_notices2 = __toESM(require_notices()); var import_url = __toESM(require_url()); @@ -11276,7 +11496,7 @@ var import_url = __toESM(require_url()); var import_components2 = __toESM(require_components()); var import_element34 = __toESM(require_element()); var import_data2 = __toESM(require_data()); -var import_i18n7 = __toESM(require_i18n()); +var import_i18n8 = __toESM(require_i18n()); import { __experimentalRegisterConnector as registerConnector, __experimentalConnectorItem as ConnectorItem, @@ -11289,7 +11509,7 @@ import { var import_core_data = __toESM(require_core_data()); var import_data = __toESM(require_data()); var import_element33 = __toESM(require_element()); -var import_i18n6 = __toESM(require_i18n()); +var import_i18n7 = __toESM(require_i18n()); var import_notices = __toESM(require_notices()); function useConnectorPlugin({ file: pluginFileFromServer, @@ -11403,9 +11623,9 @@ function useConnectorPlugin({ ); const createConnectedNotice = () => { createSuccessNotice( - (0, import_i18n6.sprintf)( + (0, import_i18n7.sprintf)( /* translators: %s: Name of the connector (e.g. "OpenAI"). */ - (0, import_i18n6.__)("%s connected successfully."), + (0, import_i18n7.__)("%s connected successfully."), connectorName ), { @@ -11416,9 +11636,9 @@ function useConnectorPlugin({ }; const createDisconnectedNotice = () => { createSuccessNotice( - (0, import_i18n6.sprintf)( + (0, import_i18n7.sprintf)( /* translators: %s: Name of the connector (e.g. "OpenAI"). */ - (0, import_i18n6.__)("%s disconnected."), + (0, import_i18n7.__)("%s disconnected."), connectorName ), { @@ -11429,9 +11649,9 @@ function useConnectorPlugin({ }; const createDisconnectErrorNotice = () => { createErrorNotice( - (0, import_i18n6.sprintf)( + (0, import_i18n7.sprintf)( /* translators: %s: Name of the connector (e.g. "OpenAI"). */ - (0, import_i18n6.__)("Failed to disconnect %s."), + (0, import_i18n7.__)("Failed to disconnect %s."), connectorName ), { @@ -11456,9 +11676,9 @@ function useConnectorPlugin({ invalidateResolution("getEntityRecord", ["root", "site"]); setIsExpanded(true); createSuccessNotice( - (0, import_i18n6.sprintf)( + (0, import_i18n7.sprintf)( /* translators: %s: Name of the connector (e.g. "OpenAI"). */ - (0, import_i18n6.__)("Plugin for %s installed and activated successfully."), + (0, import_i18n7.__)("Plugin for %s installed and activated successfully."), connectorName ), { @@ -11468,9 +11688,9 @@ function useConnectorPlugin({ ); } catch { createErrorNotice( - (0, import_i18n6.sprintf)( + (0, import_i18n7.sprintf)( /* translators: %s: Name of the connector (e.g. "OpenAI"). */ - (0, import_i18n6.__)("Failed to install plugin for %s."), + (0, import_i18n7.__)("Failed to install plugin for %s."), connectorName ), { @@ -11501,9 +11721,9 @@ function useConnectorPlugin({ invalidateResolution("getEntityRecord", ["root", "site"]); setIsExpanded(true); createSuccessNotice( - (0, import_i18n6.sprintf)( + (0, import_i18n7.sprintf)( /* translators: %s: Name of the connector (e.g. "OpenAI"). */ - (0, import_i18n6.__)("Plugin for %s activated successfully."), + (0, import_i18n7.__)("Plugin for %s activated successfully."), connectorName ), { @@ -11513,9 +11733,9 @@ function useConnectorPlugin({ ); } catch { createErrorNotice( - (0, import_i18n6.sprintf)( + (0, import_i18n7.sprintf)( /* translators: %s: Name of the connector (e.g. "OpenAI"). */ - (0, import_i18n6.__)("Failed to activate plugin for %s."), + (0, import_i18n7.__)("Failed to activate plugin for %s."), connectorName ), { @@ -11544,23 +11764,23 @@ function useConnectorPlugin({ }; const getButtonLabel = () => { if (isBusy) { - return pluginStatus === "not-installed" ? (0, import_i18n6.__)("Installing\u2026") : (0, import_i18n6.__)("Activating\u2026"); + return pluginStatus === "not-installed" ? (0, import_i18n7.__)("Installing\u2026") : (0, import_i18n7.__)("Activating\u2026"); } if (isExpanded) { - return (0, import_i18n6.__)("Cancel"); + return (0, import_i18n7.__)("Cancel"); } if (isConnected) { - return (0, import_i18n6.__)("Edit"); + return (0, import_i18n7.__)("Edit"); } switch (pluginStatus) { case "checking": - return (0, import_i18n6.__)("Checking\u2026"); + return (0, import_i18n7.__)("Checking\u2026"); case "not-installed": - return (0, import_i18n6.__)("Install"); + return (0, import_i18n7.__)("Install"); case "inactive": - return (0, import_i18n6.__)("Activate"); + return (0, import_i18n7.__)("Activate"); case "active": - return (0, import_i18n6.__)("Set up"); + return (0, import_i18n7.__)("Set up"); } }; const saveApiKey = async (apiKey) => { @@ -11594,7 +11814,7 @@ function useConnectorPlugin({ const credentials = record?.[settingName]; if (!credentials?.username || !credentials?.password) { throw new Error( - (0, import_i18n6.__)("It was not possible to save these credentials.") + (0, import_i18n7.__)("It was not possible to save these credentials.") ); } setConnectedState(true); @@ -11649,7 +11869,8 @@ function useConnectorPlugin({ } // routes/connectors-home/logos.tsx -var OpenAILogo = () => /* @__PURE__ */ React.createElement( +var import_jsx_runtime40 = __toESM(require_jsx_runtime()); +var OpenAILogo = () => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)( "svg", { width: "40", @@ -11657,17 +11878,17 @@ var OpenAILogo = () => /* @__PURE__ */ React.createElement( viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", - "aria-hidden": "true" - }, - /* @__PURE__ */ React.createElement( - "path", - { - d: "M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364l2.0201-1.1685a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.4043-.6813zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z", - fill: "currentColor" - } - ) + "aria-hidden": "true", + children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)( + "path", + { + d: "M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364l2.0201-1.1685a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.4043-.6813zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z", + fill: "currentColor" + } + ) + } ); -var ClaudeLogo = () => /* @__PURE__ */ React.createElement( +var ClaudeLogo = () => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)( "svg", { width: "40", @@ -11675,17 +11896,17 @@ var ClaudeLogo = () => /* @__PURE__ */ React.createElement( viewBox: "0 0 32 32", fill: "none", xmlns: "http://www.w3.org/2000/svg", - "aria-hidden": "true" - }, - /* @__PURE__ */ React.createElement( - "path", - { - d: "M6.2 21.024L12.416 17.536L12.52 17.232L12.416 17.064H12.112L11.072 17L7.52 16.904L4.44 16.776L1.456 16.616L0.704 16.456L0 15.528L0.072 15.064L0.704 14.64L1.608 14.72L3.608 14.856L6.608 15.064L8.784 15.192L12.008 15.528H12.52L12.592 15.32L12.416 15.192L12.28 15.064L9.176 12.96L5.816 10.736L4.056 9.456L3.104 8.808L2.624 8.2L2.416 6.872L3.28 5.92L4.44 6L4.736 6.08L5.912 6.984L8.424 8.928L11.704 11.344L12.184 11.744L12.376 11.608L12.4 11.512L12.184 11.152L10.4 7.928L8.496 4.648L7.648 3.288L7.424 2.472C7.344 2.136 7.288 1.856 7.288 1.512L8.272 0.176L8.816 0L10.128 0.176L10.68 0.656L11.496 2.52L12.816 5.456L14.864 9.448L15.464 10.632L15.784 11.728L15.904 12.064H16.112V11.872L16.28 9.624L16.592 6.864L16.896 3.312L17 2.312L17.496 1.112L18.48 0.464L19.248 0.832L19.88 1.736L19.792 2.32L19.416 4.76L18.68 8.584L18.2 11.144H18.48L18.8 10.824L20.096 9.104L22.272 6.384L23.232 5.304L24.352 4.112L25.072 3.544H26.432L27.432 5.032L26.984 6.568L25.584 8.344L24.424 9.848L22.76 12.088L21.72 13.88L21.816 14.024L22.064 14L25.824 13.2L27.856 12.832L30.28 12.416L31.376 12.928L31.496 13.448L31.064 14.512L28.472 15.152L25.432 15.76L20.904 16.832L20.848 16.872L20.912 16.952L22.952 17.144L23.824 17.192H25.96L29.936 17.488L30.976 18.176L31.6 19.016L31.496 19.656L29.896 20.472L27.736 19.96L22.696 18.76L20.968 18.328H20.728V18.472L22.168 19.88L24.808 22.264L28.112 25.336L28.28 26.096L27.856 26.696L27.408 26.632L24.504 24.448L23.384 23.464L20.848 21.328H20.68V21.552L21.264 22.408L24.352 27.048L24.512 28.472L24.288 28.936L23.488 29.216L22.608 29.056L20.8 26.52L18.936 23.664L17.432 21.104L17.248 21.208L16.36 30.768L15.944 31.256L14.984 31.624L14.184 31.016L13.76 30.032L14.184 28.088L14.696 25.552L15.112 23.536L15.488 21.032L15.712 20.2L15.696 20.144L15.512 20.168L13.624 22.76L10.752 26.64L8.48 29.072L7.936 29.288L6.992 28.8L7.08 27.928L7.608 27.152L10.752 23.152L12.648 20.672L13.872 19.24L13.864 19.032H13.792L5.44 24.456L3.952 24.648L3.312 24.048L3.392 23.064L3.696 22.744L6.208 21.016L6.2 21.024Z", - fill: "#D97757" - } - ) + "aria-hidden": "true", + children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)( + "path", + { + d: "M6.2 21.024L12.416 17.536L12.52 17.232L12.416 17.064H12.112L11.072 17L7.52 16.904L4.44 16.776L1.456 16.616L0.704 16.456L0 15.528L0.072 15.064L0.704 14.64L1.608 14.72L3.608 14.856L6.608 15.064L8.784 15.192L12.008 15.528H12.52L12.592 15.32L12.416 15.192L12.28 15.064L9.176 12.96L5.816 10.736L4.056 9.456L3.104 8.808L2.624 8.2L2.416 6.872L3.28 5.92L4.44 6L4.736 6.08L5.912 6.984L8.424 8.928L11.704 11.344L12.184 11.744L12.376 11.608L12.4 11.512L12.184 11.152L10.4 7.928L8.496 4.648L7.648 3.288L7.424 2.472C7.344 2.136 7.288 1.856 7.288 1.512L8.272 0.176L8.816 0L10.128 0.176L10.68 0.656L11.496 2.52L12.816 5.456L14.864 9.448L15.464 10.632L15.784 11.728L15.904 12.064H16.112V11.872L16.28 9.624L16.592 6.864L16.896 3.312L17 2.312L17.496 1.112L18.48 0.464L19.248 0.832L19.88 1.736L19.792 2.32L19.416 4.76L18.68 8.584L18.2 11.144H18.48L18.8 10.824L20.096 9.104L22.272 6.384L23.232 5.304L24.352 4.112L25.072 3.544H26.432L27.432 5.032L26.984 6.568L25.584 8.344L24.424 9.848L22.76 12.088L21.72 13.88L21.816 14.024L22.064 14L25.824 13.2L27.856 12.832L30.28 12.416L31.376 12.928L31.496 13.448L31.064 14.512L28.472 15.152L25.432 15.76L20.904 16.832L20.848 16.872L20.912 16.952L22.952 17.144L23.824 17.192H25.96L29.936 17.488L30.976 18.176L31.6 19.016L31.496 19.656L29.896 20.472L27.736 19.96L22.696 18.76L20.968 18.328H20.728V18.472L22.168 19.88L24.808 22.264L28.112 25.336L28.28 26.096L27.856 26.696L27.408 26.632L24.504 24.448L23.384 23.464L20.848 21.328H20.68V21.552L21.264 22.408L24.352 27.048L24.512 28.472L24.288 28.936L23.488 29.216L22.608 29.056L20.8 26.52L18.936 23.664L17.432 21.104L17.248 21.208L16.36 30.768L15.944 31.256L14.984 31.624L14.184 31.016L13.76 30.032L14.184 28.088L14.696 25.552L15.112 23.536L15.488 21.032L15.712 20.2L15.696 20.144L15.512 20.168L13.624 22.76L10.752 26.64L8.48 29.072L7.936 29.288L6.992 28.8L7.08 27.928L7.608 27.152L10.752 23.152L12.648 20.672L13.872 19.24L13.864 19.032H13.792L5.44 24.456L3.952 24.648L3.312 24.048L3.392 23.064L3.696 22.744L6.208 21.016L6.2 21.024Z", + fill: "#D97757" + } + ) + } ); -var DefaultConnectorLogo = () => /* @__PURE__ */ React.createElement( +var DefaultConnectorLogo = () => /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)( "svg", { width: "40", @@ -11693,24 +11914,26 @@ var DefaultConnectorLogo = () => /* @__PURE__ */ React.createElement( viewBox: "0 0 32 32", fill: "none", xmlns: "http://www.w3.org/2000/svg", - "aria-hidden": "true" - }, - /* @__PURE__ */ React.createElement( - "path", - { - d: "M0 4C0 1.79086 1.79086 0 4 0H28C30.2091 0 32 1.79086 32 4V28C32 30.2091 30.2091 32 28 32H4C1.79086 32 0 30.2091 0 28V4Z", - fill: "#F0F0F0" - } - ), - /* @__PURE__ */ React.createElement( - "path", - { - d: "M14.5 8V12H17.5V8H19V12H20.5C20.7652 12 21.0196 12.1054 21.2071 12.2929C21.3946 12.4804 21.5 12.7348 21.5 13V17L18.5 21V23C18.5 23.2652 18.3946 23.5196 18.2071 23.7071C18.0196 23.8946 17.7652 24 17.5 24H14.5C14.2348 24 13.9804 23.8946 13.7929 23.7071C13.6054 23.5196 13.5 23.2652 13.5 23V21L10.5 17V13C10.5 12.7348 10.6054 12.4804 10.7929 12.2929C10.9804 12.1054 11.2348 12 11.5 12H13V8H14.5ZM15 20.5V22.5H17V20.5L20 16.5V13.5H12V16.5L15 20.5Z", - fill: "#949494" - } - ) + "aria-hidden": "true", + children: [ + /* @__PURE__ */ (0, import_jsx_runtime40.jsx)( + "path", + { + d: "M0 4C0 1.79086 1.79086 0 4 0H28C30.2091 0 32 1.79086 32 4V28C32 30.2091 30.2091 32 28 32H4C1.79086 32 0 30.2091 0 28V4Z", + fill: "#F0F0F0" + } + ), + /* @__PURE__ */ (0, import_jsx_runtime40.jsx)( + "path", + { + d: "M14.5 8V12H17.5V8H19V12H20.5C20.7652 12 21.0196 12.1054 21.2071 12.2929C21.3946 12.4804 21.5 12.7348 21.5 13V17L18.5 21V23C18.5 23.2652 18.3946 23.5196 18.2071 23.7071C18.0196 23.8946 17.7652 24 17.5 24H14.5C14.2348 24 13.9804 23.8946 13.7929 23.7071C13.6054 23.5196 13.5 23.2652 13.5 23V21L10.5 17V13C10.5 12.7348 10.6054 12.4804 10.7929 12.2929C10.9804 12.1054 11.2348 12 11.5 12H13V8H14.5ZM15 20.5V22.5H17V20.5L20 16.5V13.5H12V16.5L15 20.5Z", + fill: "#949494" + } + ) + ] + } ); -var AkismetLogo = () => /* @__PURE__ */ React.createElement( +var AkismetLogo = () => /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)( "svg", { width: "40", @@ -11718,20 +11941,22 @@ var AkismetLogo = () => /* @__PURE__ */ React.createElement( viewBox: "0 0 44 44", fill: "none", xmlns: "http://www.w3.org/2000/svg", - "aria-hidden": "true" - }, - /* @__PURE__ */ React.createElement("rect", { width: "44", height: "44", fill: "#357B49", rx: "6" }), - /* @__PURE__ */ React.createElement( - "path", - { - fill: "#fff", - fillRule: "evenodd", - d: "m29.746 28.31-6.392-16.797c-.152-.397-.305-.672-.789-.675-.673 0-1.408.611-1.746 1.316l-7.378 16.154c-.072.16-.143.311-.214.454-.5.995-1.045 1.546-2.357 1.626a.399.399 0 0 0-.16.033l-.01.004a.399.399 0 0 0-.23.392v.01c0 .054.01.106.03.155l.004.01a.416.416 0 0 0 .394.252h6.212a.417.417 0 0 0 .307-.12.416.416 0 0 0 .124-.305.398.398 0 0 0-.105-.302.399.399 0 0 0-.294-.127c-.757 0-2.197-.062-2.197-1.164.02-.318.103-.63.245-.916l1.399-3.152c.52-1.163 1.654-1.163 2.572-1.163h5.843c.023 0 .044 0 .062.003.13.014.16.081.214.242l1.534 4.07a2.857 2.857 0 0 1 .216 1.04c0 .054-.003.104-.01.153-.09.726-.831.887-1.49.887a.4.4 0 0 0-.294.127l-.007.008-.007.008a.401.401 0 0 0-.092.286v.01c0 .054.01.106.03.155l.005.01a.42.42 0 0 0 .395.252h7.011a.413.413 0 0 0 .279-.13.412.412 0 0 0 .11-.297.387.387 0 0 0-.09-.294.388.388 0 0 0-.277-.135c-1.448-.122-2.295-.643-2.847-2.08Zm-11.985-5.844 2.847-6.304c.361-.728.659-1.486.889-2.265 0-.06.03-.092.06-.092s.061.032.061.091c.02.122.045.247.073.374.197.888.584 1.878.914 2.723l.176.453 1.684 4.529a.927.927 0 0 1 .092.4.473.473 0 0 1-.009.094c-.041.202-.228.272-.602.272h-6.063c-.122 0-.184-.03-.184-.092a.36.36 0 0 1 .062-.183Zm17.107-.721c0 .786-.446 1.231-1.25 1.231-.806 0-1.125-.409-1.125-1.034 0-.786.465-1.231 1.25-1.231.785 0 1.125.427 1.125 1.034ZM9.629 23.002c.803 0 1.25-.447 1.25-1.231 0-.607-.343-1.036-1.128-1.036-.785 0-1.25.447-1.25 1.231 0 .625.325 1.036 1.128 1.036Z", - clipRule: "evenodd" - } - ) + "aria-hidden": "true", + children: [ + /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("rect", { width: "44", height: "44", fill: "#357B49", rx: "6" }), + /* @__PURE__ */ (0, import_jsx_runtime40.jsx)( + "path", + { + fill: "#fff", + fillRule: "evenodd", + d: "m29.746 28.31-6.392-16.797c-.152-.397-.305-.672-.789-.675-.673 0-1.408.611-1.746 1.316l-7.378 16.154c-.072.16-.143.311-.214.454-.5.995-1.045 1.546-2.357 1.626a.399.399 0 0 0-.16.033l-.01.004a.399.399 0 0 0-.23.392v.01c0 .054.01.106.03.155l.004.01a.416.416 0 0 0 .394.252h6.212a.417.417 0 0 0 .307-.12.416.416 0 0 0 .124-.305.398.398 0 0 0-.105-.302.399.399 0 0 0-.294-.127c-.757 0-2.197-.062-2.197-1.164.02-.318.103-.63.245-.916l1.399-3.152c.52-1.163 1.654-1.163 2.572-1.163h5.843c.023 0 .044 0 .062.003.13.014.16.081.214.242l1.534 4.07a2.857 2.857 0 0 1 .216 1.04c0 .054-.003.104-.01.153-.09.726-.831.887-1.49.887a.4.4 0 0 0-.294.127l-.007.008-.007.008a.401.401 0 0 0-.092.286v.01c0 .054.01.106.03.155l.005.01a.42.42 0 0 0 .395.252h7.011a.413.413 0 0 0 .279-.13.412.412 0 0 0 .11-.297.387.387 0 0 0-.09-.294.388.388 0 0 0-.277-.135c-1.448-.122-2.295-.643-2.847-2.08Zm-11.985-5.844 2.847-6.304c.361-.728.659-1.486.889-2.265 0-.06.03-.092.06-.092s.061.032.061.091c.02.122.045.247.073.374.197.888.584 1.878.914 2.723l.176.453 1.684 4.529a.927.927 0 0 1 .092.4.473.473 0 0 1-.009.094c-.041.202-.228.272-.602.272h-6.063c-.122 0-.184-.03-.184-.092a.36.36 0 0 1 .062-.183Zm17.107-.721c0 .786-.446 1.231-1.25 1.231-.806 0-1.125-.409-1.125-1.034 0-.786.465-1.231 1.25-1.231.785 0 1.125.427 1.125 1.034ZM9.629 23.002c.803 0 1.25-.447 1.25-1.231 0-.607-.343-1.036-1.128-1.036-.785 0-1.25.447-1.25 1.231 0 .625.325 1.036 1.128 1.036Z", + clipRule: "evenodd" + } + ) + ] + } ); -var GeminiLogo = () => /* @__PURE__ */ React.createElement( +var GeminiLogo = () => /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)( "svg", { width: "40", @@ -11739,76 +11964,89 @@ var GeminiLogo = () => /* @__PURE__ */ React.createElement( style: { flex: "none", lineHeight: 1 }, viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", - "aria-hidden": "true" - }, - /* @__PURE__ */ React.createElement( - "path", - { - d: "M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z", - fill: "#3186FF" - } - ), - /* @__PURE__ */ React.createElement( - "path", - { - d: "M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z", - fill: "url(#lobe-icons-gemini-fill-0)" - } - ), - /* @__PURE__ */ React.createElement( - "path", - { - d: "M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z", - fill: "url(#lobe-icons-gemini-fill-1)" - } - ), - /* @__PURE__ */ React.createElement( - "path", - { - d: "M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z", - fill: "url(#lobe-icons-gemini-fill-2)" - } - ), - /* @__PURE__ */ React.createElement("defs", null, /* @__PURE__ */ React.createElement( - "linearGradient", - { - gradientUnits: "userSpaceOnUse", - id: "lobe-icons-gemini-fill-0", - x1: "7", - x2: "11", - y1: "15.5", - y2: "12" - }, - /* @__PURE__ */ React.createElement("stop", { stopColor: "#08B962" }), - /* @__PURE__ */ React.createElement("stop", { offset: "1", stopColor: "#08B962", stopOpacity: "0" }) - ), /* @__PURE__ */ React.createElement( - "linearGradient", - { - gradientUnits: "userSpaceOnUse", - id: "lobe-icons-gemini-fill-1", - x1: "8", - x2: "11.5", - y1: "5.5", - y2: "11" - }, - /* @__PURE__ */ React.createElement("stop", { stopColor: "#F94543" }), - /* @__PURE__ */ React.createElement("stop", { offset: "1", stopColor: "#F94543", stopOpacity: "0" }) - ), /* @__PURE__ */ React.createElement( - "linearGradient", - { - gradientUnits: "userSpaceOnUse", - id: "lobe-icons-gemini-fill-2", - x1: "3.5", - x2: "17.5", - y1: "13.5", - y2: "12" - }, - /* @__PURE__ */ React.createElement("stop", { stopColor: "#FABC12" }), - /* @__PURE__ */ React.createElement("stop", { offset: ".46", stopColor: "#FABC12", stopOpacity: "0" }) - )) + "aria-hidden": "true", + children: [ + /* @__PURE__ */ (0, import_jsx_runtime40.jsx)( + "path", + { + d: "M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z", + fill: "#3186FF" + } + ), + /* @__PURE__ */ (0, import_jsx_runtime40.jsx)( + "path", + { + d: "M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z", + fill: "url(#lobe-icons-gemini-fill-0)" + } + ), + /* @__PURE__ */ (0, import_jsx_runtime40.jsx)( + "path", + { + d: "M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z", + fill: "url(#lobe-icons-gemini-fill-1)" + } + ), + /* @__PURE__ */ (0, import_jsx_runtime40.jsx)( + "path", + { + d: "M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z", + fill: "url(#lobe-icons-gemini-fill-2)" + } + ), + /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("defs", { children: [ + /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)( + "linearGradient", + { + gradientUnits: "userSpaceOnUse", + id: "lobe-icons-gemini-fill-0", + x1: "7", + x2: "11", + y1: "15.5", + y2: "12", + children: [ + /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("stop", { stopColor: "#08B962" }), + /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("stop", { offset: "1", stopColor: "#08B962", stopOpacity: "0" }) + ] + } + ), + /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)( + "linearGradient", + { + gradientUnits: "userSpaceOnUse", + id: "lobe-icons-gemini-fill-1", + x1: "8", + x2: "11.5", + y1: "5.5", + y2: "11", + children: [ + /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("stop", { stopColor: "#F94543" }), + /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("stop", { offset: "1", stopColor: "#F94543", stopOpacity: "0" }) + ] + } + ), + /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)( + "linearGradient", + { + gradientUnits: "userSpaceOnUse", + id: "lobe-icons-gemini-fill-2", + x1: "3.5", + x2: "17.5", + y1: "13.5", + y2: "12", + children: [ + /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("stop", { stopColor: "#FABC12" }), + /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("stop", { offset: ".46", stopColor: "#FABC12", stopOpacity: "0" }) + ] + } + ) + ] }) + ] + } ); // routes/connectors-home/default-connectors.tsx +var import_jsx_runtime41 = __toESM(require_jsx_runtime()); var { store: connectorsStore } = unlock2(connectorsPrivateApis); function getConnectorScriptModuleData() { try { @@ -11835,15 +12073,15 @@ var CONNECTOR_LOGOS = { }; function getConnectorLogo(connectorId, logoUrl) { if (logoUrl) { - return /* @__PURE__ */ React.createElement("img", { src: logoUrl, alt: "", width: 40, height: 40 }); + return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("img", { src: logoUrl, alt: "", width: 40, height: 40 }); } const Logo = CONNECTOR_LOGOS[connectorId]; if (Logo) { - return /* @__PURE__ */ React.createElement(Logo, null); + return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Logo, {}); } - return /* @__PURE__ */ React.createElement(DefaultConnectorLogo, null); + return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(DefaultConnectorLogo, {}); } -var ConnectedBadge = () => /* @__PURE__ */ React.createElement( +var ConnectedBadge = () => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)( "span", { style: { @@ -11854,23 +12092,23 @@ var ConnectedBadge = () => /* @__PURE__ */ React.createElement( fontSize: "13px", fontWeight: "var(--wpds-typography-font-weight-emphasis)", whiteSpace: "nowrap" - } - }, - (0, import_i18n7.__)("Connected") + }, + children: (0, import_i18n8.__)("Connected") + } ); -var PluginDirectoryLink = ({ slug }) => /* @__PURE__ */ React.createElement( +var PluginDirectoryLink = ({ slug }) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)( Link, { - href: (0, import_i18n7.sprintf)( + href: (0, import_i18n8.sprintf)( /* translators: %s: plugin slug. */ - (0, import_i18n7.__)("https://wordpress.org/plugins/%s/"), + (0, import_i18n8.__)("https://wordpress.org/plugins/%s/"), slug ), - openInNewTab: true - }, - (0, import_i18n7.__)("Learn more") + openInNewTab: true, + children: (0, import_i18n8.__)("Learn more") + } ); -var UnavailableActionBadge = () => /* @__PURE__ */ React.createElement(Badge, null, (0, import_i18n7.__)("Not available")); +var UnavailableActionBadge = () => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Badge, { children: (0, import_i18n8.__)("Not available") }); function ConnectorActionArea({ isConnected, showUnavailableBadge, @@ -11882,19 +12120,23 @@ function ConnectorActionArea({ handleButtonClick, getButtonLabel }) { - return /* @__PURE__ */ React.createElement(import_components2.__experimentalHStack, { spacing: 3, expanded: false }, isConnected && /* @__PURE__ */ React.createElement(ConnectedBadge, null), showUnavailableBadge && (pluginSlug ? /* @__PURE__ */ React.createElement(PluginDirectoryLink, { slug: pluginSlug }) : /* @__PURE__ */ React.createElement(UnavailableActionBadge, null)), !showUnavailableBadge && /* @__PURE__ */ React.createElement( - import_components2.Button, - { - ref: actionButtonRef, - variant: isExpanded || isConnected ? "tertiary" : "secondary", - size: "compact", - onClick: handleButtonClick, - disabled: pluginStatus === "checking" || isBusy, - isBusy, - accessibleWhenDisabled: true - }, - getButtonLabel() - )); + return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_components2.__experimentalHStack, { spacing: 3, expanded: false, children: [ + isConnected && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(ConnectedBadge, {}), + showUnavailableBadge && (pluginSlug ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(PluginDirectoryLink, { slug: pluginSlug }) : /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(UnavailableActionBadge, {})), + !showUnavailableBadge && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)( + import_components2.Button, + { + ref: actionButtonRef, + variant: isExpanded || isConnected ? "tertiary" : "secondary", + size: "compact", + onClick: handleButtonClick, + disabled: pluginStatus === "checking" || isBusy, + isBusy, + accessibleWhenDisabled: true, + children: getButtonLabel() + } + ) + ] }); } function getPluginSlug(pluginFile) { const pluginBasename = pluginFile?.replace(/\.php$/, ""); @@ -11938,14 +12180,14 @@ function ApiKeyConnector({ const isExternallyConfigured = keySource === "env" || keySource === "constant"; const showUnavailableBadge = pluginStatus === "not-installed" && canInstallPlugins === false || pluginStatus === "inactive" && canActivatePlugins === false; const actionButtonRef = (0, import_element34.useRef)(null); - return /* @__PURE__ */ React.createElement( + return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)( ConnectorItem, { className: pluginSlug ? `connector-item--${pluginSlug}` : void 0, logo, name, description, - actionArea: /* @__PURE__ */ React.createElement( + actionArea: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)( ConnectorActionArea, { isConnected, @@ -11958,27 +12200,27 @@ function ApiKeyConnector({ handleButtonClick, getButtonLabel } - ) - }, - isExpanded && pluginStatus === "active" && hasResolvedSettings && /* @__PURE__ */ React.createElement( - DefaultConnectorSettings, - { - key: isConnected ? "connected" : "setup", - initialValue: isExternallyConfigured ? "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" : currentApiKey, - helpUrl, - readOnly: isConnected || isExternallyConfigured, - keySource, - onRemove: isExternallyConfigured ? void 0 : async () => { - await removeApiKey(); - actionButtonRef.current?.focus(); + ), + children: isExpanded && pluginStatus === "active" && hasResolvedSettings && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)( + DefaultConnectorSettings, + { + initialValue: isExternallyConfigured ? "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" : currentApiKey, + helpUrl, + readOnly: isConnected || isExternallyConfigured, + keySource, + onRemove: isExternallyConfigured ? void 0 : async () => { + await removeApiKey(); + actionButtonRef.current?.focus(); + }, + onSave: async (apiKey) => { + await saveApiKey(apiKey); + setIsExpanded(false); + actionButtonRef.current?.focus(); + } }, - onSave: async (apiKey) => { - await saveApiKey(apiKey); - setIsExpanded(false); - actionButtonRef.current?.focus(); - } - } - ) + isConnected ? "connected" : "setup" + ) + } ); } function ApplicationPasswordConnector({ @@ -12019,14 +12261,14 @@ function ApplicationPasswordConnector({ const isExternallyConfigured = keySource === "env" || keySource === "constant"; const actionButtonRef = (0, import_element34.useRef)(null); const showUnavailableBadge = pluginStatus === "not-installed" && canInstallPlugins === false || pluginStatus === "inactive" && canActivatePlugins === false; - return /* @__PURE__ */ React.createElement( + return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)( ConnectorItem, { className: pluginSlug ? `connector-item--${pluginSlug}` : void 0, logo, name, description, - actionArea: /* @__PURE__ */ React.createElement( + actionArea: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)( ConnectorActionArea, { isConnected, @@ -12039,27 +12281,27 @@ function ApplicationPasswordConnector({ handleButtonClick, getButtonLabel } - ) - }, - isExpanded && pluginStatus === "active" && hasResolvedSettings && /* @__PURE__ */ React.createElement( - ApplicationPasswordConnectorSettings, - { - key: isConnected ? "connected" : "setup", - initialUsername: isExternallyConfigured ? "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" : currentUsername, - helpUrl, - readOnly: isConnected || isExternallyConfigured, - keySource, - onRemove: isExternallyConfigured ? void 0 : async () => { - await removeCredentials(); - actionButtonRef.current?.focus(); + ), + children: isExpanded && pluginStatus === "active" && hasResolvedSettings && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)( + ApplicationPasswordConnectorSettings, + { + initialUsername: isExternallyConfigured ? "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" : currentUsername, + helpUrl, + readOnly: isConnected || isExternallyConfigured, + keySource, + onRemove: isExternallyConfigured ? void 0 : async () => { + await removeCredentials(); + actionButtonRef.current?.focus(); + }, + onSave: async (credentials) => { + await saveCredentials(credentials); + setIsExpanded(false); + actionButtonRef.current?.focus(); + } }, - onSave: async (credentials) => { - await saveCredentials(credentials); - setIsExpanded(false); - actionButtonRef.current?.focus(); - } - } - ) + isConnected ? "connected" : "setup" + ) + } ); } function registerDefaultConnectors() { @@ -12092,29 +12334,31 @@ function registerDefaultConnectors() { } // routes/connectors-home/wp-logo-decoration.tsx +var import_jsx_runtime42 = __toESM(require_jsx_runtime()); function WpLogoDecoration() { - return /* @__PURE__ */ React.createElement("div", { className: "ai-plugin-callout__decoration", "aria-hidden": "true" }, /* @__PURE__ */ React.createElement( + return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "ai-plugin-callout__decoration", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)( "svg", { viewBox: "0 0 248 248", xmlns: "http://www.w3.org/2000/svg", xmlnsXlink: "http://www.w3.org/1999/xlink", focusable: "false", - style: { width: "100%", height: "100%" } - }, - /* @__PURE__ */ React.createElement( - "image", - { - href: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51AAAQAElEQVR4AezdC3ojWW5tYflOzPbIbI/M9sh8+WdrdZ+KpiiKL5FB5KedwN7AeSFIpHRYmfX/PubXVGAqMBV4kQpMw3qRBzXbnApMBT4+pmHNq2AqMBV4mQpMw3qZR3X9RmeGqcCrV2Aa1qs/wdn/VOCNKjAN640e9hx1KvDqFZiG9epPcPY/FThWgZ1q07B2+mDnWFOBPVZgGtYen+qcaSqw0wpMw9rpg51jTQX2WIFpWMee6mhTganAU1ZgGtZTPpbZ1FRgKnCsAtOwjlVltKnAVOApKzAN6ykfy2zqcRWYlV6pAtOwXulpzV6nAm9egWlYb/4CmONPBV6pAtOwXulpve9e//Nw9P/7xL8d7Hy9aQWubFhvWrU59qMr8D+HBcPBna93rcA0rHd98q91bs3q3w9bBv7Bna93rMA0rHd86nPmqcCLVmAa1os+uF/Y9m8u6Q7rvw8bgLnDOhTiXb+mYb3rk3+tc//rYbsaVTjQP18amct4+h9hftt3BaZh7fv57v107rNg7+ec831WYBrWZyHGPHUF/vewu//6xNqg+HMRfyjMrb+edb5pWM/6ZGZfawX86Bc0qTU2/htVYBrWGz3sOepU4NUrMA3r1Z/g7H8q8EYVmIZ1h4c9U04FpgL3qcA0rPvUdWadCkwF7lCBaVh3KOpMORWYCtynAtOw7lPXmfVdKjDnfGgFpmE9tNyz2FRgKnBNBaZhXVO9GTsVmAo8tALTsB5a7llsKjAVuKYCv9uwrtn5jJ0KTAXergLTsN7ukc+BpwKvW4FpWK/77GbnU4G3q8A0rLd75L914Fl3KnB9BaZhXV/DmWEqMBV4UAWmYT2o0LPMVGAqcH0FpmFdX8OZYSowFfhrBe7GpmHdrbQz8VRgKnDrCkzDunVFZ76pwFTgbhWYhnW30s7EU4GpwK0rMA3r1hW9fr6ZYSowFfiiAtOwvijMyFOBqcDzVWAa1vM9k9nRVGAq8EUFpmF9UZiRpwKPqMCs8bMKTMP6Wb0meyowFfjFCkzD+sXiz9JTganAzyowDetn9ZrsqcBU4Bcr8NIN6xfrNktPBaYCv1CBaVi/UPRZciowFbisAtOwLqvbjJoKTAV+oQLTsH6h6LPkBRWYIVOBQwWmYR2KMF9TganAa1RgGtZrPKfZ5VRgKnCowDSsQxHmayowFXimCny9l2lYX9dmIlOBqcCTVWAa1pM9kNnOVGAq8HUFpmF9XZuJTAWmAk9WgWlYT/ZArt/OzDAV2G8FpmHt99nOyaYCu6vANKzdPdK7HOjfDrP+9yf4B/fP138efoeDma+pwP0rMA3r/jXewwqaVFjP8x8HAmIHd74eXIG3W24a1ts98pse+H8Os8HBzNdU4P4VmIZ1/xrvYQU/9v3L4SCwNqh/P2iwagdpvqYC96nANKz71HVmnQpMBe5QgXduWHco526n9B3W9tJ91fi7Pfwc7HkqMA3reZ7FM+/kXw+bc7EeDvTPV1z8jzC/TQXuWYFpWPes7sw9FZgK3LQC07BuWs7dTva/h5P91ye6YGfT2EP4eb9mZ/uowDSsfTzHe5/CHVXQqKzHbjX6YCpwtwpMw7pbaX808f8dsoN7oQOdr6nAVGBbgWlY24o8hvvEzXcnp1YTl3cq51ExTdRe7GldE6ev2vhTgbtV4KyGdbfV33diDeC7T9bE5T1LlezFntb94PRVG38qcLcKTMO6W2lPTuy/GPdfiJfED+6G6Lg8/m/Dnuxne7lOe5Y9/naNZv0HVGAa1gOKfMYSGkI4I/1XUp59f79SlFn0sRWYhvXYereaex/3PyunQT9iiePlPMbOKlOBJ67ANKzfeTiakvufVsdDmjgtPnYq8PYVmIb1Oy8B9z7uf06tLi7vVM7EpgJvVYFpWM/xuF1mB3dFz7Gr2cXOK/B6x5uG9RzPzH1VeI4dzS6mAk9YgWlYT/hQZktTganA8QpMwzpel1GnAlOBJ6zANKyLH8oMnApMBR5dgWlYj674rDcVmApcXIFpWBeXbgZOBaYCj67ANKxHV3zWe8UKzJ6fpALTsJ7kQcw2pgJTge8rMA3r+xpNxlRgKvAkFZiG9SQPYrYxFZgKfF+BRzSs73cxGVOBqcBU4IwKTMM6o0iTMhWYCjxHBaZhPcdzmF1MBaYCZ1RgGtYZRXrSFP9Wln/gD/htEwd/mTqNT4Nyj2ny+7/3sDgYh4NxNBYHcdrH4Tc8HOifL/E044hsmjgN0tj2Ko6DcfLE8EADcfmAg1w64IMXrcA0rNd5cN6Y3njrjnE4pvkHANP58iCNxQO+B3x11v84HA6c9+DO1ytWYBrW6zw1/6Df/FtZlz8vtYPLZ5iRv16BaVi//gjO3sD2zYb7F0mB30Q4aHBpfBqU68cjHPjl4iHNPy5oDljH4yBeLh7SxNN+Mr7cY+PFmpNtLf52/2suv9yx11TgF8ZOw/qFor/gkt7kKzrCJZox9xzf3GN3WIFpWK/xUN27hHbsuyIXyyBGZ/FAgzgrh7aO59PE5AQaiKfJ2WriNCiPPZabxsqBa8ebw9rAD9agmX+r0QcvVoFpWK/xwLzxvOFcGq87pof0OHtKE5MDLqpxwAMO4mksDfggjgMecBBPY2lsEKdBGouDOB5oEGdx4Ac8pLFpY1+sAtOwfuuBXb+uN/H1s9x2hm0zWH/8u+1KM9tbVmAa1ms8dj/SuEh2odyOXUSHtTGksadyjZETjuWm/e/BKc+4A/1g09iPw69j2kH+OHe8XHMF89GOjaeXx+LAD41nt5rcwYtVYBrWiz2wZbvehBoZ8IVYPNAgzuKw5vK32prLD8dy08xRHosDP5TLbrVtLg7lscbRWDzQIM7isObyaYMXrMA0rBd8aN9s2Y9lodQ4m/ZK1r7Duu80Np0f0n7ZzvK3qsA0rFtV8vHzeFP6r9+Bbwesy/lAgzgrh8YaC+t3I3SclRdoEGflbDU6TYwfaBBn5Ww1fN2nPB820ECcZiweaLDmyqGBcSunDV6sAtOwXuyBPWC73tTe9NulaNuLfhqsuY1nV13eOeONMRb4t4Q93HK+mevBFZiG9eCC33i5ay+S3efAui3fibjc3+o06625OH3VjKOZZ9V9aCB/1XC5q2YczTyrfq7vgt5YWMc076qN/2IVeIGG9WIVfdx2vSG9CaFVaRpDSI+zcuisxgDrHMXYFfLhO018m0eDrY6D2AoapNmjvUN7FcdDueLyQU762B1UYBrWDh7iHGEq8C4VmIa1vyfdJbTvNDqdi/Ww3g3JgfKe1TpT+2+/zpHGtne6HEgbu5MKTMPayYNcjuENC9sL7iXl765LaPi78MvOLZZ3dmc65/y3WG/meGAFpmE9sNhPuJQ7HhffT7i1i7fkTODy/eJJZuBzVmAa1nM+l2t21SW0S+fm4Qdv5lV/hR+dNNXt/p0jje1M6a9wrvY89swKTMM6s1AvnuZNHF7xKO092xnibNrYF6nAJduchnVJ1Z57jO8sQjt1aR3c8aS/inWe7f6dI43tLPSQNnYnFZiGtZMHuRzDhTOsl869gdkl9cOna7Bqz+g7i72H9hhnV00DU4O0sTupwDSsnTzIOcZU4B0qMA3rRZ/yiW27gAYX1aXxw3rf0wV9ec9qfeJ3bP9pbHv346NzqUHa2J1UYBrWTh7kcgwNKSR7E4e0V7LtnXU2e2fxQBvsvALTsHb+gD+P544nfEovZdo7u24cD6s+/k4rMA1rfw/WJTq4eO50/OANvtXjz2pdoLd/31HZp3OksTQQx1n89TEn+HsFpmH9vRRv6XjTw94O70w+Wdzbud7+PNOw9vcScLcDLqq/O52Lafgu75Xizu5M60X8K+1/9nqiAtOwThTnRUPerLD+SORTs+AN3dH4EH9W6zztv3PZdxrb3ukhbexOKrD/hrWTBzXHmApMBT4+pmHt71Xgwhn6TsQJXcIH9zs04AP/meE87b9z2Xca2/7pciBt7E4qMA1rJw9yOYY3LJxz6awRwDL85V1n96niOed/+cO+2wGmYb3bE//reXd21/PncJ3pnA8d/gyY316nAtOwXudZnbvTfzkkgovqg/vnix+8of+Ih9/SDu5Tf/nEr722fzaN7QDp8yNhFdmRnYa1o4d54ijexOFE2tOG2nu2jcbZtLE7rsA0rP09XN9ZhE7nniq440l/Fes82/07Rxr7KmeZfV5RgaVhXTHLDH2mCrhwhvXS2Zs7rHutEazaM/rO0v7Z9sgPac7kU8NpYlVkR3Ya1o4e5hzlLxWYS/e/lGMfZBrWPp7jeoouqNl0fljve3w3sl5Yl/9sVvM5tv80tj07kw8d2LSxO6nANKydPMjlGN6omhIk0wLt1dDe2c7F4uHVzjT7vaAC07AuKNoLDumeh33B7X/Yd/hYfqWxizzuXiswDWt/T9aFM6yXzvywvrnTnr0KPkRor76jsl/nSGNpII6z+GBHFZiGtaOHecFRvOnhgqFPPcSZfLL41Jt81Ob2tM40rD09zb+dxd0OuKj+m/L17y7c4euM14v4zsqZ1ov41zvF7PhoBaZhHS3LS4verOCN20F8ahY0s3Q+xJ/VOk/771z2ncauexeDVRt/BxWYhrWDhzhHmAq8SwWmYX3zpF8w7MIZ+k7EEVzCB/c7NOAD/5nhPO2/c9l3Gtv+6XIgbexOKjANaycPcjmGNyycc+msEcAy/OVdZ/ep4jnnf/nDvtsBpmG92xP/63nd88Bf1ddmzgPnfOjw2id9w91Pw9rfQ3cBDS6qOx0/eDNv9fizWp/4bffvHGlse0//+Y+EzTD2aSswDetpH81NN+ZNHG468YMma+/Zlo2zaWN3XIFpWPt7uL6zCJ0uzrrjSX+Utaa1gW9dFg+0r7Dm8strLJs2dscVmIa1v4frwhnWS2c8rCf26Rqs2j381mZrOCwO617pPghg24uckM6mseVqXs5kjrSxO6nA7RrWTgoyx3iaCmhIT7OZ2chzVGAa1nM8h1vuwgV1aN44u973uJyH8u5lfWJnbWh9Fg+tTXeJ7jultGPjxRrL4mCcM5kDH+yoAtOwdvQwP4/iDQve+J/SBx4+fuFXa7Pti8WBf2pbckK5bBp7avzEdlKBaVg7eZDfHMOPV+Gb1HPCP85pbbbB/BXpx+xXeV/px+YYbQcVmIa1g4e4OYILZ1gvnfnBm7wh8mDVil1jfcezzulSvPXFzC2eJk4DcTqLgzgN0tfxdHkgjrP4YEcVmIa1o4f5w6N4w/9wyFnp5tVgzkr+Iskc6yeHX6R9KV87/suJJ/C7FZiG9bv1v8fq7nbARfWp+eW4rIZTeT+NmdeFN/vTsfKNsyfAf4prx/90vb3nP9X5pmE91eO4yWY0C1h/JPKpWfCGbiE5sGrFrrHb+eyn9a1nbjZNnAbGirE4iJcrRhNPY2lAl8Pigx1VYBrWjh7mHGUqsPcKTMPa3xN24Qy+y+h0LtaD+x06Kwfwe8Ia9gTWtRaLgzjtK8hpoPtu7gAAEABJREFU/+Uan8Y2li4H0sbupALTsO77IH9jdm9YOOfS2uU4yL/3Xq0B6zo4nLPXddwp33zOdMs5T603sQdWYBrWA4s9Sz2kAu6u4LsPHR6ymVnkthWYhnXbej7DbC6gwUV1++EHb2Y6Kw/4tHvBj2fWgdZi29N3nwiKl2ucfbJpLA3SrYkPdlSBaVg7epgnjuJNHE6kPTzUnthTi4uvKPeYVuzhdha8fwWmYd2/xo9ewR0OrN9h8INYe+JD/FmtPR7bfxr7rHuffd2wAtOwbljMJ5nKJ2qwXjq7hA5tUxOQB/z0Z7TtnW2vLB7at+blU0PnShu7kwpMw9rJg5xjTAXeoQJP07DeodgPOqML6tCSx+56aC6rgV/uM1qf+NkjrPvDQ7rvsJxJDdLG7qQC07B28iCXY3jDgjdysjdwWHU+lPes1nnaP98+7TuNpQUxiI/dSQWmYe3kQX5zDPc94ZvUpwy3d3bdIB5WffydVmAa1v4erAtnWC+d+cEb3KlZecCnPQY/X8XFevvvOyx7TmObVRxn08bupALTsHbyIOcYf6mAZrZ+SvqX4JDXrcA0rNd9dl/t3N0NuKj+Kocux8U04HvBXs+1l+dz1TmmYV1Vvqcc7AIa1h+J/JWY4A3dxuXAqhV7Jus87d9+7c2e01ga0OWw+OBXK3Dbxadh3baeM9tUYCpwxwpMw7pjcR8wtbsaaCm+S/SQHmflpL+K9R2Ti3Ro/6zzhM4iJ8hJH7uDCkzDeu2H2Bvz0lNoBHDp+EeO03zCqXXLYU/lTewFKzAN66kf2rebc08D3yZ+kaBZXTP+i2lHngrcpwLTsO5T10fN6jIaWk/zwUN6nJWTzm457dmgsdo7tF8WD+05zspJH7uDCkzD2sFD3BzBmzQUirNpr2btPbT3OHtKKzb2xSswDet1H6A7Gt95AL+T4CFNPKTtwXZOtvPwgzNv9VUr9gx29nBGBaZhnVGkJ03xxvNXVoBvmyweaEC/9oLePM8EZ+qc63/Vnsa2Xw0MB+PSx75YBaZhvdgDm+1OBd65AtOwXvfpu7cJ6ynS2HTfYbiEhrQ9WH+tKHQe515Bx8vj0wYvWIG9NKwXLP3VW/bG04BAQzLhqtFpQQzir26dxbmB33mcO6SJywN++tgXq8A0rBd7YMt23cWERf5IYz/u+Mv8K1rqmFbsEfbY+se0R+xl1rhxBaZh3bigd5rOhfn2r6B4E9LBdw6WXjU67RZo3tYxZ5p1XGbTAA84GNf+jaMBH/iXwFhzs41vbTadxUF+uXScTRv7xBWYhvXED+fJtuZNvX4ad4vtmVMT+dFcS7Lxa7NcQme5144/a5FJul0FpmHdrpb3nMm/beXuBe65zqm5u7Q+lXMqZu+w5vjuZv2nYdbYOb753Fex5+Rvc6x/zfjtfMPvXIFpWHcu8I2m743lzdWUNG924NO9cfFAuwXMaw22+fDWWfeVxq65cmCdo/il1lywjrduKLbulb/ml7Nq4z9pBaZhPemDmW1NBaYCHx8fmyJMw9oU5AmoexXfBbBtpwtrNl2O+x9IK/8aay5Y57CGtcG6YiwO4jTAAw7iacbRrEGHNPq1MJc5oblop9Zfcxsz9gkrMA3r+R6KS2Twhv5ud3JCubg3aPyn1nhvYPanY3+abw245WW+ucwJ3+1HTvgud+JPUIFpWE/wEDZb6IJ9I59N3cnA2QM2ica6YGc3oaFTgd+twDSs363/sdV9d+Rymi2OhxqJ+FYr/285sZ9ZY829jtLAtmvJSRMvP41NE8fB/HQWB3HaLWAuc0LzrXu1Lp2VE2iDJ6/ANKwnf0Cf2/PmCp/SH5PG/hHu9Jv5V7TMJZoxp8YXu9SaP6xzpLHp/JA29okrMA3r+R6O7wZCu4uz7lzS+RC/hbVGaD5rpPHpbBpLA37AYc3lbzX5tHvBmtYAfuvgIU08jZ8+9gkqMA3rdx+CNwS0C74L95AeZ9PkuhwHfvq11hqhueJsa7E4uOg+lntMM47OGgvrePqtz2RO6wB/uz6dBvyAvwjeY5vTsH73OXvzwLFd+FHlmH5P7au93HPNY3PbBxyLjfbGFZiG9bsPvx891l1oVODTwnQ8rFoXxmLp11qX1qG57MUakMYP4sf0NPFy0+Ks+Kr7L9XVJu1aa43OxG8+fkizl2O5xcf+YgWmYf1i8Y8s7c1TE1rfsGmsnIbyIX6tNZd1Q/Ph1gY+XS4OaXQ84CCexqd9NV7s1rCWdYFvfrY9sTSQE/DBE1VgGtafh/FUv/lRKLSxOJt2L2uN0Bpx9pj2lX4q15gV5T7SHlv/mPbIPc1aJyowDetEce4c8qf4uX9dxCV08IZqa3yIX2vN1Tps87mExsG+6WuuOA3kBBzE04yjsWniNDA/ncVvAWtVa745WesEGsRZOTTg33JP5hz8sALTsH5YsCdL9yaCJ9vWVdvxiaEzsVdNdOPBmirceNqZ7icVmIb1k2rdNtcdSrh0Zn/iw6Xjn3GcS291YW+5P3PCpXO6iF/vui6dZ8ZdUYFpWFcU78qh3jzeAFDTofmELLREnJWTfmtrbmuE5rfHtPbKpomXm8amieNgHJ3FQZwGdJzFbwHnMifwzclaO9AgzsqhAR/4g1+qwDSsXyr8LDsVmAr8vALTsH5es0tGuJPxHQM0nu9iF8TpLB5oEGfl0G453lzmNLc1Ag3E0+RsNXEalMfiII7DT8Yfy01jzResA3FWDu3Y+mJygjyIs3Jo63g+bfALFfhpw/qFLe5iSZe1sF4k870hQgeNs6c0MTkBhziLAz/gIc1etppYmjge0uPiW00sTRwP6XHxrSaWJo6H9Dh7ShOTE3CIszjwAx7S7CVt7IMrMA3rwQWf5aYCU4HLKzAN6/La/WSky16XuGzj+tSJ1mUui4dy46wcuh9NcEhj8SAP4qwc2jreXmhicgINxNPk0I6Np5fH4nDp+NY6Nl7MGsE6EGfl0Na9prFygjyIs3Jo63h7oQ1+oQLTsH6h6J9LejOs+JQ/ztU+Dr/OzT2Wdxj+cUz/u/bxj1+rxi/CD+dq8s/NPZZ3yXjzGBdwiLM48AMe0ti0sQ+uwDSsxxTcn9DBXYhV2a1GT2Nx4AfjaOxWo6exOPCDcTQ2jaUBP+Cw5vK3mnwa8AMOxqTxaZDG4sAP5bJbbZuLQ3mscTQWBz4N8IBDnC2XxYM8iLP44M4VmIZ15wJ/Tu/CPXxKH3HWG4LO4oEGcRaHNZe/1dZcfpAHxqR1kbxqYvKAH+TQ2LTG09NYOV9p3uRy4KvxxoKc0JxsGisP+AGHNZe/1eTTgB9wMCbtu73KH9ypAtOw7lTYN53WG/tNj/7ix36R7U/DesyDcu+xwqr+6kkaHtLYn2ryjQs4xFkc+MFeaJDG4iCOAw78IL7VitHFV06Ls+I0wAMO4luNnsbiwA84xFk84OFczV7KdQEf0sbesQLTsO5Y3GVqnziFZD8SpfHp3jxpLA34QQ6NTbv3ePOfWkvcnqA8FgdxHPi0Y/unywlyaMak8WliaSwN+EEOjU271XjzmivggztXYBrWnQv8Ob0flcKn9BHPfnz+irOf0gc/fCy/0thkfjiliZXH4sAPOMSzNIizOPADDvEsDeIsDvyAQzxLgziLAz/gIY39qSbfuIBDnMUHd67ANKxbFPgfc3jh9u8u+ZO3iL/mEeTQXeJuNbE0Vh7wgxya+beaWBorD/hBDm0dby80sfJYGojjIId2bDxdTsDh0vGtdWy8WOuw1gF+kENb95rGlsfKA36QQ1vH2wtNrDyWFsTyx96wAtOwbljMmWoq8FkBDUyT+6RjblWBaVi3quQ/5nFfEv6hjvdOFfC3GrwG3unMDznrNKzbltmLtMtdfrN7AYd0eWn9aSyWxp4ab4wc4Mu9dLy9nBovbh1oLRYHceMBDziIpxlHY9PEaZDGOg9NHAfjaGJ4oEGclUMzBgc+TQwPNIizcmjG4P/y8fFhLzSxNJa2Qnzl49+gAtOwblDEmWIqMBV4TAWmYV1XZ5er0Cz+JHZ/Afx0PJQvvtXE0thHjbcXa321vrj9gBy5q8angZyAg3jaT8Yfy01jm5O1DvCDHNqx9cXKY+UBP8ihreP5NLHyWBqI4yCHNrhRBaZhXV5IL0Yvyj41aiY6rH+FAw/liaex6fxwShMrj8WBH3CIs3jAwV62Gj1NHA/pcfGtJpYmjof0uPhWE0sTx0N6nD2lickJOMRZHPgBD2n2stXE0sRxSBt7owo8uGHdaNfPM417ivW/fH6enc1OpgI7rMA0rMsfqmblAtaPAM1C669qsOn8IIeu0W01epq5cUhjG8/iwJcHOPxkvHxjgR9wOLZXa5bHygN+wOHS8db4ajy9dVgc+KHx7Fbb5uJQHmscjcUDDeIsDny1B+NogxtVYBrWjQr5OY0XqAYG/E/5Aw8fn7/ibLksDvzP1A88fHz+Ek/jk9mtRk9jcTiWu2prLj/I+Wo8vTwWB364x3hzWwf4AQdrpvG3mhgN+AEHY9L4W02MBuIBH9ywAtOwLi+mOwovVOCbicUDDeKsHBqLA58GeMAhzpbL4sCXB3jAIc6Wy+JBHsRZHNZc/lZbc/kA8sAYHPhbjU4DfjiWm7bNxaGxbLksDnx5gAcc4my5LB7kQZzFYc3lb7U1V2zwgwpMw/pBsTapLtvD+sJMc/nakDT2mHZs/Fe5jTdGDvDpLB5oEGdxWHPb66qtufwg56vx9PJYHPjhHuPNbR3gBxysmcbfamI04AccjEm7Za3MPfhBBaZh/aBYkzoVmAr8bgWmYV1efxfJ27uKOCve7HhIE99qYmksDvyAQ5zFAx7O1ezlVK74qTnFHz3eeu2JxYEfcIizeMDDudotz9qaL28fdYBpWJdX2l2ET4KAbyYvfhzS6HiQQxNP49PE0lga8IMcGpt27/HmP7WWuD1BeSwO4jjwacf2T5cT5NCMSePTxNJYGvCDHBqbdu/x5j+1lrg9DS6owDSsC4r2OcS9xopP+eMSzZiPz1/88Cl9xNmP5RcekuPsKU1MTsAhzuLAX0GDSzRjjAV+wCHO4sBfQYNztZ/kHpvz0vHmMhb4AR9cUIFpWOcVzZ+K/qt2thEuYWnghUgXx0GcBngoV3yriaWxxgI/yKGta6Wx5bHygB/k0Nbx9kITK4+lgTgOcmjHxtPlBBwuHd9ax8aLtQ5rHeAHObR1r2lseaw84Ac5tHW8vdDEymNpII6DHNqx8fTBDyswDeu8gvlkyIuPPW/ED7Im9a0r4B98fOsC/OTw07DOq5aLVvcg7HkjJmsqcF4Fjv3TNOeNfMOsaVjnPXTf0rtIZRuBe7FBOouDeLl40Pjo4mnG0cTSWBrwgxyaMWl8mlgaSwN+kEMzJs1eaGJpLA3EcTCOxuIgTgM84CCeZhyNTROnQRprPzRxHIyjieGBBnFWDs0YHPg0MTzQIM7KoRmDg73QxPBAA/E042hsmjhtcEEFpmFdUFjYef8AAA5ZSURBVLQZMhW4uAIz8KoKTMP65/K5q4I14gI1FPOn5ilNvDnKY0+NF5MTHjW+vX61vnh7kmNfq8anQXksDuI4/GT8sdw01nzBOhBn5dCOrS8mJ8iDOCuHto7n08TkBBqIp8nZauI0KI/FB99UYBrWPxfIiwd6scngBxxcwKexNOCDOA54wEE8jaUBP+AQZ/GAh59q8htrLziksTiI44EGcXEc0lgcxPFAg7g4DmksDuJ4oEGcxYEf8JDG/lSTbxzYCw54wEE8jaUBH8RxwAM++KYC07C+KdCEpwJTgeepwGs1rMfUrctRl6qt6N84Cuk+MdxqYmnsT8fLNw7Wy1k8WEMeu9XoaSwO/GAcjU1jacAPOFx6VmPh0vH2+NV4evtkceCD+jWepQFfHuABhzhbLosHeRBncfjJWe0xGDv4pgLTsL4p0GfYvUP4lD7irBf0x+EXiwP/IP35wsMf4fBbnC2XxYF/SPvzhYc/wuE38TT+Qfpg09iPz1/88Cl9rLn8j8Mvtjz2IP354gc5RHar0dNYHPjBOBq71ehpLA78YByNTWNpwAdxHPg04G81Og34AQdj0vhbTYwG/HAsN00uP+CDbyowDeuvBXKf0IuNLcoPcujsVqOnsTjwg3E0dqvR01gc+ME4GrvV6GksDvxgHI1NY2nADzisufytJp8G/ICDMWl8GqSxOPBDuexW2+biUB5rHI3FgU8DPOAgnsbfamI04AccjEnjbzUxGvADDsYEfLBUYBrWUoyD64Xir1bAejmKh0Pan684axzRiw+HS8abx9hgToizOKy5/K225vKDPDAmrb2umpg84Ac5NDat8fQ0Fgd+MI72Ta0+5MsDfmg8m8bKA37AYc3lbzX5NOAHHIxJ66yrJiYP+EEOjU1rPD2NxUGuD30AHywVmIa1FONM17fwZ6ZO2gtWQMN4wW2/x5anYf31OWtGweVp0TQ2TRyHNH4QP6aniZebxqaxOPADDnEWD3g4V7OXU7nip+YUf/R467UnFgd+wCHO4gEP52r3Pqv9uMSH9jT2swLTsD4L8Wm8WPrUxo8sn/Kf/z15epp4Gp9+zng5co05NV5MHvBD49k0c8lbNTEa8IMcGpv23XjxU7ni5oTyWBzEceDTjq1PlxPk0IxJ49PE0lga8IMcGpt27/HmP7WWuD1BeSwO9ioH8HfA2WechvXPpfIjQSgaZ49pX+nHco9pl4w3j3EBhziLAz/gIY09V/tJ7rE5f2O8fVg34BBnceAHPKSx52o/yT025zq++Fvbd29Y/hSDXgR8l52wXoTioVzxtF5Y54wv99h4seZkW4sf5NDXtdLY8lh5wA9yaOt4e6GJlcfSQBwHObRj4+lyAg6Xjm+tY+PFWoe1DvCDHNq61zS2PFYeHFtrHS8u79rx5rBuwMH8adagDT4r8M4Ny4vBi2P91OazLGOmAlOBZ6zAOzcsz8PFJvBfFbPv21bAH2S3nXFmu1kF3rlhdbnJVlDf+vdXc9aL0DS2XHEcjKOzOIjTAA+tJ55mnDyxNJYG/CCHZkwanyaWxtKAH+TQjEmzF5pYGksDcRyMo7E4iNMADziIpxlHY9PEaZDG2g9NHAfjaGJ4oEGclUMzBgc+TQwPNIizcmjG4GAvNDE80EA8zTgamyZOgzQWB3EcjKMNPivwzg3rswRjpgJTgVepwDs3LH96bS83V43fcyyPTRPHoR8jVo1frpxwLDeNLY991Pj2+tX64vYDcuxr1fg0kBNwEE/7yfhjuWlsc7LWAX6QQzu2vlh5rDw4lrtqfHnXjjeHdQMO5k+zBg3o/3lwVu1A3+vrnRuWy3YPP/Tk4+JbTSxNHA/pcfGtJpYmjof0OHtKE5MTcIizOPADHtLsZauJpYnjIT0uvtXE0sTxkB4X32piaeJ4SI+zpzQxOQGHOIvDuhYe5ID4VqOnieMhPS6+1cTSxPGQ7gMioKe9nX3nhvV2D3sOfFYF3rohnFWhX0x654blr1j4hBBcoHoMLB5oEGdxuHS8Nb4aT7dGwCHONp7FgS8P8IBDnC2XxYM8iLM4XHpWY+HS8fb41Xi6PQYc4i6vG8+m8+VBGosDP5TLprHygB9wuPSsxsKx8XSX8OBHQ/wt8VYNa/OEPfjgBSnMbjV6GosDPxhHY7caPY3FgR+Mo7FpLA34AYc1l7/V5NOAH3AwJo2/1cRowA/HctO2uTg0li2XxYEvD/CAQ5wtl8WDPIiL48Df6qsmJg/4AYc1l7/V5NOAH47lpm1zcWgsu+aKvT3epWH5Nj/00HEvCuDTWTzQIM7KobE48LcanQb8cCw3bZuLQ2PZclkc+PIADzjE2XJZPMiDOIvDmsvfamsuP8gDY9L4W02MBvxwLDdtm4tDY9lyWRz48gAPOIin8beaGA34AQdj0vhbTYwG/ICDMWn8rSZGe0u8S8PqUxe2B+0CM6wvjDSXn8dyj2n3GG8fx9ZKs6Yc4NNZPNAgzuKw5nbWVVtz+UHOV+Pp5bE48MM9xpvbOsAPOFgzjb/VxGjgNYIDDsbg8Ey1sre3wrs0rLd6qHPYj4+PKcIuK/AuDauLUbYH6XLTHQGk8YP4MT1NvNy0OCt+TE8TlwdpLB5wiLM48AMe0thzNXs5lStuPjiWJ35MTxM3FtL4QfyYniZebhqbxuLADzjEWTzg4VzNXk7lip+aU/xW45vnbey7NCw/94ceLu6TJODTvdBwSKPjQQ5NPI1PE9tq9DRWDs0YHPg0MTzQIM7KobE43Hu8+a0D/K/Wp8sJOBiTxqcd2z+9PFYOzRgc+DQxPNAgzsqhsTjce7z5rQP8r9anywk4GJPGpx3bP/3t8C4N6+0e7Bx4KrDHChxvWPs7qYtU6E8sJ8T/7+BAOouD+CH85wsPLmCJ4mnG0dg0cRqksafGi8kJxkKclUNb1+LTxOQEGsRZOTRjcGivYniQB+JpxtHYNHEapLE4iONgHI3FQZwGeLAfmniacTSxNJYG/CCHZkwanyaWxtKAH+TQjEmzF5pYGksDcRyMo7E4iNMADziIpxlHY9PEaW+Jd2lYXlzQJzxv+bDn0FOBV6/AuzQsdwCwXni++rOb/U8F3q4C79KwtpeYHjTNX3UA33LTWBzEaYAHjY8mnmYcjU0Tp0Eae2q8mJxgLMRZObR1LT5NTE6gQZyVQzPmXz4+PmjtVQwP8kA8zTgamyZOgzQWB3EcjKOxOIjTAA/2QxNPM44mlsbSgB/k0IxJ49PE0lga8IMcmjFp9kITS2NpII6DcTQWB3Ea4AEH8TTjaGyaOO0t8S4N6y0f7hx6KrC3Crxzw/KnlgtMcL/l2a4anwZywrHcNLa8a8ebx9rAD9agmX+riaWx8oAf5NDW8XyaWHksDcRxkLPVxGkgJ+AgnvaT8cdy09jmZK0D/CCHdmx9sfJYecAPcmjreD5NrDyWBuI4yNlq4jSQE3AQT2s8nQ/8t8U7NywX8F4AsL4AcBBPx0OaeBpLZ4M4DdJYHMTxQIM4iwM/4CGN/akm3ziwFxzwgIN4GksDPojjgAccxNNYGvBBHAc84CCextKAH3CIs3jAw081+Y21FxzSWBzE8UCDuDgOaSwO4niggb8WpJHR8Uvw8mPeuWG9/MObA7xVBXxg5N7srQ69Pew7Nyx/TccFJvRCYOmhesVZOXQvIBzSWDzIgzgrh3ZsPF1OwCHONp7FgS8PcHAuHPBQLpvGygN+wOHYXh8x3hpfrU9vnywO/NB4dqttc3EojzWOxuKBBnEWh3vUyrx+VPRM7QV/S7xzw/LgQw8f98IAfjoejmnlsuXxj+Ue08plG88ey01bc/l01jjg0wAPOIin8beaGA344Vhu2jYXh8ay5bI48OUBHnCIs+WyeJAHcRaHNZe/1dZcfpAHxqTxt5oYDfjhWG7aNheHxrJrrtjb450b1rGH735gRTlePEGczp7SxOQBPxhHY7caPY3FgR+Mo7FbjZ7G4sAPxtHYNJYG/IDDmsvfavJpwA84GJPG32piNOCHY7lp21wcGsuWy+LAlwd4wCHOlsviQR7EWRzWXP5WW3P5QR4YE/DBUoFpWEsxDq4XiotNcMl5kP588cMf4fBbnDXuIH2wOLg8/fj8hYdP6SPOGkdn8UCDOIvDmsvfamsuP8gDY9La66qJyQN+kENj0xpPT2Nx4AfjaGzatePNY07gBxzWtfhbTT4N+AEHY9La66qJyQN+kENj0xpPT2NxkOv1B3za4LMC07A+CzFmKjAVeP4KTMP66zNyZxBcnhZNY9PEcUjjB/Fjepp4uWlsGosDP+AQZ/GAh3M1ezmVK35qTvFHj7dee2Jx4Acc4iwe8PAX7UDoB/Pnix/ufVbruMQH/p8NzG9/q8A0rL/Vod+9QHwSA+4W0vEghy6exqeJbTV6GiuHZgwOfJoYHmgQZ+XQWBzuPd781gH+V+vT5QQcjEnj047tn14eK4dmDA58mhgeaBBn5dBYHO493vzWAf5X69PlBBzs1TjAB0sFpmEtxRh3KjAVeO4KTMN67ufzTLv7yQXwT3Kf6YyzlyevwF0a1pOfebZ3ugKajX8sbpvlkyyxVceP/ejiE641b/ypwE0qMA3rJmXc1STuUPxTJttDuWsRW3X8WMM6Nn4dN/5U4KIKTMO6qGwzaCowFfiNCkzD+o2q72nNOctU4IEVmIb1wGLPUlOBqcB1FZiGdV39ZvRUYCrwwApMw3pgsWepqcBrV+D3dz8N6/efwexgKjAVOLMC07DOLNSkTQWmAr9fgWlYv/8MZgdTganAmRWYhnVmoa5PmxmmAlOBayswDevaCs74qcBU4GEVmIb1sFLPQlOBqcC1FZiGdW0FZ/xU4J8rMMqdKjAN606FnWmnAlOB21dgGtbtazozTgWmAneqwDSsOxV2pp0KTAVuX4H/DwAA//9sB2hHAAAABklEQVQDAB9QlitZA9bLAAAAAElFTkSuQmCC", - width: "248", - height: "248", - style: { mixBlendMode: "multiply" } - } - ) - )); + style: { width: "100%", height: "100%" }, + children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)( + "image", + { + href: "data:image/png;base64,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", + width: "248", + height: "248", + style: { mixBlendMode: "multiply" } + } + ) + } + ) }); } // routes/connectors-home/ai-plugin-callout.tsx +var import_jsx_runtime43 = __toESM(require_jsx_runtime()); var AI_PLUGIN_SLUG = "ai"; var AI_PLUGIN_PAGE_SLUG = "ai-wp-admin"; var AI_PLUGIN_ID = "ai/ai"; @@ -12204,14 +12448,14 @@ function AiPluginCallout() { ); setJustActivated(true); createSuccessNotice( - (0, import_i18n8.__)("AI plugin installed and activated successfully."), + (0, import_i18n9.__)("AI plugin installed and activated successfully."), { id: "ai-plugin-install-success", type: "snackbar" } ); } catch { - createErrorNotice((0, import_i18n8.__)("Failed to install the AI plugin."), { + createErrorNotice((0, import_i18n9.__)("Failed to install the AI plugin."), { id: "ai-plugin-install-error", type: "snackbar" }); @@ -12229,12 +12473,12 @@ function AiPluginCallout() { { throwOnError: true } ); setJustActivated(true); - createSuccessNotice((0, import_i18n8.__)("AI plugin activated successfully."), { + createSuccessNotice((0, import_i18n9.__)("AI plugin activated successfully."), { id: "ai-plugin-activate-success", type: "snackbar" }); } catch { - createErrorNotice((0, import_i18n8.__)("Failed to activate the AI plugin."), { + createErrorNotice((0, import_i18n9.__)("Failed to activate the AI plugin."), { id: "ai-plugin-activate-error", type: "snackbar" }); @@ -12260,63 +12504,70 @@ function AiPluginCallout() { const hideButtons = pluginStatus === "not-installed" && canInstallPlugins === false; const getMessage = () => { if (isJustConnected) { - return (0, import_i18n8.__)( + return (0, import_i18n9.__)( "The AI plugin is ready to use. You can use it to generate featured images, alt text, titles, excerpts and more. Learn more" ); } if (isActiveNoProvider) { - return (0, import_i18n8.__)( + return (0, import_i18n9.__)( "The AI plugin is installed. Connect an AI provider below to generate featured images, alt text, titles, excerpts, and more. Learn more" ); } - return (0, import_i18n8.__)( + return (0, import_i18n9.__)( "The AI plugin can use your AI connectors to generate featured images, alt text, titles, excerpts and more. Learn more" ); }; const getPrimaryButtonProps = () => { if (pluginStatus === "not-installed") { return { - label: isBusy ? (0, import_i18n8.__)("Installing\u2026") : (0, import_i18n8.__)("Install the AI plugin"), + label: isBusy ? (0, import_i18n9.__)("Installing\u2026") : (0, import_i18n9.__)("Install the AI plugin"), disabled: isBusy, onClick: isBusy ? void 0 : installPlugin }; } return { - label: isBusy ? (0, import_i18n8.__)("Activating\u2026") : (0, import_i18n8.__)("Activate the AI plugin"), + label: isBusy ? (0, import_i18n9.__)("Activating\u2026") : (0, import_i18n9.__)("Activate the AI plugin"), disabled: isBusy, onClick: isBusy ? void 0 : activatePlugin }; }; - return /* @__PURE__ */ React.createElement("div", { className: "ai-plugin-callout" }, /* @__PURE__ */ React.createElement("div", { className: "ai-plugin-callout__content" }, /* @__PURE__ */ React.createElement("p", null, (0, import_element35.createInterpolateElement)(getMessage(), { - strong: /* @__PURE__ */ React.createElement("strong", null), - // @ts-expect-error `children` is injected by `createInterpolateElement` at runtime. - a: /* @__PURE__ */ React.createElement(import_components3.ExternalLink, { href: AI_PLUGIN_URL }) - })), !hideButtons && (showInstallActivate ? /* @__PURE__ */ React.createElement( - import_components3.Button, - { - variant: "primary", - size: "compact", - isBusy, - disabled: getPrimaryButtonProps().disabled, - accessibleWhenDisabled: true, - onClick: getPrimaryButtonProps().onClick - }, - getPrimaryButtonProps().label - ) : /* @__PURE__ */ React.createElement( - import_components3.Button, - { - ref: actionButtonRef, - variant: "secondary", - size: "compact", - href: (0, import_url.addQueryArgs)("options-general.php", { - page: AI_PLUGIN_PAGE_SLUG - }) - }, - (0, import_i18n8.__)("Control features in the AI plugin") - ))), /* @__PURE__ */ React.createElement(WpLogoDecoration, null)); + return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "ai-plugin-callout", children: [ + /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "ai-plugin-callout__content", children: [ + /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("p", { children: (0, import_element35.createInterpolateElement)(getMessage(), { + strong: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("strong", {}), + // @ts-expect-error `children` is injected by `createInterpolateElement` at runtime. + a: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_components3.ExternalLink, { href: AI_PLUGIN_URL }) + }) }), + !hideButtons && (showInstallActivate ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)( + import_components3.Button, + { + variant: "primary", + size: "compact", + isBusy, + disabled: getPrimaryButtonProps().disabled, + accessibleWhenDisabled: true, + onClick: getPrimaryButtonProps().onClick, + children: getPrimaryButtonProps().label + } + ) : /* @__PURE__ */ (0, import_jsx_runtime43.jsx)( + import_components3.Button, + { + ref: actionButtonRef, + variant: "secondary", + size: "compact", + href: (0, import_url.addQueryArgs)("options-general.php", { + page: AI_PLUGIN_PAGE_SLUG + }), + children: (0, import_i18n9.__)("Control features in the AI plugin") + } + )) + ] }), + /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(WpLogoDecoration, {}) + ] }); } // routes/connectors-home/stage.tsx +var import_jsx_runtime44 = __toESM(require_jsx_runtime()); var { store } = unlock2(connectorsPrivateApis2); registerDefaultConnectors(); function ConnectorsPage() { @@ -12349,7 +12600,9 @@ function ConnectorsPage() { (connector) => connector.type === "ai_provider" ).map( (connector) => connector.plugin?.file?.split("/")[0] - ).filter((slug) => !!slug) + ).filter( + (slug) => !!slug + ) ) ).sort(); const installedPluginSlugs = new Set( @@ -12366,86 +12619,96 @@ function ConnectorsPage() { (slug) => !installedPluginSlugs.has(slug) ); const isEmpty = renderableConnectors.length === 0; - return /* @__PURE__ */ React.createElement( + return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)( page_default, { - title: (0, import_i18n9.__)("Connectors"), - subTitle: (0, import_i18n9.__)( + title: (0, import_i18n10.__)("Connectors"), + subTitle: (0, import_i18n10.__)( "All of your API keys and credentials are stored here and shared across plugins. Configure once and use everywhere." - ) - }, - /* @__PURE__ */ React.createElement( - "div", - { - className: `connectors-page${isEmpty ? " connectors-page--empty" : ""}` - }, - manualInstallPluginSlugs.length > 0 && (isFileModDisabled || !canInstallPlugins) && /* @__PURE__ */ React.createElement( - notice_exports.Root, - { - intent: "info", - className: "connectors-page__file-mods-notice" - }, - /* @__PURE__ */ React.createElement(notice_exports.Description, null, isFileModDisabled ? (0, import_i18n9.__)( - "Plugins cannot be installed here due to your site configuration. Install them manually using your normal deployment workflow." - ) : (0, import_i18n9.__)( - "You do not have permission to install plugins. Please ask a site administrator to install them for you." - )) ), - isEmpty ? /* @__PURE__ */ React.createElement( - import_components4.__experimentalVStack, + children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)( + "div", { - alignment: "center", - spacing: 3, - style: { maxWidth: 480 } - }, - /* @__PURE__ */ React.createElement(import_components4.__experimentalVStack, { alignment: "center", spacing: 2 }, /* @__PURE__ */ React.createElement(import_components4.__experimentalHeading, { level: 2, size: 15 }, (0, import_i18n9.__)("No connectors yet")), /* @__PURE__ */ React.createElement(import_components4.__experimentalText, { size: 12 }, (0, import_i18n9.__)( - "Connectors appear here when you install plugins that use external services. Each plugin registers the API keys it needs, and you manage them all in one place." - ))), - /* @__PURE__ */ React.createElement( - import_components4.Button, - { - variant: "secondary", - href: "plugin-install.php", - __next40pxDefaultSize: true - }, - (0, import_i18n9.__)("Learn more") - ) - ) : /* @__PURE__ */ React.createElement(import_components4.__experimentalVStack, { spacing: 3 }, /* @__PURE__ */ React.createElement(AiPluginCallout, null), /* @__PURE__ */ React.createElement(import_components4.__experimentalVStack, { spacing: 3, role: "list" }, connectors.map( - (connector) => { - if (connector.render) { - return /* @__PURE__ */ React.createElement( - connector.render, + className: `connectors-page${isEmpty ? " connectors-page--empty" : ""}`, + children: [ + manualInstallPluginSlugs.length > 0 && (isFileModDisabled || !canInstallPlugins) && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)( + notice_exports.Root, { - key: connector.slug, - slug: connector.slug, - name: connector.name, - description: connector.description, - type: connector.type, - logo: connector.logo, - authentication: connector.authentication, - plugin: connector.plugin + intent: "info", + className: "connectors-page__file-mods-notice", + children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(notice_exports.Description, { children: isFileModDisabled ? (0, import_i18n10.__)( + "Plugins cannot be installed here due to your site configuration. Install them manually using your normal deployment workflow." + ) : (0, import_i18n10.__)( + "You do not have permission to install plugins. Please ask a site administrator to install them for you." + ) }) } - ); - } - return null; - } - ))), - canInstallPlugins && !isFileModDisabled && /* @__PURE__ */ React.createElement("p", null, (0, import_element36.createInterpolateElement)( - (0, import_i18n9.__)( - "If the connector you need is not listed, search the plugin directory to see if a connector is available." - ), - { - a: ( - // eslint-disable-next-line jsx-a11y/anchor-has-content - /* @__PURE__ */ React.createElement("a", { href: "plugin-install.php?s=connector&tab=search&type=tag" }) - ) + ), + isEmpty ? /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)( + import_components4.__experimentalVStack, + { + alignment: "center", + spacing: 3, + style: { maxWidth: 480 }, + children: [ + /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_components4.__experimentalVStack, { alignment: "center", spacing: 2, children: [ + /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_components4.__experimentalHeading, { level: 2, size: 15, children: (0, import_i18n10.__)("No connectors yet") }), + /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_components4.__experimentalText, { size: 12, children: (0, import_i18n10.__)( + "Connectors appear here when you install plugins that use external services. Each plugin registers the API keys it needs, and you manage them all in one place." + ) }) + ] }), + /* @__PURE__ */ (0, import_jsx_runtime44.jsx)( + import_components4.Button, + { + variant: "secondary", + href: "plugin-install.php", + __next40pxDefaultSize: true, + children: (0, import_i18n10.__)("Learn more") + } + ) + ] + } + ) : /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_components4.__experimentalVStack, { spacing: 3, children: [ + /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(AiPluginCallout, {}), + /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_components4.__experimentalVStack, { spacing: 3, role: "list", children: connectors.map( + (connector) => { + if (connector.render) { + return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)( + connector.render, + { + slug: connector.slug, + name: connector.name, + description: connector.description, + type: connector.type, + logo: connector.logo, + authentication: connector.authentication, + plugin: connector.plugin + }, + connector.slug + ); + } + return null; + } + ) }) + ] }), + canInstallPlugins && !isFileModDisabled && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("p", { children: (0, import_element36.createInterpolateElement)( + (0, import_i18n10.__)( + "If the connector you need is not listed, search the plugin directory to see if a connector is available." + ), + { + a: ( + // eslint-disable-next-line jsx-a11y/anchor-has-content + /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("a", { href: "plugin-install.php?s=connector&tab=search&type=tag" }) + ) + } + ) }) + ] } - )) - ) + ) + } ); } function Stage() { - return /* @__PURE__ */ React.createElement(ConnectorsPage, null); + return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(ConnectorsPage, {}); } var stage = Stage; export { diff --git a/src/wp-includes/build/routes/connectors-home/content.min.asset.php b/src/wp-includes/build/routes/connectors-home/content.min.asset.php index ebf36d49cadba..1dda70de8f9a3 100644 --- a/src/wp-includes/build/routes/connectors-home/content.min.asset.php +++ b/src/wp-includes/build/routes/connectors-home/content.min.asset.php @@ -1 +1 @@ - array('react', 'react-dom', 'react-jsx-runtime', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-element', 'wp-i18n', 'wp-notices', 'wp-primitives', 'wp-private-apis', 'wp-theme', 'wp-url'), 'module_dependencies' => array(array('id' => '@wordpress/a11y', 'import' => 'static'), array('id' => '@wordpress/connectors', 'import' => 'static'), array('id' => '@wordpress/route', 'import' => 'static')), 'version' => '5dd79b91fcc9e57d6786'); \ No newline at end of file + array('react', 'react-dom', 'react-jsx-runtime', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-element', 'wp-i18n', 'wp-notices', 'wp-primitives', 'wp-private-apis', 'wp-theme', 'wp-url', 'wp-warning'), 'module_dependencies' => array(array('id' => '@wordpress/a11y', 'import' => 'static'), array('id' => '@wordpress/connectors', 'import' => 'static'), array('id' => '@wordpress/route', 'import' => 'static')), 'version' => '9c97839e08e086000847'); \ No newline at end of file diff --git a/src/wp-includes/build/routes/connectors-home/content.min.js b/src/wp-includes/build/routes/connectors-home/content.min.js index a126dc05f98d2..2296c11a9ccd8 100644 --- a/src/wp-includes/build/routes/connectors-home/content.min.js +++ b/src/wp-includes/build/routes/connectors-home/content.min.js @@ -1,4 +1,4 @@ -var If=Object.create;var Rr=Object.defineProperty;var Mf=Object.getOwnPropertyDescriptor;var Bf=Object.getOwnPropertyNames;var Hf=Object.getPrototypeOf,zf=Object.prototype.hasOwnProperty;var Re=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),Ot=(e,t)=>{for(var o in t)Rr(e,o,{get:t[o],enumerable:!0})},Df=(e,t,o,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of Bf(t))!zf.call(e,r)&&r!==o&&Rr(e,r,{get:()=>t[r],enumerable:!(n=Mf(t,r))||n.enumerable});return e};var b=(e,t,o)=>(o=e!=null?If(Hf(e)):{},Df(t||!e||!e.__esModule?Rr(o,"default",{value:e,enumerable:!0}):o,e));var lt=Re((M0,ea)=>{ea.exports=window.wp.i18n});var ce=Re((H0,oa)=>{oa.exports=window.wp.element});var z=Re((z0,na)=>{na.exports=window.React});var K=Re((U0,aa)=>{aa.exports=window.ReactJSXRuntime});var Mt=Re((Zh,Ia)=>{Ia.exports=window.ReactDOM});var Fc=Re(jc=>{"use strict";var ho=z();function Vm(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var Wm=typeof Object.is=="function"?Object.is:Vm,Ym=ho.useState,Um=ho.useEffect,Gm=ho.useLayoutEffect,Xm=ho.useDebugValue;function Km(e,t){var o=t(),n=Ym({inst:{value:o,getSnapshot:t}}),r=n[0].inst,i=n[1];return Gm(function(){r.value=o,r.getSnapshot=t,ci(r)&&i({inst:r})},[e,o,t]),Um(function(){return ci(r)&&i({inst:r}),e(function(){ci(r)&&i({inst:r})})},[e]),Xm(o),o}function ci(e){var t=e.getSnapshot;e=e.value;try{var o=t();return!Wm(e,o)}catch{return!0}}function qm(e,t){return t()}var Zm=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?qm:Km;jc.useSyncExternalStore=ho.useSyncExternalStore!==void 0?ho.useSyncExternalStore:Zm});var li=Re((z1,Vc)=>{"use strict";Vc.exports=Fc()});var Yc=Re(Wc=>{"use strict";var Dn=z(),Qm=li();function Jm(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var $m=typeof Object.is=="function"?Object.is:Jm,eg=Qm.useSyncExternalStore,tg=Dn.useRef,og=Dn.useEffect,ng=Dn.useMemo,rg=Dn.useDebugValue;Wc.useSyncExternalStoreWithSelector=function(e,t,o,n,r){var i=tg(null);if(i.current===null){var s={hasValue:!1,value:null};i.current=s}else s=i.current;i=ng(function(){function l(m){if(!c){if(c=!0,d=m,m=n(m),r!==void 0&&s.hasValue){var u=s.value;if(r(u,m))return f=u}return f=m}if(u=f,$m(d,m))return u;var g=n(m);return r!==void 0&&r(u,g)?(d=m,u):(d=m,f=g)}var c=!1,d,f,p=o===void 0?null:o;return[function(){return l(t())},p===null?void 0:function(){return l(p())}]},[t,o,n,r]);var a=eg(e,i[0],i[1]);return og(function(){s.hasValue=!0,s.value=a},[a]),rg(a),a}});var Gc=Re((j1,Uc)=>{"use strict";Uc.exports=Yc()});var $t=Re((g4,xd)=>{xd.exports=window.wp.primitives});var Od=Re((H4,Ad)=>{Ad.exports=window.wp.theme});var ts=Re((z4,Nd)=>{Nd.exports=window.wp.privateApis});var tn=Re((P3,Gu)=>{Gu.exports=window.wp.components});var nn=Re((j3,ef)=>{ef.exports=window.wp.data});var hr=Re((F3,tf)=>{tf.exports=window.wp.coreData});var Us=Re((Y3,nf)=>{nf.exports=window.wp.notices});var sf=Re((U3,rf)=>{rf.exports=window.wp.url});function ta(e){var t,o,n="";if(typeof e=="string"||typeof e=="number")n+=e;else if(typeof e=="object")if(Array.isArray(e)){var r=e.length;for(t=0;te();function Y(e){let t=Se(Wf).current;return t.next=e,Vf(t.effect),t.trampoline}function Wf(){let e={next:void 0,callback:Yf,trampoline:(...t)=>e.callback?.(...t),effect:()=>{e.callback=e.next}};return e}function Yf(){}var sa=b(z(),1),Uf=()=>{},D=typeof document<"u"?sa.useLayoutEffect:Uf;var bn=b(z(),1),Er=bn.createContext(void 0);function so(){return bn.useContext(Er)?.direction??"ltr"}function Gf(e,t){return function(n,...r){let i=new URL(e);return i.searchParams.set("code",n.toString()),r.forEach(s=>i.searchParams.append("args[]",s)),`${t} error #${n}; visit ${i} for the full message.`}}var Xf=Gf("https://base-ui.com/production-error","Base UI"),ke=Xf;var Wt=b(z(),1);function Tr(e,t,o,n){let r=Se(la).current;return Kf(r,e,t,o,n)&&da(r,[e,t,o,n]),r.callback}function ca(e){let t=Se(la).current;return qf(t,e)&&da(t,e),t.callback}function la(){return{callback:null,cleanup:null,refs:[]}}function Kf(e,t,o,n,r){return e.refs[0]!==t||e.refs[1]!==o||e.refs[2]!==n||e.refs[3]!==r}function qf(e,t){return e.refs.length!==t.length||e.refs.some((o,n)=>o!==t[n])}function da(e,t){if(e.refs=t,t.every(o=>o==null)){e.callback=null;return}e.callback=o=>{if(e.cleanup&&(e.cleanup(),e.cleanup=null),o!=null){let n=Array(t.length).fill(null);for(let r=0;r{for(let r=0;r=e}function kr(e){if(!fa.isValidElement(e))return null;let t=e,o=t.props;return(ao(19)?o?.ref:t.ref)??null}function Mo(e,t){if(e&&!t)return e;if(!e&&t)return t;if(e||t)return{...e,...t}}function Nt(){}var eh=Object.freeze([]),be=Object.freeze({});function pa(e,t){let o={};for(let n in e){let r=e[n];if(t?.hasOwnProperty(n)){let i=t[n](r);i!=null&&Object.assign(o,i);continue}r===!0?o[`data-${n.toLowerCase()}`]="":r&&(o[`data-${n.toLowerCase()}`]=r.toString())}return o}function ma(e,t){return typeof e=="function"?e(t):e}function ga(e,t){return typeof e=="function"?e(t):e}var Pr={};function we(e,t,o,n,r){if(!o&&!n&&!r&&!e)return hn(t);let i=hn(e);return t&&(i=Bo(i,t)),o&&(i=Bo(i,o)),n&&(i=Bo(i,n)),r&&(i=Bo(i,r)),i}function ba(e){if(e.length===0)return Pr;if(e.length===1)return hn(e[0]);let t=hn(e[0]);for(let o=1;o=65&&r<=90&&(typeof t=="function"||typeof t>"u")}function Cr(e){return typeof e=="function"}function wa(e,t){return Cr(e)?e(t):e??Pr}function $f(e,t){return t?e?(...o)=>{let n=o[0];if(_a(n)){let i=n;Ho(i);let s=t(...o);return i.baseUIHandlerPrevented||e?.(...o),s}let r=t(...o);return e?.(...o),r}:va(t):e}function va(e){return e&&((...t)=>{let o=t[0];return _a(o)&&Ho(o),e(...t)})}function Ho(e){return e.preventBaseUIHandler=()=>{e.baseUIHandlerPrevented=!0},e}function Ar(e,t){return t?e?t+" "+e:t:e}function _a(e){return e!=null&&typeof e=="object"&&"nativeEvent"in e}var Or=b(z(),1);function Pe(e,t,o={}){let n=t.render,r=ep(t,o);if(o.enabled===!1)return null;let i=o.state??be;return np(e,n,r,i)}function ep(e,t={}){let{className:o,style:n,render:r}=e,{state:i=be,ref:s,props:a,stateAttributesMapping:l,enabled:c=!0}=t,d=c?ma(o,i):void 0,f=c?ga(n,i):void 0,p=c?pa(i,l):be,m=c&&a?tp(a):void 0,u=c?Mo(p,m)??{}:be;return typeof document<"u"&&(c?Array.isArray(s)?u.ref=ca([u.ref,kr(r),...s]):u.ref=Tr(u.ref,kr(r),s):Tr(null,null)),c?(d!==void 0&&(u.className=Ar(u.className,d)),f!==void 0&&(u.style=Mo(u.style,f)),u):be}function tp(e){return Array.isArray(e)?ba(e):we(void 0,e)}var op=Symbol.for("react.lazy");function np(e,t,o,n){if(t){if(typeof t=="function")return t(o,n);let r=we(o,t.props);r.ref=o.ref;let i=t;return i?.$$typeof===op&&(i=Wt.Children.toArray(t)[0]),Wt.cloneElement(i,r)}if(e&&typeof e=="string")return rp(e,o);throw new Error(ke(8))}function rp(e,t){return e==="button"?(0,Or.createElement)("button",{type:"button",...t,key:t.key}):e==="img"?(0,Or.createElement)("img",{alt:"",...t,key:t.key}):Wt.createElement(e,t)}var wn=b(z(),1);var ya=0;function ip(e,t="mui"){let[o,n]=wn.useState(e),r=e||o;return wn.useEffect(()=>{o==null&&(ya+=1,n(`${t}-${ya}`))},[o,t]),r}var xa=Io.useId;function Lt(e,t){if(xa!==void 0){let o=xa();return e??(t?`${t}-${o}`:o)}return ip(e,t)}function Ra(e){return Lt(e,"base-ui")}var U={};Ot(U,{cancelOpen:()=>Lp,chipRemovePress:()=>gp,clearPress:()=>mp,closePress:()=>fp,closeWatcher:()=>Tp,decrementPress:()=>wp,disabled:()=>Mp,drag:()=>Ap,escapeKey:()=>Ep,focusOut:()=>Sp,imperativeAction:()=>zp,incrementPress:()=>hp,initial:()=>Hp,inputBlur:()=>yp,inputChange:()=>vp,inputClear:()=>_p,inputPaste:()=>xp,inputPress:()=>Rp,itemPress:()=>up,keyboard:()=>Pp,linkPress:()=>pp,listNavigation:()=>kp,missing:()=>Bp,none:()=>sp,outsidePress:()=>dp,pointer:()=>Cp,scrub:()=>Np,siblingOpen:()=>Ip,swipe:()=>Dp,trackPress:()=>bp,triggerFocus:()=>lp,triggerHover:()=>cp,triggerPress:()=>ap,wheel:()=>Op,windowResize:()=>jp});var sp="none",ap="trigger-press",cp="trigger-hover",lp="trigger-focus",dp="outside-press",up="item-press",fp="close-press",pp="link-press",mp="clear-press",gp="chip-remove-press",bp="track-press",hp="increment-press",wp="decrement-press",vp="input-change",_p="input-clear",yp="input-blur",xp="input-paste",Rp="input-press",Sp="focus-out",Ep="escape-key",Tp="close-watcher",kp="list-navigation",Pp="keyboard",Cp="pointer",Ap="drag",Op="wheel",Np="scrub",Lp="cancel-open",Ip="sibling-open",Mp="disabled",Bp="missing",Hp="initial",zp="imperative-action",Dp="swipe",jp="window-resize";function ee(e,t,o,n){let r=!1,i=!1,s=n??be;return{reason:e,event:t??new Event("base-ui"),cancel(){r=!0},allowPropagation(){i=!0},get isCanceled(){return r},get isPropagationAllowed(){return i},trigger:o,...s}}var Lr=b(z(),1);var Sa=b(z(),1),Fp=[];function co(e){Sa.useEffect(e,Fp)}var vn=null,kh=globalThis.requestAnimationFrame,Nr=class{callbacks=[];callbacksCount=0;nextId=1;startId=1;isScheduled=!1;tick=t=>{this.isScheduled=!1;let o=this.callbacks,n=this.callbacksCount;if(this.callbacks=[],this.callbacksCount=0,this.startId=this.nextId,n>0)for(let r=0;r=this.callbacks.length||(this.callbacks[o]=null,this.callbacksCount-=1)}},_n=new Nr,dt=class e{static create(){return new e}static request(t){return _n.request(t)}static cancel(t){return _n.cancel(t)}currentId=vn;request(t){this.cancel(),this.currentId=_n.request(()=>{this.currentId=vn,t()})}cancel=()=>{this.currentId!==vn&&(_n.cancel(this.currentId),this.currentId=vn)};disposeEffect=()=>this.cancel};function lo(){let e=Se(dt.create).current;return co(e.disposeEffect),e}function Ea(e,t=!1,o=!1){let[n,r]=Lr.useState(e&&t?"idle":void 0),[i,s]=Lr.useState(e);return e&&!i&&(s(!0),r("starting")),!e&&i&&n!=="ending"&&!o&&r("ending"),!e&&!i&&n==="ending"&&r(void 0),D(()=>{if(!e&&i&&n!=="ending"&&o){let a=dt.request(()=>{r("ending")});return()=>{dt.cancel(a)}}},[e,i,n,o]),D(()=>{if(!e||t)return;let a=dt.request(()=>{r(void 0)});return()=>{dt.cancel(a)}},[t,e]),D(()=>{if(!e||!t)return;e&&i&&n!=="idle"&&r("starting");let a=dt.request(()=>{r("idle")});return()=>{dt.cancel(a)}},[t,e,i,n]),{mounted:i,setMounted:s,transitionStatus:n}}var Yt=(function(e){return e.startingStyle="data-starting-style",e.endingStyle="data-ending-style",e})({}),Vp={[Yt.startingStyle]:""},Wp={[Yt.endingStyle]:""},Ta={transitionStatus(e){return e==="starting"?Vp:e==="ending"?Wp:null}};var fo=b(z(),1);function yn(){return typeof window<"u"}function Gt(e){return xn(e)?(e.nodeName||"").toLowerCase():"#document"}function me(e){var t;return(e==null||(t=e.ownerDocument)==null?void 0:t.defaultView)||window}function ft(e){var t;return(t=(xn(e)?e.ownerDocument:e.document)||window.document)==null?void 0:t.documentElement}function xn(e){return yn()?e instanceof Node||e instanceof me(e).Node:!1}function F(e){return yn()?e instanceof Element||e instanceof me(e).Element:!1}function ye(e){return yn()?e instanceof HTMLElement||e instanceof me(e).HTMLElement:!1}function uo(e){return!yn()||typeof ShadowRoot>"u"?!1:e instanceof ShadowRoot||e instanceof me(e).ShadowRoot}function zo(e){let{overflow:t,overflowX:o,overflowY:n,display:r}=Ie(e);return/auto|scroll|overlay|hidden|clip/.test(t+n+o)&&r!=="inline"&&r!=="contents"}function ka(e){return/^(table|td|th)$/.test(Gt(e))}function Do(e){try{if(e.matches(":popover-open"))return!0}catch{}try{return e.matches(":modal")}catch{return!1}}var Yp=/transform|translate|scale|rotate|perspective|filter/,Up=/paint|layout|strict|content/,Ut=e=>!!e&&e!=="none",Ir;function Rn(e){let t=F(e)?Ie(e):e;return Ut(t.transform)||Ut(t.translate)||Ut(t.scale)||Ut(t.rotate)||Ut(t.perspective)||!Sn()&&(Ut(t.backdropFilter)||Ut(t.filter))||Yp.test(t.willChange||"")||Up.test(t.contain||"")}function Pa(e){let t=ut(e);for(;ye(t)&&!pt(t);){if(Rn(t))return t;if(Do(t))return null;t=ut(t)}return null}function Sn(){return Ir==null&&(Ir=typeof CSS<"u"&&CSS.supports&&CSS.supports("-webkit-backdrop-filter","none")),Ir}function pt(e){return/^(html|body|#document)$/.test(Gt(e))}function Ie(e){return me(e).getComputedStyle(e)}function jo(e){return F(e)?{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}:{scrollLeft:e.scrollX,scrollTop:e.scrollY}}function ut(e){if(Gt(e)==="html")return e;let t=e.assignedSlot||e.parentNode||uo(e)&&e.host||ft(e);return uo(t)?t.host:t}function Ca(e){let t=ut(e);return pt(t)?(e.ownerDocument||e).body:ye(t)&&zo(t)?t:Ca(t)}function It(e,t,o){var n;t===void 0&&(t=[]),o===void 0&&(o=!0);let r=Ca(e),i=r===((n=e.ownerDocument)==null?void 0:n.body),s=me(r);if(i){let a=En(s);return t.concat(s,s.visualViewport||[],zo(r)?r:[],a&&o?It(a):[])}else return t.concat(r,It(r,[],o))}function En(e){return e.parent&&Object.getPrototypeOf(e.parent)?e.frameElement:null}var Tn=b(z(),1),Gp=Tn.createContext(void 0);function Aa(e=!1){let t=Tn.useContext(Gp);if(t===void 0&&!e)throw new Error(ke(16));return t}var Oa=b(z(),1);function Na(e){let{focusableWhenDisabled:t,disabled:o,composite:n=!1,tabIndex:r=0,isNativeButton:i}=e,s=n&&t!==!1,a=n&&t===!1;return{props:Oa.useMemo(()=>{let c={onKeyDown(d){o&&t&&d.key!=="Tab"&&d.preventDefault()}};return n||(c.tabIndex=r,!i&&o&&(c.tabIndex=t?r:-1)),(i&&(t||s)||!i&&o)&&(c["aria-disabled"]=o),i&&(!t||a)&&(c.disabled=o),c},[n,o,t,s,a,i,r])}}function La(e={}){let{disabled:t=!1,focusableWhenDisabled:o,tabIndex:n=0,native:r=!0,composite:i}=e,s=fo.useRef(null),a=Aa(!0),l=i??a!==void 0,{props:c}=Na({focusableWhenDisabled:o,disabled:t,composite:l,tabIndex:n,isNativeButton:r}),d=fo.useCallback(()=>{let m=s.current;Mr(m)&&l&&t&&c.disabled===void 0&&m.disabled&&(m.disabled=!1)},[t,c.disabled,l]);D(d,[d]);let f=fo.useCallback((m={})=>{let{onClick:u,onMouseDown:g,onKeyUp:v,onKeyDown:_,onPointerDown:w,...y}=m;return we({onClick(h){if(t){h.preventDefault();return}u?.(h)},onMouseDown(h){t||g?.(h)},onKeyDown(h){if(t||(Ho(h),_?.(h),h.baseUIHandlerPrevented))return;let T=h.target===h.currentTarget,x=h.currentTarget,R=Mr(x),E=!r&&Xp(x),k=T&&(r?R:!E),C=h.key==="Enter",W=h.key===" ",O=x.getAttribute("role"),L=O?.startsWith("menuitem")||O==="option"||O==="gridcell";if(T&&l&&W){if(h.defaultPrevented&&L)return;h.preventDefault(),E||r&&R?(x.click(),h.preventBaseUIHandler()):k&&(u?.(h),h.preventBaseUIHandler());return}k&&(!r&&(W||C)&&h.preventDefault(),!r&&C&&u?.(h))},onKeyUp(h){if(!t){if(Ho(h),v?.(h),h.target===h.currentTarget&&r&&l&&Mr(h.currentTarget)&&h.key===" "){h.preventDefault();return}h.baseUIHandlerPrevented||h.target===h.currentTarget&&!r&&!l&&h.key===" "&&u?.(h)}},onPointerDown(h){if(t){h.preventDefault();return}w?.(h)}},r?{type:"button"}:{role:"button"},c,y)},[t,c,l,r]),p=Y(m=>{s.current=m,d()});return{getButtonProps:f,buttonRef:p}}function Mr(e){return ye(e)&&e.tagName==="BUTTON"}function Xp(e){return!!(e?.tagName==="A"&&e?.href)}function re(e,t,o,n){return e.addEventListener(t,o,n),()=>{e.removeEventListener(t,o,n)}}function He(e){let t=Se(Kp,e).current;return t.next=e,D(t.effect),t}function Kp(e){let t={current:e,next:e,effect:()=>{t.current=t.next}};return t}function xe(e){return e?.ownerDocument||document}var Ha=b(z(),1);var Ba=b(Mt(),1);function Ma(e){return e==null?e:"current"in e?e.current:e}function po(e,t=!1,o=!0){let n=lo();return Y((r,i=null)=>{n.cancel();let s=Ma(e);if(s==null)return;let a=s,l=()=>{Ba.flushSync(r)};if(typeof a.getAnimations!="function"||globalThis.BASE_UI_ANIMATIONS_DISABLED){r();return}function c(){Promise.all(a.getAnimations().map(d=>d.finished)).then(()=>{i?.aborted||l()}).catch(()=>{if(o){i?.aborted||l();return}let d=a.getAnimations();!i?.aborted&&d.length>0&&d.some(f=>f.pending||f.playState!=="finished")&&c()})}if(t){let d=Yt.startingStyle;if(!a.hasAttribute(d)){n.request(c);return}let f=new MutationObserver(()=>{a.hasAttribute(d)||(f.disconnect(),c())});f.observe(a,{attributes:!0,attributeFilter:[d]}),i?.addEventListener("abort",()=>f.disconnect(),{once:!0});return}n.request(c)})}function kn(e){let{enabled:t=!0,open:o,ref:n,onComplete:r}=e,i=Y(r),s=po(n,o,!1);Ha.useEffect(()=>{if(!t)return;let a=new AbortController;return s(i,a.signal),()=>{a.abort()}},[t,o,i,s])}var za=b(z(),1);function Da(e){let t=za.useRef(!0);t.current&&(t.current=!1,e())}var Rt={};Ot(Rt,{engine:()=>jr,env:()=>Vr,os:()=>zr,screenReader:()=>Fr});var zr={};Ot(zr,{android:()=>Va,apple:()=>Hr,ios:()=>Br,linux:()=>$p,mac:()=>Wa,windows:()=>Jp});function qp(){return typeof navigator>"u"?{userAgent:"",platform:"",maxTouchPoints:0}:{userAgent:navigator.userAgent,platform:navigator.platform??"",maxTouchPoints:navigator.maxTouchPoints??0}}var{userAgent:Zp,platform:Qp,maxTouchPoints:ja}=qp(),Xt=Zp.toLowerCase(),Kt=Qp.toLowerCase();var Br=/^i(os$|p)/.test(Kt)||Kt==="macintel"&&ja>1,Fa="android",Va=Kt===Fa||Xt.includes(Fa),Wa=!Br&&Kt.startsWith("mac"),Jp=Kt.startsWith("win"),$p=!Va&&/^(linux|chrome os)/.test(Kt),Hr=Wa||Br;var jr={};Ot(jr,{blink:()=>tm,gecko:()=>em,webkit:()=>Dr});var Dr=typeof CSS<"u"&&!!CSS.supports?.("-webkit-backdrop-filter:none"),em=!Dr&&Xt.includes("firefox"),tm=!Dr&&Xt.includes("chrom");var Fr={};Ot(Fr,{voiceOver:()=>om});var om=Hr;var Vr={};Ot(Vr,{jsdom:()=>nm});var nm=/jsdom|happydom/.test(Xt);var Fo=0,We=class e{static create(){return new e}currentId=Fo;start(t,o){this.clear(),this.currentId=setTimeout(()=>{this.currentId=Fo,o()},t)}isStarted(){return this.currentId!==Fo}clear=()=>{this.currentId!==Fo&&(clearTimeout(this.currentId),this.currentId=Fo)};disposeEffect=()=>this.clear};function ot(){let e=Se(We.create).current;return co(e.disposeEffect),e}var Ce=b(z(),1);function Ya(e){return"nativeEvent"in e}function St(e,t){let o=["mouse","pen"];return t||o.push("",void 0),o.includes(e)}function Ua(e){let t=e.type;return t==="click"||t==="mousedown"||t==="keydown"||t==="keyup"}var Wr="data-base-ui-focusable";var Yr="input:not([type='hidden']):not([disabled]),[contenteditable]:not([contenteditable='false']),textarea:not([disabled])";function Pn(e){let t=e.activeElement;for(;t?.shadowRoot?.activeElement!=null;)t=t.shadowRoot.activeElement;return t}function ie(e,t){if(!e||!t)return!1;let o=t.getRootNode?.();if(e.contains(t))return!0;if(o&&uo(o)){let n=t;for(;n;){if(e===n)return!0;n=n.parentNode||n.host}}return!1}function Me(e){return"composedPath"in e?e.composedPath()[0]:e.target}function Bt(e,t){if(!F(e))return!1;let o=e;if(t.hasElement(o))return!o.hasAttribute("data-trigger-disabled");for(let[,n]of t.entries())if(ie(n,o))return!n.hasAttribute("data-trigger-disabled");return!1}function Cn(e,t){if(t==null)return!1;if("composedPath"in e)return e.composedPath().includes(t);let o=e;return o.target!=null&&t.contains(o.target)}function Ga(e){return e.matches("html,body")}function Xa(e){return ye(e)&&e.matches(Yr)}function Ur(e){return e?.closest(`button,a[href],[role="button"],select,[tabindex]:not([tabindex="-1"]),${Yr}`)!=null}function Ka(e){if(!e||Rt.env.jsdom)return!0;try{return e.matches(":focus-visible")}catch{return!0}}function rm(e,t){return t!=null&&!St(t)?0:typeof e=="function"?e():e}function Et(e,t,o){let n=rm(e,o);return typeof n=="number"?n:n?.[t]}function Gr(e){return typeof e=="function"?e():e}function An(e,t){return t||e==="click"||e==="mousedown"}function qa(e){return e?.includes("mouse")&&e!=="mousedown"}var Za=b(K(),1),Qa=Ce.createContext({hasProvider:!1,timeoutMs:0,delayRef:{current:0},initialDelayRef:{current:0},timeout:new We,currentIdRef:{current:null},currentContextRef:{current:null}});function im(e,t){e.current=t.current}function Xr(e){let{children:t,delay:o,timeoutMs:n=0}=e,r=Ce.useRef(o),i=Ce.useRef(o),s=Ce.useRef(null),a=Ce.useRef(null),l=ot();return D(()=>{if(i.current=o,!s.current){r.current=o;return}r.current={open:Et(r.current,"open"),close:Et(o,"close")}},[o,s,r,i]),(0,Za.jsx)(Qa.Provider,{value:Ce.useMemo(()=>({hasProvider:!0,delayRef:r,initialDelayRef:i,currentIdRef:s,timeoutMs:n,currentContextRef:a,timeout:l}),[n,l]),children:t})}function Kr(e,t={open:!1}){let{open:o}=t,n="rootStore"in e?e.rootStore:e,r=n.useState("floatingId"),i=Ce.useContext(Qa),{currentIdRef:s,delayRef:a,timeoutMs:l,initialDelayRef:c,currentContextRef:d,hasProvider:f,timeout:p}=i,[m,u]=Ce.useState(!1),g=Ce.useRef(o),v=Ce.useRef(!1);return D(()=>{g.current=o},[o]),D(()=>()=>{v.current=!0},[]),D(()=>{function _(){v.current||u(!1),d.current?.setIsInstantPhase(!1),s.current=null,d.current=null,a.current=c.current,p.clear()}if(s.current&&!o&&s.current===r){if(u(!1),l){let w=r;return p.start(l,()=>{n.select("open")||s.current&&s.current!==w||_()}),()=>{(g.current||s.current!==w)&&p.clear()}}_()}},[o,r,s,a,l,c,d,p,n]),D(()=>{if(!o)return;let _=d.current,w=s.current;p.clear(),d.current={onOpenChange:n.setOpen,setIsInstantPhase:u},s.current=r,a.current={open:0,close:Et(c.current,"close")},w!==null&&w!==r?(u(!0),_?.setIsInstantPhase(!0),_?.onOpenChange(!1,ee(U.none))):(u(!1),_?.setIsInstantPhase(!1))},[o,r,n,s,a,c,d,p]),D(()=>()=>{if(s.current===r){if(d.current=null,!g.current)return;s.current=null,im(a,c),p.clear()}},[d,s,a,r,c,p]),Ce.useMemo(()=>({hasProvider:f,delayRef:a,isInstantPhase:m}),[f,a,m])}function nt(...e){return()=>{for(let t=0;t({x:e,y:e}),sm={left:"right",right:"left",bottom:"top",top:"bottom"};function Nn(e,t,o){return rt(e,Ht(t,o))}function it(e,t){return typeof e=="function"?e(t):e}function Ae(e){return e.split("-")[0]}function st(e){return e.split("-")[1]}function Ln(e){return e==="x"?"y":"x"}function Yo(e){return e==="y"?"height":"width"}function ze(e){let t=e[0];return t==="t"||t==="b"?"y":"x"}function Uo(e){return Ln(ze(e))}function tc(e,t,o){o===void 0&&(o=!1);let n=st(e),r=Uo(e),i=Yo(r),s=r==="x"?n===(o?"end":"start")?"right":"left":n==="start"?"bottom":"top";return t.reference[i]>t.floating[i]&&(s=Vo(s)),[s,Vo(s)]}function oc(e){let t=Vo(e);return[On(e),t,On(t)]}function On(e){return e.includes("start")?e.replace("start","end"):e.replace("end","start")}var Ja=["left","right"],$a=["right","left"],am=["top","bottom"],cm=["bottom","top"];function lm(e,t,o){switch(e){case"top":case"bottom":return o?t?$a:Ja:t?Ja:$a;case"left":case"right":return t?am:cm;default:return[]}}function nc(e,t,o,n){let r=st(e),i=lm(Ae(e),o==="start",n);return r&&(i=i.map(s=>s+"-"+r),t&&(i=i.concat(i.map(On)))),i}function Vo(e){let t=Ae(e);return sm[t]+e.slice(t.length)}function dm(e){var t,o,n,r;return{top:(t=e.top)!=null?t:0,right:(o=e.right)!=null?o:0,bottom:(n=e.bottom)!=null?n:0,left:(r=e.left)!=null?r:0}}function In(e){return typeof e!="number"?dm(e):{top:e,right:e,bottom:e,left:e}}function qt(e){let{x:t,y:o,width:n,height:r}=e;return{width:n,height:r,top:o,left:t,right:t+n,bottom:o+r,x:t,y:o}}function Tt(e,t,o=!0){return e.filter(r=>r.parentId===t).flatMap(r=>[...!o||r.context?.open?[r]:[],...Tt(e,r.id,o)])}function mo(e){return`data-base-ui-${e}`}var Ye=b(z(),1),sc=b(Mt(),1);var rc={style:{transition:"none"}};var um="data-base-ui-swipe-ignore",fm="data-swipe-ignore",zw=`[${um}]`,Dw=`[${fm}]`;var ic={fallbackAxisSide:"end"};var ac=b(K(),1),pm=Ye.createContext(null),mm=()=>Ye.useContext(pm),gm=mo("portal");function qr(e={}){let{ref:t,container:o,componentProps:n=be,elementProps:r}=e,i=Lt(),a=mm()?.portalNode,[l,c]=Ye.useState(null),[d,f]=Ye.useState(null),p=Y(v=>{v!==null&&f(v)}),m=Ye.useRef(null);D(()=>{if(o===null){m.current&&(m.current=null,f(null),c(null));return}if(i==null)return;let v=(o&&(xn(o)?o:o.current))??a??document.body;if(v==null){m.current&&(m.current=null,f(null),c(null));return}m.current!==v&&(m.current=v,f(null),c(v))},[o,a,i]);let u=Pe("div",n,{ref:[t,p],props:[{id:i,[gm]:""},r]});return{portalNode:d,portalSubtree:l&&u?sc.createPortal(u,l):null}}var Zt=b(z(),1);function cc(){let e=new Map;return{emit(t,o){e.get(t)?.forEach(n=>n(o))},on(t,o){e.has(t)||e.set(t,new Set),e.get(t).add(o)},off(t,o){e.get(t)?.delete(o)}}}var bm=b(K(),1),hm=Zt.createContext(null),wm=Zt.createContext(null),go=()=>Zt.useContext(hm)?.id||null,Dt=e=>{let t=Zt.useContext(wm);return e??t};var De=b(z(),1);function vm(e,t){let o=null,n=null,r=!1;return{contextElement:e||void 0,getBoundingClientRect(){let i=e?.getBoundingClientRect()||{width:0,height:0,x:0,y:0},s=t.axis==="x"||t.axis==="both",a=t.axis==="y"||t.axis==="both",l=["mouseenter","mousemove"].includes(t.dataRef.current.openEvent?.type||"")&&t.pointerType!=="touch",c=i.width,d=i.height,f=i.x,p=i.y;return o==null&&t.x&&s&&(o=i.x-t.x),n==null&&t.y&&a&&(n=i.y-t.y),f-=o||0,p-=n||0,c=0,d=0,!r||l?(c=t.axis==="y"?i.width:0,d=t.axis==="x"?i.height:0,f=s&&t.x!=null?t.x:f,p=a&&t.y!=null?t.y:p):r&&!l&&(d=t.axis==="x"?i.height:d,c=t.axis==="y"?i.width:c),r=!0,{width:c,height:d,x:f,y:p,top:p,right:f+c,bottom:p+d,left:f}}}}function lc(e){return e!=null&&e.clientX!=null}function Zr(e,t={}){let{enabled:o=!0,axis:n="both"}=t,r="rootStore"in e?e.rootStore:e,i=r.useState("open"),s=r.useState("floatingElement"),a=r.useState("domReferenceElement"),l=r.context.dataRef,c=De.useRef(!1),d=De.useRef(null),[f,p]=De.useState(),[m,u]=De.useState([]),g=Y(h=>{r.set("positionReference",h)}),v=Y((h,T,x)=>{c.current||l.current.openEvent&&!lc(l.current.openEvent)||r.set("positionReference",vm(x??a,{x:h,y:T,axis:n,dataRef:l,pointerType:f}))}),_=Y(h=>{i?d.current||(v(h.clientX,h.clientY,h.currentTarget),u([])):v(h.clientX,h.clientY,h.currentTarget)}),w=St(f)?s:i;De.useEffect(()=>{if(!o){g(a);return}if(!w)return;function h(){d.current?.(),d.current=null}let T=me(s);function x(R){let E=Me(R);ie(s,E)?h():v(R.clientX,R.clientY)}return!l.current.openEvent||lc(l.current.openEvent)?d.current=re(T,"mousemove",x):g(a),h},[w,o,s,l,a,r,v,g,m]),De.useEffect(()=>()=>{r.set("positionReference",null)},[r]),De.useEffect(()=>{o&&!s&&(c.current=!1)},[o,s]),De.useEffect(()=>{!o&&i&&(c.current=!0)},[o,i]);let y=De.useMemo(()=>{function h(T){p(T.pointerType)}return{onPointerDown:h,onPointerEnter:h,onMouseMove:_,onMouseEnter:_}},[_]);return De.useMemo(()=>o?{reference:y,trigger:y}:{},[o,y])}var je=b(z(),1);function _m(){return!1}function ym(e){return{escapeKey:typeof e=="boolean"?e:e?.escapeKey??!1,outsidePress:typeof e=="boolean"?e:e?.outsidePress??!0}}function Qr(e,t={}){let{enabled:o=!0,escapeKey:n=!0,outsidePress:r=!0,outsidePressEvent:i="sloppy",referencePress:s=_m,bubbles:a,externalTree:l}=t,c="rootStore"in e?e.rootStore:e,d=c.useState("open"),f=c.useState("floatingElement"),{dataRef:p}=c.context,m=Dt(l),u=Y(typeof r=="function"?r:()=>!1),g=typeof r=="function"?u:r,v=g!==!1,_=Y(()=>i),{escapeKey:w,outsidePress:y}=ym(a),h=je.useRef(!1),T=je.useRef(!1),x=je.useRef(!1),R=je.useRef(!1),E=je.useRef(""),k=je.useRef(null),C=ot(),W=ot(),O=Y(()=>{W.clear(),p.current.insideReactTree=!1}),L=Y(V=>{let oe=p.current.floatingContext?.nodeId;return(m?Tt(m.nodesRef.current,oe):[]).some(se=>se.context?.open&&!se.context.dataRef.current[V])}),I=Y(V=>Cn(V,c.select("floatingElement"))||Cn(V,c.select("domReferenceElement"))),S=Y(V=>{s()&&c.setOpen(!1,ee(U.triggerPress,V.nativeEvent))}),N=Y(V=>{if(!d||!o||!n||V.key!=="Escape"||R.current||!w&&L("__escapeKeyBubbles"))return;let oe=Ya(V)?V.nativeEvent:V,te=ee(U.escapeKey,oe);c.setOpen(!1,te),te.isCanceled||V.preventDefault(),!w&&!te.isPropagationAllowed&&V.stopPropagation()}),H=Y(()=>{p.current.insideReactTree=!0,W.start(0,O)}),P=Y(V=>{if(!d||!o||V.button!==0)return;let oe=Me(V.nativeEvent);ie(c.select("floatingElement"),oe)&&(h.current||(h.current=!0,T.current=!1))}),A=Y(V=>{!d||!o||(V.defaultPrevented||V.nativeEvent.defaultPrevented)&&h.current&&(T.current=!0)});je.useEffect(()=>{if(!d||!o)return;p.current.__escapeKeyBubbles=w,p.current.__outsidePressBubbles=y;let V=new We,oe=new We;function te(){V.clear(),R.current=!0}function se(){V.start(Rt.engine.webkit?5:0,()=>{R.current=!1})}function G(){x.current=!0,oe.start(0,()=>{x.current=!1})}function q(){h.current=!1,T.current=!1}function J(){let B=E.current,j=B==="pen"||!B?"mouse":B,he=_(),Te=typeof he=="function"?he():he;return typeof Te=="string"?Te:Te[j]}function ne(B){let j=J();return j==="intentional"&&B.type!=="click"||j==="sloppy"&&B.type==="click"}function ge(B){let j=p.current.floatingContext?.nodeId,he=m&&Tt(m.nodesRef.current,j).some(Te=>Cn(B,Te.context?.elements.floating));return I(B)||he}function de(B){if(ne(B)){B.type!=="click"&&!I(B)&&(oe.clear(),x.current=!1),O();return}if(p.current.insideReactTree){O();return}let j=Me(B),he=`[${mo("inert")}]`,Te=F(j)?j.getRootNode():null,Pt=Array.from((uo(Te)?Te:xe(c.select("floatingElement"))).querySelectorAll(he)),No=c.context.triggerElements;if(j&&(No.hasElement(j)||No.hasMatchingElement(Ve=>ie(Ve,j))))return;let yt=F(j)?j:null;for(;yt&&!pt(yt);){let Ve=ut(yt);if(pt(Ve)||!F(Ve))break;yt=Ve}if(!(Pt.length&&F(j)&&!Ga(j)&&!ie(j,c.select("floatingElement"))&&Pt.every(Ve=>!ie(yt,Ve)))){if(ye(j)&&!("touches"in B)){let Ve=pt(j),Ct=Ie(j),At=/auto|scroll/,dn=Ve||At.test(Ct.overflowX),un=Ve||At.test(Ct.overflowY),fn=dn&&j.clientWidth>0&&j.scrollWidth>j.clientWidth,pn=un&&j.clientHeight>0&&j.scrollHeight>j.clientHeight,mn=Ct.direction==="rtl",ae=pn&&(mn?B.offsetX<=j.offsetWidth-j.clientWidth:B.offsetX>j.clientWidth),Le=fn&&B.offsetY>j.clientHeight;if(ae||Le)return}if(!ge(B)){if(J()==="intentional"&&x.current){oe.clear(),x.current=!1;return}typeof g=="function"&&!g(B)||L("__outsidePressBubbles")||(c.setOpen(!1,ee(U.outsidePress,B)),O())}}}function X(B){J()!=="sloppy"||B.pointerType==="touch"||!c.select("open")||!o||I(B)||de(B)}function pe(B){if(J()!=="sloppy"||!c.select("open")||!o||I(B))return;let j=B.touches[0];j&&(k.current={startTime:Date.now(),startX:j.clientX,startY:j.clientY,dismissOnTouchEnd:!1,dismissOnMouseDown:!0},C.start(1e3,()=>{k.current&&(k.current.dismissOnTouchEnd=!1,k.current.dismissOnMouseDown=!1)}))}function ue(B,j){let he=Me(B);if(!he)return;let Te=re(he,B.type,()=>{j(B),Te()})}function _t(B){E.current="touch",ue(B,pe)}function Ee(B){C.clear(),B.type==="pointerdown"&&(E.current=B.pointerType),!(B.type==="mousedown"&&k.current&&!k.current.dismissOnMouseDown)&&ue(B,j=>{j.type==="pointerdown"?X(j):de(j)})}function Fe(B){if(!h.current)return;let j=T.current;if(q(),J()==="intentional"){if(B.type==="pointercancel"){j&&G();return}if(!ge(B)){if(j){G();return}typeof g=="function"&&!g(B)||(oe.clear(),x.current=!0,O())}}}function Xe(B){if(J()!=="sloppy"||!k.current||I(B))return;let j=B.touches[0];if(!j)return;let he=Math.abs(j.clientX-k.current.startX),Te=Math.abs(j.clientY-k.current.startY),Pt=Math.sqrt(he*he+Te*Te);Pt>5&&(k.current.dismissOnTouchEnd=!0),Pt>10&&(de(B),C.clear(),k.current=null)}function Be(B){ue(B,Xe)}function no(B){J()!=="sloppy"||!k.current||I(B)||(k.current.dismissOnTouchEnd&&de(B),C.clear(),k.current=null)}function ln(B){ue(B,no)}let _e=xe(f),ro=nt(n&&nt(re(_e,"keydown",N),re(_e,"compositionstart",te),re(_e,"compositionend",se)),v&&nt(re(_e,"click",Ee,!0),re(_e,"pointerdown",Ee,!0),re(_e,"pointerup",Fe,!0),re(_e,"pointercancel",Fe,!0),re(_e,"mousedown",Ee,!0),re(_e,"mouseup",Fe,!0),re(_e,"touchstart",_t,!0),re(_e,"touchmove",Be,!0),re(_e,"touchend",ln,!0)));return()=>{ro(),V.clear(),oe.clear(),q(),x.current=!1}},[p,f,n,v,g,d,o,w,y,N,O,_,L,I,m,c,C]),je.useEffect(O,[g,O]);let M=je.useMemo(()=>({onKeyDown:N,onPointerDown:S,onClick:S}),[N,S]),Q=je.useMemo(()=>({onKeyDown:N,onPointerDown:A,onMouseDown:A,onClickCapture:H,onMouseDownCapture(V){H(),P(V)},onPointerDownCapture(V){H(),P(V)},onMouseUpCapture:H,onTouchEndCapture:H,onTouchMoveCapture:H}),[N,H,P,A]);return je.useMemo(()=>o?{reference:M,floating:Q,trigger:M}:{},[o,M,Q])}var Oe=b(z(),1);function dc(e,t,o){let{reference:n,floating:r}=e,i=ze(t),s=Uo(t),a=Yo(s),l=Ae(t),c=i==="y",d=n.x+n.width/2-r.width/2,f=n.y+n.height/2-r.height/2,p=n[a]/2-r[a]/2,m;switch(l){case"top":m={x:d,y:n.y-r.height};break;case"bottom":m={x:d,y:n.y+n.height};break;case"right":m={x:n.x+n.width,y:f};break;case"left":m={x:n.x-r.width,y:f};break;default:m={x:n.x,y:n.y}}let u=st(t);return u&&(m[s]+=p*(u==="end"?1:-1)*(o&&c?-1:1)),m}async function pc(e,t){var o;t===void 0&&(t={});let{x:n,y:r,platform:i,rects:s,elements:a,strategy:l}=e,{boundary:c="clippingAncestors",rootBoundary:d="viewport",elementContext:f="floating",altBoundary:p=!1,padding:m=0}=it(t,e),u=In(m),v=a[p?f==="floating"?"reference":"floating":f],_=qt(await i.getClippingRect({element:(o=await(i.isElement==null?void 0:i.isElement(v)))==null||o?v:v.contextElement||await(i.getDocumentElement==null?void 0:i.getDocumentElement(a.floating)),boundary:c,rootBoundary:d,strategy:l})),w=f==="floating"?{x:n,y:r,width:s.floating.width,height:s.floating.height}:s.reference,y=await(i.getOffsetParent==null?void 0:i.getOffsetParent(a.floating)),h=await(i.isElement==null?void 0:i.isElement(y))&&await(i.getScale==null?void 0:i.getScale(y))||{x:1,y:1},T=qt(i.convertOffsetParentRelativeRectToViewportRelativeRect?await i.convertOffsetParentRelativeRectToViewportRelativeRect({elements:a,rect:w,offsetParent:y,strategy:l}):w);return{top:(_.top-T.top+u.top)/h.y,bottom:(T.bottom-_.bottom+u.bottom)/h.y,left:(_.left-T.left+u.left)/h.x,right:(T.right-_.right+u.right)/h.x}}var xm=50,mc=async(e,t,o)=>{let{placement:n="bottom",strategy:r="absolute",middleware:i=[],platform:s}=o,a=s.detectOverflow?s:{...s,detectOverflow:pc},l=await(s.isRTL==null?void 0:s.isRTL(t)),c=await s.getElementRects({reference:e,floating:t,strategy:r}),{x:d,y:f}=dc(c,n,l),p=n,m=0,u={};for(let g=0;gI<=0)){var W,O;let I=(((W=i.flip)==null?void 0:W.index)||0)+1,S=R[I];if(S&&(!(f==="alignment"?w!==ze(S):!1)||C.every(P=>ze(P.placement)===w?P.overflows[0]>0:!0)))return{data:{index:I,overflows:C},reset:{placement:S}};let N=(O=C.filter(H=>H.overflows[0]<=0).sort((H,P)=>H.overflows[1]-P.overflows[1])[0])==null?void 0:O.placement;if(!N)switch(m){case"bestFit":{var L;let H=(L=C.filter(P=>{if(x){let A=ze(P.placement);return A===w||A==="y"}return!0}).map(P=>[P.placement,P.overflows.filter(A=>A>0).reduce((A,M)=>A+M,0)]).sort((P,A)=>P[1]-A[1])[0])==null?void 0:L[0];H&&(N=H);break}case"initialPlacement":N=a;break}if(r!==N)return{reset:{placement:N}}}return{}}}};function uc(e,t){return{top:e.top-t.height,right:e.right-t.width,bottom:e.bottom-t.height,left:e.left-t.width}}function fc(e){return ec.some(t=>e[t]>=0)}var bc=function(e){return e===void 0&&(e={}),{name:"hide",options:e,async fn(t){let{rects:o,platform:n}=t,{strategy:r="referenceHidden",...i}=it(e,t);switch(r){case"referenceHidden":{let s=await n.detectOverflow(t,{...i,elementContext:"reference"}),a=uc(s,o.reference);return{data:{referenceHiddenOffsets:a,referenceHidden:fc(a)}}}case"escaped":{let s=await n.detectOverflow(t,{...i,altBoundary:!0}),a=uc(s,o.floating);return{data:{escapedOffsets:a,escaped:fc(a)}}}default:return{}}}}};var hc=new Set(["left","top"]);async function Rm(e,t){let{placement:o,platform:n,elements:r}=e,i=await(n.isRTL==null?void 0:n.isRTL(r.floating)),s=Ae(o),a=st(o),l=ze(o)==="y",c=hc.has(s)?-1:1,d=i&&l?-1:1,f=it(t,e),{mainAxis:p,crossAxis:m,alignmentAxis:u}=typeof f=="number"?{mainAxis:f,crossAxis:0,alignmentAxis:null}:{mainAxis:f.mainAxis||0,crossAxis:f.crossAxis||0,alignmentAxis:f.alignmentAxis};return a&&typeof u=="number"&&(m=a==="end"?u*-1:u),l?{x:m*d,y:p*c}:{x:p*c,y:m*d}}var wc=function(e){return e===void 0&&(e=0),{name:"offset",options:e,async fn(t){var o,n;let{x:r,y:i,placement:s,middlewareData:a}=t,l=await Rm(t,e);return s===((o=a.offset)==null?void 0:o.placement)&&(n=a.arrow)!=null&&n.alignmentOffset?{}:{x:r+l.x,y:i+l.y,data:{...l,placement:s}}}}},vc=function(e){return e===void 0&&(e={}),{name:"shift",options:e,async fn(t){let{x:o,y:n,placement:r,platform:i}=t,{mainAxis:s=!0,crossAxis:a=!1,limiter:l={fn:w=>{let{x:y,y:h}=w;return{x:y,y:h}}},...c}=it(e,t),d={x:o,y:n},f=await i.detectOverflow(t,c),p=ze(r),m=Ln(p),u=d[m],g=d[p],v=(w,y)=>Nn(y+f[w==="y"?"top":"left"],y,y-f[w==="y"?"bottom":"right"]);s&&(u=v(m,u)),a&&(g=v(p,g));let _=l.fn({...t,[m]:u,[p]:g});return{..._,data:{x:_.x-o,y:_.y-n,enabled:{[m]:s,[p]:a}}}}}},_c=function(e){return e===void 0&&(e={}),{options:e,fn(t){var o,n;let{x:r,y:i,placement:s,rects:a,middlewareData:l}=t,{offset:c=0,mainAxis:d=!0,crossAxis:f=!0}=it(e,t),p={x:r,y:i},m=ze(s),u=Ln(m),g=p[u],v=p[m],_=it(c,t),w=typeof _=="number"?{mainAxis:_,crossAxis:0}:{mainAxis:(o=_.mainAxis)!=null?o:0,crossAxis:(n=_.crossAxis)!=null?n:0};if(d){let T=u==="y"?"height":"width",x=a.reference[u]-a.floating[T]+w.mainAxis,R=a.reference[u]+a.reference[T]-w.mainAxis;gR&&(g=R)}if(f){var y,h;let T=u==="y"?"width":"height",x=hc.has(Ae(s)),R=a.reference[m]-a.floating[T]+(x&&((y=l.offset)==null?void 0:y[m])||0)+(x?0:w.crossAxis),E=a.reference[m]+a.reference[T]+(x?0:((h=l.offset)==null?void 0:h[m])||0)-(x?w.crossAxis:0);vE&&(v=E)}return{[u]:g,[m]:v}}}},yc=function(e){return e===void 0&&(e={}),{name:"size",options:e,async fn(t){let{placement:o,rects:n,platform:r,elements:i}=t,{apply:s=()=>{},...a}=it(e,t),l=await r.detectOverflow(t,a),c=Ae(o),d=st(o),f=ze(o)==="y",{width:p,height:m}=n.floating,u,g;c==="top"||c==="bottom"?(u=c,g=d===(await(r.isRTL==null?void 0:r.isRTL(i.floating))?"start":"end")?"left":"right"):(g=c,u=d==="end"?"top":"bottom");let v=m-l.top-l.bottom,_=p-l.left-l.right,w=Ht(m-l[u],v),y=Ht(p-l[g],_),h=t.middlewareData.shift,T=!h,x=w,R=y;h!=null&&h.enabled.x&&(R=_),h!=null&&h.enabled.y&&(x=v),T&&!d&&(f?R=p-2*rt(l.left,l.right):x=m-2*rt(l.top,l.bottom)),await s({...t,availableWidth:R,availableHeight:x});let E=await r.getDimensions(i.floating);return p!==E.width||m!==E.height?{reset:{rects:!0}}:{}}}};function Sc(e){let t=Ie(e),o=parseFloat(t.width)||0,n=parseFloat(t.height)||0,r=ye(e),i=r?e.offsetWidth:o,s=r?e.offsetHeight:n,a=zt(o)!==i||zt(n)!==s;return a&&(o=i,n=s),{width:o,height:n,$:a}}function $r(e){return F(e)?e:e.contextElement}function bo(e){let t=$r(e);if(!ye(t))return mt(1);let o=t.getBoundingClientRect(),{width:n,height:r,$:i}=Sc(t),s=(i?zt(o.width):o.width)/n,a=(i?zt(o.height):o.height)/r;return(!s||!Number.isFinite(s))&&(s=1),(!a||!Number.isFinite(a))&&(a=1),{x:s,y:a}}var Sm=mt(0);function Ec(e){let t=me(e);return!Sn()||!t.visualViewport?Sm:{x:t.visualViewport.offsetLeft,y:t.visualViewport.offsetTop}}function Em(e,t,o){return t===void 0&&(t=!1),!!o&&t&&o===me(e)}function Qt(e,t,o,n){t===void 0&&(t=!1),o===void 0&&(o=!1);let r=e.getBoundingClientRect(),i=$r(e),s=mt(1);t&&(n?F(n)&&(s=bo(n)):s=bo(e));let a=Em(i,o,n)?Ec(i):mt(0),l=(r.left+a.x)/s.x,c=(r.top+a.y)/s.y,d=r.width/s.x,f=r.height/s.y;if(i&&n){let p=me(i),m=F(n)?me(n):n,u=p,g=En(u);for(;g&&m!==u;){let v=bo(g),_=g.getBoundingClientRect(),w=Ie(g),y=_.left+(g.clientLeft+parseFloat(w.paddingLeft))*v.x,h=_.top+(g.clientTop+parseFloat(w.paddingTop))*v.y;l*=v.x,c*=v.y,d*=v.x,f*=v.y,l+=y,c+=h,u=me(g),g=En(u)}}return qt({width:d,height:f,x:l,y:c})}function Mn(e,t){let o=jo(e).scrollLeft;return t?t.left+o:Qt(ft(e)).left+o}function Tc(e,t){let o=e.getBoundingClientRect(),n=o.left+t.scrollLeft-Mn(e,o),r=o.top+t.scrollTop;return{x:n,y:r}}function Tm(e){let{elements:t,rect:o,offsetParent:n,strategy:r}=e,i=r==="fixed",s=ft(n),a=t?Do(t.floating):!1;if(n===s||a&&i)return o;let l={scrollLeft:0,scrollTop:0},c=mt(1),d=mt(0),f=ye(n);if((f||!i)&&((Gt(n)!=="body"||zo(s))&&(l=jo(n)),f)){let m=Qt(n);c=bo(n),d.x=m.x+n.clientLeft,d.y=m.y+n.clientTop}let p=s&&!f&&!i?Tc(s,l):mt(0);return{width:o.width*c.x,height:o.height*c.y,x:o.x*c.x-l.scrollLeft*c.x+d.x+p.x,y:o.y*c.y-l.scrollTop*c.y+d.y+p.y}}function km(e){return e.getClientRects?Array.from(e.getClientRects()):[]}function Pm(e){let t=jo(e),o=e.ownerDocument.body,n=rt(e.scrollWidth,e.clientWidth,o.scrollWidth,o.clientWidth),r=rt(e.scrollHeight,e.clientHeight,o.scrollHeight,o.clientHeight),i=-t.scrollLeft+Mn(e),s=-t.scrollTop;return Ie(o).direction==="rtl"&&(i+=rt(e.clientWidth,o.clientWidth)-n),{width:n,height:r,x:i,y:s}}var Cm=25;function Am(e,t,o){o===void 0&&(o="viewport");let n=o==="layoutViewport",r=me(e),i=ft(e),s=r.visualViewport,a=i.clientWidth,l=i.clientHeight,c=0,d=0;if(s){let p=!Sn()||t==="fixed";n?p||(c=-s.offsetLeft,d=-s.offsetTop):(a=s.width,l=s.height,p&&(c=s.offsetLeft,d=s.offsetTop))}if(Mn(i)<=0){let p=i.ownerDocument,m=p.body,u=getComputedStyle(m),g=p.compatMode==="CSS1Compat"&&parseFloat(u.marginLeft)+parseFloat(u.marginRight)||0,v=Math.abs(i.clientWidth-m.clientWidth-g),_=getComputedStyle(i).scrollbarGutter==="stable both-edges"?v/2:v;_<=Cm&&(a-=_)}return{width:a,height:l,x:c,y:d}}function Om(e,t){let o=Qt(e,!0,t==="fixed"),n=o.top+e.clientTop,r=o.left+e.clientLeft,i=bo(e),s=e.clientWidth*i.x,a=e.clientHeight*i.y,l=r*i.x,c=n*i.y;return{width:s,height:a,x:l,y:c}}function xc(e,t,o){let n;if(t==="viewport"||t==="layoutViewport")n=Am(e,o,t);else if(t==="document")n=Pm(ft(e));else if(F(t))n=Om(t,o);else{let r=Ec(e);n={x:t.x-r.x,y:t.y-r.y,width:t.width,height:t.height}}return qt(n)}function Nm(e,t){let o=t.get(e);if(o)return o;let n=It(e,[],!1).filter(a=>F(a)&&Gt(a)!=="body"),r=null,i=Ie(e).position==="fixed",s=i?ut(e):e;for(;F(s)&&!pt(s);){let a=Ie(s),l=Rn(s),c=r?r.position:i?"fixed":"";!l&&(c==="fixed"||c==="absolute"&&a.position==="static")?n=n.filter(f=>f!==s):r=a,s=ut(s)}return t.set(e,n),n}function Lm(e){let{element:t,boundary:o,rootBoundary:n,strategy:r}=e,s=[...o==="clippingAncestors"?Do(t)?[]:Nm(t,this._c):[].concat(o),n],a=xc(t,s[0],r),l=a.top,c=a.right,d=a.bottom,f=a.left;for(let p=1;p{a(!1,1e-7)},1e3)}R=!1}try{n=new IntersectionObserver(E,{...x,root:i.ownerDocument})}catch{n=new IntersectionObserver(E,x)}n.observe(e)}let l=me(e),c=()=>a(o);return l.addEventListener("resize",c),a(!0),()=>{l.removeEventListener("resize",c),s()}}function Go(e,t,o,n){n===void 0&&(n={});let{ancestorScroll:r=!0,ancestorResize:i=!0,elementResize:s=typeof ResizeObserver=="function",layoutShift:a=typeof IntersectionObserver=="function",animationFrame:l=!1}=n,c=$r(e),d=r||i?[...c?It(c):[],...t?It(t):[]]:[];d.forEach(_=>{r&&_.addEventListener("scroll",o),i&&_.addEventListener("resize",o)});let f=c&&a?zm(c,o,i):null,p=-1,m=null;s&&(m=new ResizeObserver(_=>{let[w]=_;w&&w.target===c&&m&&t&&(m.unobserve(t),cancelAnimationFrame(p),p=requestAnimationFrame(()=>{var y;(y=m)==null||y.observe(t)})),o()}),c&&!l&&m.observe(c),t&&m.observe(t));let u,g=l?Qt(e):null;l&&v();function v(){let _=Qt(e);g&&!Pc(g,_)&&o(),g=_,u=requestAnimationFrame(v)}return o(),()=>{var _;d.forEach(w=>{r&&w.removeEventListener("scroll",o),i&&w.removeEventListener("resize",o)}),f?.(),(_=m)==null||_.disconnect(),m=null,l&&cancelAnimationFrame(u)}}var Cc=wc;var Ac=vc,Oc=gc,Nc=yc,Lc=bc;var Ic=_c,Bn=(e,t,o)=>{let n=new Map,r=o??{},i={...ei,...r.platform,_c:n};return mc(e,t,{...r,platform:i})};var ve=b(z(),1),Bc=b(z(),1),Hc=b(Mt(),1),jm=typeof document<"u",Fm=function(){},Hn=jm?Bc.useLayoutEffect:Fm;function zn(e,t){if(e===t)return!0;if(typeof e!=typeof t)return!1;if(typeof e=="function"&&e.toString()===t.toString())return!0;let o,n,r;if(e&&t&&typeof e=="object"){if(Array.isArray(e)){if(o=e.length,o!==t.length)return!1;for(n=o;n--!==0;)if(!zn(e[n],t[n]))return!1;return!0}if(r=Object.keys(e),o=r.length,o!==Object.keys(t).length)return!1;for(n=o;n--!==0;)if(!{}.hasOwnProperty.call(t,r[n]))return!1;for(n=o;n--!==0;){let i=r[n];if(!(i==="_owner"&&e.$$typeof)&&!zn(e[i],t[i]))return!1}return!0}return e!==e&&t!==t}function zc(e){return typeof window>"u"?1:(e.ownerDocument.defaultView||window).devicePixelRatio||1}function Mc(e,t){let o=zc(e);return Math.round(t*o)/o}function ti(e){let t=ve.useRef(e);return Hn(()=>{t.current=e}),t}function Dc(e){e===void 0&&(e={});let{placement:t="bottom",strategy:o="absolute",middleware:n=[],platform:r,elements:{reference:i,floating:s}={},transform:a=!0,whileElementsMounted:l,open:c}=e,[d,f]=ve.useState({x:0,y:0,strategy:o,placement:t,middlewareData:{},isPositioned:!1}),[p,m]=ve.useState(n);zn(p,n)||m(n);let[u,g]=ve.useState(null),[v,_]=ve.useState(null),w=ve.useCallback(P=>{P!==x.current&&(x.current=P,g(P))},[]),y=ve.useCallback(P=>{P!==R.current&&(R.current=P,_(P))},[]),h=i||u,T=s||v,x=ve.useRef(null),R=ve.useRef(null),E=ve.useRef(d),k=l!=null,C=ti(l),W=ti(r),O=ti(c),L=ve.useCallback(()=>{if(!x.current||!R.current)return;let P={placement:t,strategy:o,middleware:p};W.current&&(P.platform=W.current),Bn(x.current,R.current,P).then(A=>{let M={...A,isPositioned:O.current!==!1};I.current&&!zn(E.current,M)&&(E.current=M,Hc.flushSync(()=>{f(M)}))})},[p,t,o,W,O]);Hn(()=>{c===!1&&E.current.isPositioned&&(E.current.isPositioned=!1,f(P=>({...P,isPositioned:!1})))},[c]);let I=ve.useRef(!1);Hn(()=>(I.current=!0,()=>{I.current=!1}),[]),Hn(()=>{if(h&&(x.current=h),T&&(R.current=T),h&&T){if(C.current)return C.current(h,T,L);L()}},[h,T,L,C,k]);let S=ve.useMemo(()=>({reference:x,floating:R,setReference:w,setFloating:y}),[w,y]),N=ve.useMemo(()=>({reference:h,floating:T}),[h,T]),H=ve.useMemo(()=>{let P={position:o,left:0,top:0};if(!N.floating)return P;let A=Mc(N.floating,d.x),M=Mc(N.floating,d.y);return a?{...P,transform:"translate("+A+"px, "+M+"px)",...zc(N.floating)>=1.5&&{willChange:"transform"}}:{position:o,left:A,top:M}},[o,a,N.floating,d.x,d.y]);return ve.useMemo(()=>({...d,update:L,refs:S,elements:N,floatingStyles:H}),[d,L,S,N,H])}var oi=(e,t)=>{let o=Cc(e);return{name:o.name,fn:o.fn,options:[e,t]}},ni=(e,t)=>{let o=Ac(e);return{name:o.name,fn:o.fn,options:[e,t]}},ri=(e,t)=>({fn:Ic(e).fn,options:[e,t]}),ii=(e,t)=>{let o=Oc(e);return{name:o.name,fn:o.fn,options:[e,t]}},si=(e,t)=>{let o=Nc(e);return{name:o.name,fn:o.fn,options:[e,t]}};var ai=(e,t)=>{let o=Lc(e);return{name:o.name,fn:o.fn,options:[e,t]}};var vo=b(z(),1),tl=b(Mt(),1);var $c=b(z(),1);var Z=(e,t,o,n,r,i,...s)=>{if(s.length>0)throw new Error(ke(1));let a;if(e&&t&&o&&n&&r&&i)a=(l,c,d,f)=>{let p=e(l,c,d,f),m=t(l,c,d,f),u=o(l,c,d,f),g=n(l,c,d,f),v=r(l,c,d,f);return i(p,m,u,g,v,c,d,f)};else if(e&&t&&o&&n&&r)a=(l,c,d,f)=>{let p=e(l,c,d,f),m=t(l,c,d,f),u=o(l,c,d,f),g=n(l,c,d,f);return r(p,m,u,g,c,d,f)};else if(e&&t&&o&&n)a=(l,c,d,f)=>{let p=e(l,c,d,f),m=t(l,c,d,f),u=o(l,c,d,f);return n(p,m,u,c,d,f)};else if(e&&t&&o)a=(l,c,d,f)=>{let p=e(l,c,d,f),m=t(l,c,d,f);return o(p,m,c,d,f)};else if(e&&t)a=(l,c,d,f)=>{let p=e(l,c,d,f);return t(p,c,d,f)};else if(e)a=e;else throw new Error("Missing arguments");return a};var Qc=b(z(),1),pi=b(li(),1),Jc=b(Gc(),1);var Xc=b(z(),1);var di=[],ui;function Kc(){return ui}function qc(e){di.push(e)}function fi(e){let t=(o,n)=>{let r=Se(ig).current,i;try{ui=r;for(let s of di)s.before(r);i=e(o,n);for(let s of di)s.after(r);r.didInitialize=!0}finally{ui=void 0}return i};return t.displayName=e.displayName||e.name,t}function Zc(e){return Xc.forwardRef(fi(e))}function ig(){return{didInitialize:!1}}var sg=ao(19),ag=sg?lg:dg;function jn(e,t,o,n,r){return ag(e,t,o,n,r)}function cg(e,t,o,n,r){let i=Qc.useCallback(()=>t(e.getSnapshot(),o,n,r),[e,t,o,n,r]);return(0,pi.useSyncExternalStore)(e.subscribe,i,i)}qc({before(e){e.syncIndex=0,e.didInitialize||(e.syncTick=1,e.syncHooks=[],e.didChangeStore=!0,e.getSnapshot=()=>{let t=!1;for(let o=0;o0&&(e.didChangeStore&&(e.didChangeStore=!1,e.subscribe=t=>{let o=new Set;for(let r of e.syncHooks)o.add(r.store);let n=[];for(let r of o)n.push(r.subscribe(t));return()=>{for(let r of n)r()}}),(0,pi.useSyncExternalStore)(e.subscribe,e.getSnapshot,e.getSnapshot))}});function lg(e,t,o,n,r){let i=Kc();if(!i)return cg(e,t,o,n,r);let s=i.syncIndex;i.syncIndex+=1;let a;return i.didInitialize?(a=i.syncHooks[s],(a.store!==e||a.selector!==t||!Object.is(a.a1,o)||!Object.is(a.a2,n)||!Object.is(a.a3,r))&&(a.store!==e&&(i.didChangeStore=!0),a.store=e,a.selector=t,a.a1=o,a.a2=n,a.a3=r,a.value=t(e.getSnapshot(),o,n,r))):(a={store:e,selector:t,a1:o,a2:n,a3:r,value:t(e.getSnapshot(),o,n,r)},i.syncHooks.push(a)),a.value}function dg(e,t,o,n,r){return(0,Jc.useSyncExternalStoreWithSelector)(e.subscribe,e.getSnapshot,e.getSnapshot,i=>t(i,o,n,r))}var Fn=class{constructor(t){this.state=t,this.listeners=new Set,this.updateTick=0}subscribe=t=>(this.listeners.add(t),()=>{this.listeners.delete(t)});getSnapshot=()=>this.state;setState(t){if(this.state===t)return;this.state=t,this.updateTick+=1;let o=this.updateTick;for(let n of this.listeners){if(o!==this.updateTick)return;n(t)}}update(t){for(let o in t)if(!Object.is(this.state[o],t[o])){this.setState({...this.state,...t});return}}set(t,o){Object.is(this.state[t],o)||this.setState({...this.state,[t]:o})}notifyAll(){let t={...this.state};this.setState(t)}use(t,o,n,r){return jn(this,t,o,n,r)}};var Jt=b(z(),1);var wo=class extends Fn{constructor(t,o={},n){super(t),this.context=o,this.selectors=n}useSyncedValue(t,o){Jt.useDebugValue(t);let n=this;D(()=>{n.state[t]!==o&&n.set(t,o)},[n,t,o])}useSyncedValueWithCleanup(t,o){let n=this;D(()=>(n.state[t]!==o&&n.set(t,o),()=>{n.set(t,void 0)}),[n,t,o])}useSyncedValues(t){let o=this,n=Object.values(t);D(()=>{o.update(t)},[o,...n])}useControlledProp(t,o){Jt.useDebugValue(t);let n=this,r=o!==void 0;D(()=>{r&&!Object.is(n.state[t],o)&&n.setState({...n.state,[t]:o})},[n,t,o,r])}select(t,o,n,r){let i=this.selectors[t];return i(this.state,o,n,r)}useState(t,o,n,r){return Jt.useDebugValue(t),jn(this,this.selectors[t],o,n,r)}useContextCallback(t,o){Jt.useDebugValue(t);let n=Y(o??Nt);this.context[t]=n}useStateSetter(t){let o=Jt.useRef(void 0);return o.current===void 0&&(o.current=n=>{this.set(t,n)}),o.current}observe(t,o){let n;typeof t=="function"?n=t:n=this.selectors[t];let r=n(this.state);return o(r,r,this),this.subscribe(i=>{let s=n(i);if(!Object.is(r,s)){let a=r;r=s,o(s,a,this)}})}};var ug={open:Z(e=>e.open),transitionStatus:Z(e=>e.transitionStatus),domReferenceElement:Z(e=>e.domReferenceElement),referenceElement:Z(e=>e.positionReference??e.referenceElement),floatingElement:Z(e=>e.floatingElement),floatingId:Z(e=>e.floatingId)},gt=class extends wo{constructor(t){let{syncOnly:o,nested:n,onOpenChange:r,triggerElements:i,...s}=t;super({...s,positionReference:s.referenceElement,domReferenceElement:s.referenceElement},{onOpenChange:r,dataRef:{current:{}},events:cc(),nested:n,triggerElements:i},ug),this.syncOnly=o}syncOpenEvent=(t,o)=>{(!t||!this.state.open||o!=null&&Ua(o))&&(this.context.dataRef.current.openEvent=t?o:void 0)};dispatchOpenChange=(t,o)=>{this.syncOpenEvent(t,o.event);let n={open:t,reason:o.reason,nativeEvent:o.event,nested:this.context.nested,triggerElement:o.trigger};this.context.events.emit("openchange",n)};setOpen=(t,o)=>{if(this.syncOnly){this.context.onOpenChange?.(t,o);return}this.dispatchOpenChange(t,o),this.context.onOpenChange?.(t,o)}};function el(e){let{popupStore:t,treatPopupAsFloatingElement:o=!1,floatingRootContext:n,floatingId:r,nested:i,onOpenChange:s}=e,a=t.useState("open"),l=t.useState("activeTriggerElement"),c=t.useState(o?"popupElement":"positionerElement"),d=t.context.triggerElements,f=s,p=$c.useRef(null);n===void 0&&p.current===null&&(p.current=new gt({open:a,transitionStatus:void 0,referenceElement:l,floatingElement:c,triggerElements:d,onOpenChange:f,floatingId:r,syncOnly:!0,nested:i}));let m=n??p.current;return t.useSyncedValue("floatingId",r),D(()=>{let u={open:a,floatingId:r,referenceElement:l,floatingElement:c};F(l)&&(u.domReferenceElement=l),m.state.positionReference===m.state.referenceElement&&(u.positionReference=l),m.update(u)},[a,r,l,c,m]),m.context.onOpenChange=f,m.context.nested=i,m}var ol={tabIndex:-1,[Wr]:""};function nl(e,t,o=!1){let n=Lt(),r=go()!=null,i=vo.useRef(null);e===void 0&&i.current===null&&(i.current=t(n,r));let s=e??i.current;return el({popupStore:s,treatPopupAsFloatingElement:o,floatingRootContext:s.state.floatingRootContext,floatingId:n,nested:r,onOpenChange:s.setOpen}),{store:s,internalStore:i.current}}function fg(e,t){let o=vo.useRef(null),n=vo.useRef(null);return vo.useCallback(r=>{if(e===void 0)return;let i=!1;if(o.current!==null){let s=o.current,a=n.current,l=t.context.triggerElements.getById(s);a&&l===a&&(t.context.triggerElements.delete(s),i=!0),o.current=null,n.current=null}if(r!==null&&(o.current=e,n.current=r,t.context.triggerElements.add(e,r),i=!0),i){let s=t.context.triggerElements.size;t.select("open")&&t.state.triggerCount!==s&&t.set("triggerCount",s)}},[t,e])}function pg(e,t,o,n=!1){t?e.preventUnmountingOnClose=!1:n&&(e.preventUnmountingOnClose=!0);let r=o?.id??null;(r||t)&&(e.activeTriggerId=r,e.activeTriggerElement=o??null)}function mg(e){let t=!1;return e.preventUnmountOnClose=()=>{t=!0},()=>t}function rl(e,t,o,n={}){let r=o.reason,i=r===U.triggerHover,s=t&&r===U.triggerFocus,a=!t&&(r===U.triggerPress||r===U.escapeKey),l=mg(o);if(e.context.onOpenChange?.(t,o),o.isCanceled)return;n.onBeforeDispatch?.(),e.state.floatingRootContext.dispatchOpenChange(t,o);let c=()=>{let d={...n.extraState,open:t};s?d.instantType="focus":a?d.instantType="dismiss":i&&(d.instantType=void 0),pg(d,t,o.trigger,l()),e.update(d)};i?tl.flushSync(c):c()}function il(e,t,o,n){Da(()=>{t===void 0&&e.state.open===!1&&o&&(e.state={...e.state,open:!0,activeTriggerId:n,preventUnmountingOnClose:!1})})}function sl(e,t,o,n){let r=o.useState("isMountedByTrigger",e),i=fg(e,o),s=Y(a=>{if(i(a),!a)return;let l=o.select("open"),c=o.select("activeTriggerId");if(c===e){o.update({activeTriggerElement:a,...l?n:null});return}c==null&&l&&o.update({activeTriggerId:e,activeTriggerElement:a,...n})});return D(()=>{r&&o.update({activeTriggerElement:t.current,...n})},[r,o,t,...Object.values(n)]),{registerTrigger:s,isMountedByThisTrigger:r}}function al(e,t={}){let{closeOnActiveTriggerUnmount:o=!1}=t,n=e.useState("open"),r=e.useState("triggerCount");D(()=>{if(!n){e.state.triggerCount!==0&&e.set("triggerCount",0);return}let i=e.context.triggerElements.size,s={};e.state.triggerCount!==i&&(s.triggerCount=i);let a=e.select("activeTriggerId"),l=null;if(a){let c=e.context.triggerElements.getById(a);c?c!==e.state.activeTriggerElement&&(s.activeTriggerElement=c):l=a}if(!l&&!a&&i===1){let c=e.context.triggerElements.entries().next();if(!c.done){let[d,f]=c.value;s.activeTriggerId=d,s.activeTriggerElement=f}}(s.triggerCount!==void 0||s.activeTriggerId!==void 0||s.activeTriggerElement!==void 0)&&e.update(s),l&&o&&queueMicrotask(()=>{if(e.select("open")&&e.select("activeTriggerId")===l&&!e.context.triggerElements.getById(l)){let c=ee(U.none);e.setOpen(!1,c),c.isCanceled||e.update({activeTriggerId:null,activeTriggerElement:null})}})},[n,e,r,o])}function cl(e,t,o){let{mounted:n,setMounted:r,transitionStatus:i}=Ea(e),s=t.useState("preventUnmountingOnClose"),a=e?!1:s;t.useSyncedValues({mounted:n,transitionStatus:i,preventUnmountingOnClose:a});let l=Y(()=>{r(!1),t.update({activeTriggerId:null,activeTriggerElement:null,mounted:!1,preventUnmountingOnClose:!1}),o?.(),t.context.onOpenChangeComplete?.(!1)});return kn({enabled:n&&!e&&!a,open:e,ref:t.context.popupRef,onComplete(){e||l()}}),{forceUnmount:l,transitionStatus:i}}function ll(e,t){e.useSyncedValues(t),D(()=>()=>{e.update({activeTriggerProps:be,inactiveTriggerProps:be,popupProps:be})},[e])}var jt=class{constructor(){this.elementsSet=new Set,this.idMap=new Map}add(t,o){let n=this.idMap.get(t);n!==o&&(n!==void 0&&this.elementsSet.delete(n),this.elementsSet.add(o),this.idMap.set(t,o))}delete(t){let o=this.idMap.get(t);o&&(this.elementsSet.delete(o),this.idMap.delete(t))}hasElement(t){return this.elementsSet.has(t)}hasMatchingElement(t){for(let o of this.elementsSet)if(t(o))return!0;return!1}getById(t){return this.idMap.get(t)}entries(){return this.idMap.entries()}elements(){return this.elementsSet.values()}get size(){return this.idMap.size}};function dl(){return new gt({open:!1,transitionStatus:void 0,floatingElement:null,referenceElement:null,triggerElements:new jt,floatingId:void 0,syncOnly:!1,nested:!1,onOpenChange:void 0})}function fl(){return{open:!1,openProp:void 0,mounted:!1,transitionStatus:void 0,floatingRootContext:dl(),floatingId:void 0,triggerCount:0,preventUnmountingOnClose:!1,payload:void 0,activeTriggerId:null,activeTriggerElement:null,triggerIdProp:void 0,popupElement:null,positionerElement:null,activeTriggerProps:be,inactiveTriggerProps:be,popupProps:be}}function pl(e,t,o=!1){return new gt({open:!1,transitionStatus:void 0,floatingElement:null,referenceElement:null,triggerElements:e,floatingId:t,syncOnly:!0,nested:o,onOpenChange:void 0})}var Xo=Z(e=>e.triggerIdProp??e.activeTriggerId),mi=Z(e=>e.openProp??e.open),ul=Z(e=>(e.popupElement?.id??e.floatingId)||void 0);function ml(e,t){return t!==void 0&&mi(e)&&Xo(e)===t}function gg(e,t){return ml(e,t)?!0:t!==void 0&&mi(e)&&Xo(e)==null&&e.triggerCount===1}var gl={open:mi,mounted:Z(e=>e.mounted),transitionStatus:Z(e=>e.transitionStatus),floatingRootContext:Z(e=>e.floatingRootContext),triggerCount:Z(e=>e.triggerCount),preventUnmountingOnClose:Z(e=>e.preventUnmountingOnClose),payload:Z(e=>e.payload),activeTriggerId:Xo,activeTriggerElement:Z(e=>e.mounted?e.activeTriggerElement:null),popupId:ul,isTriggerActive:Z((e,t)=>t!==void 0&&Xo(e)===t),isOpenedByTrigger:Z((e,t)=>ml(e,t)),isMountedByTrigger:Z((e,t)=>t!==void 0&&Xo(e)===t&&e.mounted),triggerProps:Z((e,t)=>t?e.activeTriggerProps:e.inactiveTriggerProps),triggerPopupId:Z((e,t)=>gg(e,t)?ul(e):void 0),popupProps:Z(e=>e.popupProps),popupElement:Z(e=>e.popupElement),positionerElement:Z(e=>e.positionerElement)};function bl(e){let{open:t=!1,onOpenChange:o,elements:n={}}=e,r=Lt(),i=go()!=null,s=Se(()=>new gt({open:t,transitionStatus:void 0,onOpenChange:o,referenceElement:n.reference??null,floatingElement:n.floating??null,triggerElements:new jt,floatingId:r,syncOnly:!1,nested:i})).current;return D(()=>{let a={open:t,floatingId:r};n.reference!==void 0&&(a.referenceElement=n.reference,a.domReferenceElement=F(n.reference)?n.reference:null),n.floating!==void 0&&(a.floatingElement=n.floating),s.update(a)},[t,r,n.reference,n.floating,s]),s.context.onOpenChange=o,s.context.nested=i,s}function gi(e={}){let{nodeId:t,externalTree:o}=e,n=bl(e),r=e.rootContext||n,i=r.useState("referenceElement"),s=r.useState("floatingElement"),a=r.useState("domReferenceElement"),l=r.useState("open"),c=r.useState("floatingId"),[d,f]=Oe.useState(null),[p,m]=Oe.useState(void 0),[u,g]=Oe.useState(void 0),v=Oe.useRef(null),_=Dt(o),w=Oe.useMemo(()=>({reference:i,floating:s,domReference:a}),[i,s,a]),y=Dc({...e,elements:{...w,...d&&{reference:d}}}),h=F(p)?p:null,T=u===void 0?r.state.floatingElement:u;r.useSyncedValue("referenceElement",p??null),r.useSyncedValue("domReferenceElement",p===void 0?a:h),r.useSyncedValue("floatingElement",T);let x=Oe.useCallback(O=>{let L=F(O)?{getBoundingClientRect:()=>O.getBoundingClientRect(),getClientRects:()=>O.getClientRects(),contextElement:O}:O;f(L),y.refs.setReference(L)},[y.refs]),R=Oe.useCallback(O=>{(F(O)||O===null)&&(v.current=O,m(O)),(F(y.refs.reference.current)||y.refs.reference.current===null||O!==null&&!F(O))&&y.refs.setReference(O)},[y.refs,m]),E=Oe.useCallback(O=>{g(O),y.refs.setFloating(O)},[y.refs]),k=Oe.useMemo(()=>({...y.refs,setReference:R,setFloating:E,setPositionReference:x,domReference:v}),[y.refs,R,E,x]),C=Oe.useMemo(()=>({...y.elements,domReference:a}),[y.elements,a]),W=Oe.useMemo(()=>({...y,dataRef:r.context.dataRef,open:l,onOpenChange:r.setOpen,events:r.context.events,floatingId:c,refs:k,elements:C,nodeId:t,rootStore:r}),[y,k,C,t,r,l,c]);return D(()=>{a&&(v.current=a)},[a]),D(()=>{r.context.dataRef.current.floatingContext=W;let O=_?.nodesRef.current.find(L=>L.id===t);O&&(O.context=W)}),Oe.useMemo(()=>({...y,context:W,refs:k,elements:C,rootStore:r}),[y,k,C,W,r])}var bt=b(z(),1);var bi=Rt.os.mac&&Rt.engine.webkit;function hi(e,t={}){let{enabled:o=!0,delay:n}=t,r="rootStore"in e?e.rootStore:e,{events:i,dataRef:s}=r.context,a=bt.useRef(!1),l=bt.useRef(null),c=bt.useRef(!0),d=ot();bt.useEffect(()=>{let p=r.select("domReferenceElement");if(!o)return;let m=me(p);function u(){let _=r.select("domReferenceElement");!r.select("open")&&ye(_)&&_===Pn(xe(_))&&(a.current=!0)}function g(){c.current=!0}function v(){c.current=!1}return nt(re(m,"blur",u),bi&&re(m,"keydown",g,!0),bi&&re(m,"pointerdown",v,!0))},[r,o]),bt.useEffect(()=>{if(!o)return;function p(m){if(m.reason===U.triggerPress||m.reason===U.escapeKey){let u=r.select("domReferenceElement");F(u)&&(l.current=u,a.current=!0)}}return i.on("openchange",p),()=>{i.off("openchange",p)}},[i,o,r]);let f=bt.useMemo(()=>{function p(){a.current=!1,l.current=null}return{onMouseLeave(){p()},onFocus(m){let u=m.currentTarget;if(a.current){if(l.current===u)return;p()}let g=Me(m.nativeEvent);if(F(g)){if(bi&&!m.relatedTarget){if(!c.current&&!Xa(g))return}else if(!Ka(g))return}let v=Bt(m.relatedTarget,r.context.triggerElements),{nativeEvent:_,currentTarget:w}=m,y=typeof n=="function"?n():n;if(r.select("open")&&v||y===0||y===void 0){r.setOpen(!0,ee(U.triggerFocus,_,w));return}d.start(y,()=>{a.current||r.setOpen(!0,ee(U.triggerFocus,_,w))})},onBlur(m){p();let u=m.relatedTarget,g=m.nativeEvent,v=F(u)&&u.hasAttribute(mo("focus-guard"))&&u.getAttribute("data-type")==="outside";d.start(0,()=>{let _=r.select("domReferenceElement"),w=Pn(xe(_));!u&&w===_||ie(s.current.floatingContext?.refs.floating.current,w)||ie(_,w)||v||Bt(u??w,r.context.triggerElements)||r.setOpen(!1,ee(U.triggerFocus,g))})}}},[s,n,r,d]);return bt.useMemo(()=>o?{reference:f,trigger:f}:{},[o,f])}var vi=b(z(),1);var wi=class e{constructor(){this.pointerType=void 0,this.interactedInside=!1,this.handler=void 0,this.blockMouseMove=!0,this.performedPointerEventsMutation=!1,this.pointerEventsScopeElement=null,this.pointerEventsReferenceElement=null,this.pointerEventsFloatingElement=null,this.restTimeoutPending=!1,this.openChangeTimeout=new We,this.restTimeout=new We,this.handleCloseOptions=void 0}static create(){return new e}dispose=()=>{this.openChangeTimeout.clear(),this.restTimeout.clear()};disposeEffect=()=>this.dispose},Vn=new WeakMap;function _o(e){if(!e.performedPointerEventsMutation)return;let t=e.pointerEventsScopeElement;t&&Vn.get(t)===e&&(e.pointerEventsScopeElement?.style.removeProperty("pointer-events"),e.pointerEventsReferenceElement?.style.removeProperty("pointer-events"),e.pointerEventsFloatingElement?.style.removeProperty("pointer-events"),Vn.delete(t)),e.performedPointerEventsMutation=!1,e.pointerEventsScopeElement=null,e.pointerEventsReferenceElement=null,e.pointerEventsFloatingElement=null}function Wn(e,t){let{scopeElement:o,referenceElement:n,floatingElement:r}=t,i=Vn.get(o);i&&i!==e&&_o(i),_o(e),e.performedPointerEventsMutation=!0,e.pointerEventsScopeElement=o,e.pointerEventsReferenceElement=n,e.pointerEventsFloatingElement=r,Vn.set(o,e),o.style.pointerEvents="none",n.style.pointerEvents="auto",r.style.pointerEvents="auto"}function yo(e){let t=e.context.dataRef.current,o=Se(()=>t.hoverInteractionState??wi.create()).current;return t.hoverInteractionState||(t.hoverInteractionState=o),co(t.hoverInteractionState.disposeEffect),t.hoverInteractionState}function _i(e,t={}){let{enabled:o=!0,closeDelay:n=0,nodeId:r}=t,i="rootStore"in e?e.rootStore:e,s=i.useState("open"),a=i.useState("floatingElement"),l=i.useState("domReferenceElement"),{dataRef:c}=i.context,d=Dt(),f=go(),p=yo(i),m=ot(),u=Y(()=>An(c.current.openEvent?.type,p.interactedInside)),g=Y(()=>qa(c.current.openEvent?.type)),v=Y(()=>{_o(p)});D(()=>{s||(p.pointerType=void 0,p.restTimeoutPending=!1,p.interactedInside=!1,v())},[s,p,v]),vi.useEffect(()=>v,[v]),D(()=>{if(o&&s&&p.handleCloseOptions?.blockPointerEvents&&g()&&F(l)&&a){let _=l,w=a,y=xe(a),h=d?.nodesRef.current.find(E=>E.id===f)?.context?.elements.floating;h&&(h.style.pointerEvents="");let T=p.pointerEventsScopeElement!==w?p.pointerEventsScopeElement:null,x=h!==w?h:null,R=p.handleCloseOptions?.getScope?.()??T??x??_.closest("[data-rootownerid]")??y.body;return Wn(p,{scopeElement:R,referenceElement:_,floatingElement:w}),()=>{v()}}},[o,s,l,a,p,g,d,f,v]),vi.useEffect(()=>{if(!o)return;function _(){return!!(d&&f&&Tt(d.nodesRef.current,f).length>0)}function w(E){let k=Et(n,"close",p.pointerType),C=()=>{i.setOpen(!1,ee(U.triggerHover,E)),d?.events.emit("floating.closed",E)};k?p.openChangeTimeout.start(k,C):(p.openChangeTimeout.clear(),C())}function y(E){let k=Me(E);if(!Ur(k)){p.interactedInside=!1;return}p.interactedInside=k?.closest("[aria-haspopup]")!=null}function h(){p.openChangeTimeout.clear(),m.clear(),d?.events.off("floating.closed",x),v()}function T(E){if(_()&&d){d.events.on("floating.closed",x);return}if(Bt(E.relatedTarget,i.context.triggerElements))return;let k=c.current.floatingContext?.nodeId??r,C=E.relatedTarget;if(!(d&&k&&F(C)&&Tt(d.nodesRef.current,k,!1).some(O=>ie(O.context?.elements.floating,C)))){if(p.handler){p.handler(E);return}v(),g()&&!u()&&w(E)}}function x(E){!d||!f||_()||m.start(0,()=>{d.events.off("floating.closed",x),i.setOpen(!1,ee(U.triggerHover,E)),d.events.emit("floating.closed",E)})}let R=a;return nt(R&&re(R,"mouseenter",h),R&&re(R,"mouseleave",T),R&&re(R,"pointerdown",y,!0),()=>{d?.events.off("floating.closed",x)})},[o,a,i,c,n,r,g,u,v,p,d,f,m])}var Ft=b(z(),1),hl=b(Mt(),1);var bg={current:null};function yi(e,t={}){let{enabled:o=!0,delay:n=0,handleClose:r=null,mouseOnly:i=!1,restMs:s=0,move:a=!0,triggerElementRef:l=bg,externalTree:c,isActiveTrigger:d=!0,getHandleCloseContext:f,isClosing:p,shouldOpen:m}=t,u="rootStore"in e?e.rootStore:e,{dataRef:g,events:v}=u.context,_=Dt(c),w=yo(u),y=Ft.useRef(!1),h=He(r),T=He(n),x=He(s),R=He(o),E=He(m),k=He(p),C=Y(()=>An(g.current.openEvent?.type,w.interactedInside)),W=Y(()=>E.current?.()!==!1),O=Y((S,N,H)=>{let P=u.context.triggerElements;if(P.hasElement(N))return!S||!ie(S,N);if(!F(H))return!1;let A=H;return P.hasMatchingElement(M=>ie(M,A))&&(!S||!ie(S,A))}),L=Y(()=>{if(!w.handler)return;xe(u.select("domReferenceElement")).removeEventListener("mousemove",w.handler),w.handler=void 0}),I=Y(()=>{_o(w)});return d&&(w.handleCloseOptions=h.current?.__options),Ft.useEffect(()=>L,[L]),Ft.useEffect(()=>{if(!o)return;function S(N){N.open?y.current=!1:(y.current=N.reason===U.triggerHover,L(),w.openChangeTimeout.clear(),w.restTimeout.clear(),w.blockMouseMove=!0,w.restTimeoutPending=!1)}return v.on("openchange",S),()=>{v.off("openchange",S)}},[o,v,w,L]),Ft.useEffect(()=>{if(!o)return;function S(A,M=!0){let Q=Et(T.current,"close",w.pointerType);Q?w.openChangeTimeout.start(Q,()=>{u.setOpen(!1,ee(U.triggerHover,A)),_?.events.emit("floating.closed",A)}):M&&(w.openChangeTimeout.clear(),u.setOpen(!1,ee(U.triggerHover,A)),_?.events.emit("floating.closed",A))}let N=l.current??(d?u.select("domReferenceElement"):null);if(!F(N))return;function H(A){if(w.openChangeTimeout.clear(),w.blockMouseMove=!1,i&&!St(w.pointerType))return;let M=Gr(x.current),Q=Et(T.current,"open",w.pointerType),V=Me(A),oe=A.currentTarget??null,te=u.select("domReferenceElement"),se=oe;if(F(V)&&!u.context.triggerElements.hasElement(V)){for(let ue of u.context.triggerElements.elements())if(ie(ue,V)){se=ue;break}}F(oe)&&F(te)&&!u.context.triggerElements.hasElement(oe)&&ie(oe,te)&&(se=te);let G=se==null?!1:O(te,se,V),q=u.select("open"),J=k.current?.()??u.select("transitionStatus")==="ending",ne=!q&&J&&y.current,ge=!G&&F(se)&&F(te)&&ie(te,se)&&ne,de=M>0&&!Q,X=G&&(q||ne)||ge,pe=!q||G;if(X){W()&&u.setOpen(!0,ee(U.triggerHover,A,se));return}de||(Q?w.openChangeTimeout.start(Q,()=>{pe&&W()&&u.setOpen(!0,ee(U.triggerHover,A,se))}):pe&&W()&&u.setOpen(!0,ee(U.triggerHover,A,se)))}function P(A){if(C()){I();return}L();let M=u.select("domReferenceElement"),Q=xe(M);w.restTimeout.clear(),w.restTimeoutPending=!1;let V=g.current.floatingContext??f?.();if(Bt(A.relatedTarget,u.context.triggerElements))return;if(h.current&&V){u.select("open")||w.openChangeTimeout.clear();let te=l.current;w.handler=h.current({...V,tree:_,x:A.clientX,y:A.clientY,onClose(){I(),L(),R.current&&!C()&&te===u.select("domReferenceElement")&&S(A,!0)}}),Q.addEventListener("mousemove",w.handler),w.handler(A);return}(w.pointerType!=="touch"||!ie(u.select("floatingElement"),A.relatedTarget))&&S(A)}return a?nt(re(N,"mousemove",H,{once:!0}),re(N,"mouseenter",H),re(N,"mouseleave",P)):nt(re(N,"mouseenter",H),re(N,"mouseleave",P))},[L,I,g,T,u,o,h,w,d,O,C,i,a,x,l,_,R,f,k,W]),Ft.useMemo(()=>{if(!o)return;function S(N){w.pointerType=N.pointerType}return{onPointerDown:S,onPointerEnter:S,onMouseMove(N){let{nativeEvent:H}=N,P=N.currentTarget,A=u.select("domReferenceElement"),M=u.select("open"),Q=O(A,P,N.target);if(i&&!St(w.pointerType))return;if(M&&Q&&w.handleCloseOptions?.blockPointerEvents){let te=u.select("floatingElement");if(te){let se=w.handleCloseOptions?.getScope?.()??P.ownerDocument.body;Wn(w,{scopeElement:se,referenceElement:P,floatingElement:te})}}let V=Gr(x.current);if(M&&!Q||V===0||!Q&&w.restTimeoutPending&&N.movementX**2+N.movementY**2<2)return;w.restTimeout.clear();function oe(){if(w.restTimeoutPending=!1,C())return;let te=u.select("open");!w.blockMouseMove&&(!te||Q)&&W()&&u.setOpen(!0,ee(U.triggerHover,H,P))}w.pointerType==="touch"?hl.flushSync(()=>{oe()}):Q&&M?oe():(w.restTimeoutPending=!0,w.restTimeout.start(V,oe))}}},[o,w,C,O,i,u,x,W])}var wl=.1,hg=wl*wl,le=.5;function Yn(e,t,o,n,r,i){return n>=t!=i>=t&&e<=(r-o)*(t-n)/(i-n)+o}function Un(e,t,o,n,r,i,s,a,l,c){let d=!1;return Yn(e,t,o,n,r,i)&&(d=!d),Yn(e,t,r,i,s,a)&&(d=!d),Yn(e,t,s,a,l,c)&&(d=!d),Yn(e,t,l,c,o,n)&&(d=!d),d}function wg(e,t,o){return e>=o.x&&e<=o.x+o.width&&t>=o.y&&t<=o.y+o.height}function Gn(e,t,o,n,r,i){let s=Math.min(o,r),a=Math.max(o,r),l=Math.min(n,i),c=Math.max(n,i);return e>=s&&e<=a&&t>=l&&t<=c}function xi(e={}){let{blockPointerEvents:t=!1}=e,o=new We,n=({x:r,y:i,placement:s,elements:a,onClose:l,nodeId:c,tree:d})=>{let f=s?.split("-")[0],p=!1,m=null,u=null,g=typeof performance<"u"?performance.now():0;function v(w,y){let h=performance.now(),T=h-g;if(m===null||u===null||T===0)return m=w,u=y,g=h,!1;let x=w-m,R=y-u,E=x*x+R*R,k=T*T*hg;return m=w,u=y,g=h,E0)}function L(){O()||_()}if(O())return;let I=h.getBoundingClientRect(),S=T.getBoundingClientRect(),N=r>S.right-S.width/2,H=i>S.bottom-S.height/2,P=S.width>I.width,A=S.height>I.height,M=(P?I:S).left,Q=(P?I:S).right,V=(A?I:S).top,oe=(A?I:S).bottom;if(f==="top"&&i>=I.bottom-1||f==="bottom"&&i<=I.top+1||f==="left"&&r>=I.right-1||f==="right"&&r<=I.left+1){L();return}let te=!1;switch(f){case"top":te=Gn(x,R,M,I.top+1,Q,S.bottom-1);break;case"bottom":te=Gn(x,R,M,S.top+1,Q,I.bottom-1);break;case"left":te=Gn(x,R,S.right-1,oe,I.left+1,V);break;case"right":te=Gn(x,R,I.right-1,oe,S.left+1,V);break;default:}if(te)return;if(p&&!wg(x,R,I)){L();return}if(!k&&v(x,R)){L();return}let se=!1;switch(f){case"top":{let G=P?le/2:le*4,q=P||N?r+G:r-G,J=P?r-G:N?r+G:r-G,ne=i+le+1,ge=N||P?S.bottom-le:S.top,de=N?P?S.bottom-le:S.top:S.bottom-le;se=Un(x,R,q,ne,J,ne,S.left,ge,S.right,de);break}case"bottom":{let G=P?le/2:le*4,q=P||N?r+G:r-G,J=P?r-G:N?r+G:r-G,ne=i-le,ge=N||P?S.top+le:S.bottom,de=N?P?S.top+le:S.bottom:S.top+le;se=Un(x,R,q,ne,J,ne,S.left,ge,S.right,de);break}case"left":{let G=A?le/2:le*4,q=A||H?i+G:i-G,J=A?i-G:H?i+G:i-G,ne=r+le+1,ge=H||A?S.right-le:S.left,de=H?A?S.right-le:S.left:S.right-le;se=Un(x,R,ge,S.top,de,S.bottom,ne,q,ne,J);break}case"right":{let G=A?le/2:le*4,q=A||H?i+G:i-G,J=A?i-G:H?i+G:i-G,ne=r-le,ge=H||A?S.left+le:S.right,de=H?A?S.left+le:S.right:S.left+le;se=Un(x,R,ne,q,ne,J,ge,S.top,de,S.bottom);break}default:}se?p||o.start(40,L):L()}};return n.__options={...e,blockPointerEvents:t},n}var Ri=(function(e){return e.open="data-open",e.closed="data-closed",e[e.startingStyle=Yt.startingStyle]="startingStyle",e[e.endingStyle=Yt.endingStyle]="endingStyle",e.anchorHidden="data-anchor-hidden",e.side="data-side",e.align="data-align",e})({}),Ko=(function(e){return e.popupOpen="data-popup-open",e.pressed="data-pressed",e})({}),vg={[Ko.popupOpen]:""},oy={[Ko.popupOpen]:"",[Ko.pressed]:""},_g={[Ri.open]:""},yg={[Ri.closed]:""},xg={[Ri.anchorHidden]:""},vl={open(e){return e?vg:null}};var xo={open(e){return e?_g:yg},anchorHidden(e){return e?xg:null}};function _l(e){return ao(19)?e:e?"true":void 0}var Ue=b(z(),1);var Rg=e=>({name:"arrow",options:e,async fn(t){let{x:o,y:n,placement:r,rects:i,platform:s,elements:a,middlewareData:l}=t,{element:c,padding:d=0,offsetParent:f="real"}=it(e,t)||{};if(c==null)return{};let p=In(d),m={x:o,y:n},u=Uo(r),g=Yo(u),v=await s.getDimensions(c),_=u==="y",w=_?"top":"left",y=_?"bottom":"right",h=_?"clientHeight":"clientWidth",T=i.reference[g]+i.reference[u]-m[u]-i.floating[g],x=m[u]-i.reference[u],R=f==="real"?await s.getOffsetParent?.(c):a.floating,E=a.floating[h]||i.floating[g];(!E||!await s.isElement?.(R))&&(E=a.floating[h]||i.floating[g]);let k=T/2-x/2,C=E/2-v[g]/2-1,W=Math.min(p[w],C),O=Math.min(p[y],C),L=W,I=E-v[g]-O,S=E/2-v[g]/2+k,N=Nn(L,S,I),H=!l.arrow&&st(r)!=null&&S!==N&&i.reference[g]/2-(S({...Rg(e),options:[e,t]});var Sg=ai().fn,xl={name:"hide",async fn(e){let{width:t,height:o,x:n,y:r}=e.rects.reference,i=t===0&&o===0&&n===0&&r===0;return{data:{referenceHidden:(await Sg(e)).data?.referenceHidden||i}}}};var qo={sideX:"left",sideY:"top"},Rl={name:"adaptiveOrigin",async fn(e){let{x:t,y:o,rects:{floating:n},elements:{floating:r},platform:i,strategy:s,placement:a}=e,l=me(r),c=l.getComputedStyle(r);if(!(c.transitionDuration!=="0s"&&c.transitionDuration!==""))return{x:t,y:o,data:qo};let f=await i.getOffsetParent?.(r),p={width:0,height:0};if(s==="fixed"&&l?.visualViewport)p={width:l.visualViewport.width,height:l.visualViewport.height};else if(f===l){let w=xe(r);p={width:w.documentElement.clientWidth,height:w.documentElement.clientHeight}}else await i.isElement?.(f)&&(p=await i.getDimensions(f));let m=Ae(a),u=t,g=o;m==="left"&&(u=p.width-(t+n.width)),m==="top"&&(g=p.height-(o+n.height));let v=m==="left"?"right":qo.sideX,_=m==="top"?"bottom":qo.sideY;return{x:u,y:g,data:{sideX:v,sideY:_}}}};function Tl(e,t,o){let n=e==="inline-start"||e==="inline-end";return{top:"top",right:n?o?"inline-start":"inline-end":"right",bottom:"bottom",left:n?o?"inline-end":"inline-start":"left"}[t]}function Sl(e,t,o){let{rects:n,placement:r}=e;return{side:Tl(t,Ae(r),o),align:st(r)||"center",anchor:{width:n.reference.width,height:n.reference.height},positioner:{width:n.floating.width,height:n.floating.height}}}function kl(e){let{anchor:t,positionMethod:o="absolute",side:n="bottom",sideOffset:r=0,align:i="center",alignOffset:s=0,collisionBoundary:a,collisionPadding:l=5,sticky:c=!1,arrowPadding:d=5,disableAnchorTracking:f=!1,inline:p,keepMounted:m=!1,floatingRootContext:u,mounted:g,collisionAvoidance:v,shiftCrossAxis:_=!1,nodeId:w,adaptiveOrigin:y,lazyFlip:h=!1,externalTree:T}=e,[x,R]=Ue.useState(null);!g&&x!==null&&R(null);let E=v.side||"flip",k=v.align||"flip",C=v.fallbackAxisSide||"end",W=typeof t=="function"?t:void 0,O=Y(W),L=W?O:t,I=He(t),S=He(g),H=so()==="rtl",P=x||{top:"top",right:"right",bottom:"bottom",left:"left","inline-end":H?"left":"right","inline-start":H?"right":"left"}[n],A=i==="center"?P:`${P}-${i}`,M=l,Q=1,V=n==="bottom"?Q:0,oe=n==="top"?Q:0,te=n==="right"?Q:0,se=n==="left"?Q:0;typeof M=="number"?M={top:M+V,right:M+se,bottom:M+oe,left:M+te}:M&&(M={top:(M.top||0)+V,right:(M.right||0)+se,bottom:(M.bottom||0)+oe,left:(M.left||0)+te});let G={boundary:a==="clipping-ancestors"?"clippingAncestors":a,padding:M},q=Ue.useRef(null),J=He(r),ne=He(s),ge=typeof r!="function"?r:0,de=typeof s!="function"?s:0,X=[];p&&X.push(p),X.push(oi(ae=>{let Le=Sl(ae,n,H),ct=typeof J.current=="function"?J.current(Le):J.current,Ke=typeof ne.current=="function"?ne.current(Le):ne.current;return{mainAxis:ct,crossAxis:Ke,alignmentAxis:Ke}},[ge,de,H,n]));let pe=k==="none"&&E!=="shift",ue=!pe&&(c||_||E==="shift"),_t=E==="none"?null:ii({...G,padding:{top:M.top+Q,right:M.right+Q,bottom:M.bottom+Q,left:M.left+Q},mainAxis:!_&&E==="flip",crossAxis:k==="flip"?"alignment":!1,fallbackAxisSideDirection:C}),Ee=pe?null:ni(ae=>{let Le=xe(ae.elements.floating).documentElement;return{...G,rootBoundary:_?{x:0,y:0,width:Le.clientWidth,height:Le.clientHeight}:void 0,mainAxis:k!=="none",crossAxis:ue,limiter:c||_?void 0:ri(ct=>{if(!q.current)return{};let{width:Ke,height:xt}=q.current.getBoundingClientRect(),tt=ze(Ae(ct.placement)),Vt=tt==="y"?Ke:xt,io=tt==="y"?M.left+M.right:M.top+M.bottom;return{offset:Vt/2+io/2}})}},[G,c,_,M,k]);E==="shift"||k==="shift"||i==="center"?X.push(Ee,_t):X.push(_t,Ee),X.push(si({...G,apply({elements:{floating:ae},availableWidth:Le,availableHeight:ct,rects:Ke}){if(!S.current)return;let xt=ae.style;xt.setProperty("--available-width",`${Le}px`),xt.setProperty("--available-height",`${ct}px`);let tt=me(ae).devicePixelRatio||1,{x:Vt,y:io,width:gn,height:vr}=Ke.reference,_r=(Math.round((Vt+gn)*tt)-Math.round(Vt*tt))/tt,yr=(Math.round((io+vr)*tt)-Math.round(io*tt))/tt;xt.setProperty("--anchor-width",`${_r}px`),xt.setProperty("--anchor-height",`${yr}px`)}}),yl(ae=>({element:q.current||xe(ae.elements.floating).createElement("div"),padding:d,offsetParent:"floating"}),[d]),{name:"transformOrigin",fn(ae){let{elements:Le,middlewareData:ct,placement:Ke,rects:xt,y:tt}=ae,Vt=Ae(Ke),io=ze(Vt),gn=q.current,vr=ct.arrow?.x||0,_r=ct.arrow?.y||0,yr=gn?.clientWidth||0,Pf=gn?.clientHeight||0,xr=vr+yr/2,$s=_r+Pf/2,Cf=Math.abs(ct.shift?.y||0),Af=xt.reference.height/2,Lo=typeof r=="function"?r(Sl(ae,n,H)):r,Of=Cf>Lo,Nf={top:`${xr}px calc(100% + ${Lo}px)`,bottom:`${xr}px ${-Lo}px`,left:`calc(100% + ${Lo}px) ${$s}px`,right:`${-Lo}px ${$s}px`}[Vt],Lf=`${xr}px ${xt.reference.y+Af-tt}px`;return Le.floating.style.setProperty("--transform-origin",ue&&io==="y"&&Of?Lf:Nf),{}}},xl,y),D(()=>{!g&&u&&u.update({referenceElement:null,floatingElement:null,domReferenceElement:null,positionReference:null})},[g,u]);let Fe=Ue.useMemo(()=>({elementResize:!f&&typeof ResizeObserver<"u",layoutShift:!f&&typeof IntersectionObserver<"u"}),[f]),{refs:Xe,elements:Be,x:no,y:ln,middlewareData:_e,update:ro,placement:B,context:j,isPositioned:he,floatingStyles:Te}=gi({rootContext:u,open:m?g:void 0,placement:A,middleware:X,strategy:o,whileElementsMounted:m?void 0:(...ae)=>Go(...ae,Fe),nodeId:w,externalTree:T}),{sideX:Pt,sideY:No}=_e.adaptiveOrigin||qo,yt=he?o:"fixed",Ve=Ue.useMemo(()=>{let ae=y?{position:yt,[Pt]:no,[No]:ln}:{position:yt,...Te};return he||(ae.opacity=0),ae},[y,yt,Pt,no,No,ln,Te,he]),Ct=Ue.useRef(null);D(()=>{if(!g)return;let ae=I.current,Le=typeof ae=="function"?ae():ae,Ke=(El(Le)?Le.current:Le)||null||null;Ke!==Ct.current&&(Xe.setPositionReference(Ke),Ct.current=Ke)},[g,Xe,L,I]),Ue.useEffect(()=>{if(!g)return;let ae=I.current;typeof ae!="function"&&El(ae)&&ae.current!==Ct.current&&(Xe.setPositionReference(ae.current),Ct.current=ae.current)},[g,Xe,L,I]),Ue.useEffect(()=>{if(m&&g&&Be.reference&&Be.floating)return Go(Be.reference,Be.floating,ro,Fe)},[m,g,Be,ro,Fe]);let At=Ae(B),dn=Tl(n,At,H),un=st(B)||"center",fn=!!_e.hide?.referenceHidden;D(()=>{h&&g&&he&&R(At)},[h,g,he,At]);let pn=Ue.useMemo(()=>({position:"absolute",top:_e.arrow?.y,left:_e.arrow?.x}),[_e.arrow]),mn=_e.arrow?.centerOffset!==0;return Ue.useMemo(()=>({positionerStyles:Ve,arrowStyles:pn,arrowRef:q,arrowUncentered:mn,side:dn,align:un,physicalSide:At,anchorHidden:fn,refs:Xe,context:j,isPositioned:he,update:ro}),[Ve,pn,q,mn,dn,un,At,fn,Xe,j,he,ro])}function El(e){return e!=null&&"current"in e}function Xn(e){return e==="starting"?rc:be}function Pl(e,t,{styles:o,transitionStatus:n,props:r,refs:i,hidden:s,inert:a=!1}){let l={...o};return a&&(l.pointerEvents="none"),Pe("div",e,{state:t,ref:i,props:[{role:"presentation",hidden:s,style:l},Xn(n),r],stateAttributesMapping:xo})}var Cl=b(z(),1);var Si=Cl.forwardRef(function(t,o){let{render:n,className:r,disabled:i=!1,focusableWhenDisabled:s=!1,nativeButton:a=!0,style:l,...c}=t,{getButtonProps:d,buttonRef:f}=La({disabled:i,focusableWhenDisabled:s,native:a});return Pe("button",t,{state:{disabled:i},ref:[o,f],props:[c,d]})});var Ne=b(z(),1),Hl=b(Mt(),1);var Al=b(z(),1);function Ol(e){let[t,o]=Al.useState({current:e,previous:null});return e!==t.current&&o({current:e,previous:t.current}),t.previous}var Ro=b(z(),1);function Ei(e){let t=Ie(e),o=parseFloat(t.width)||0,n=parseFloat(t.height)||0,r=ye(e),i=r?e.offsetWidth:o,s=r?e.offsetHeight:n;return(zt(o)!==i||zt(n)!==s)&&(o=i,n=s),{width:o,height:n}}function Ll(e){let{popupElement:t,positionerElement:o,content:n,mounted:r,onMeasureLayout:i,onMeasureLayoutComplete:s,side:a,direction:l}=e,c=po(t,!0,!1),d=lo(),f=Ro.useRef(null),p=Ro.useRef(!0),m=Ro.useRef(Nt),u=Y(i),g=Y(s),v=Ro.useMemo(()=>{let _=a==="top",w=a==="left";return l==="rtl"?(_=_||a==="inline-end",w=w||a==="inline-end"):(_=_||a==="inline-start",w=w||a==="inline-start"),_?{position:"absolute",[a==="top"?"bottom":"top"]:"0",[w?"right":"left"]:"0"}:be},[a,l]);D(()=>{if(!r){m.current=Nt,p.current=!0,f.current=null;return}if(!t||!o)return;m.current=Nl(t,v),Ti(t,"auto");let _=qn(t,"position","static"),w=qn(t,"transform","none"),y=qn(t,"scale","1"),h=Nl(o,{"--available-width":"max-content","--available-height":"max-content"});function T(){_(),w(),h()}function x(){T(),y()}if(u?.(),p.current||f.current===null){Kn(o,"max-content");let C=Ei(t);return f.current=C,Kn(o,C),x(),g?.(null,C),p.current=!1,()=>{m.current(),m.current=Nt}}Kn(o,"max-content");let R=f.current,E=Ei(t);f.current=E,Ti(t,R),x(),g?.(R,E),Kn(o,E);let k=new AbortController;return d.request(()=>{Ti(t,E),c(()=>{t.style.setProperty("--popup-width","auto"),t.style.setProperty("--popup-height","auto")},k.signal)}),()=>{k.abort(),d.cancel(),m.current(),m.current=Nt}},[n,t,o,c,d,r,u,g,v])}function qn(e,t,o){let n=e.style.getPropertyValue(t);return e.style.setProperty(t,o),()=>{e.style.setProperty(t,n)}}function Nl(e,t){let o=[];for(let[n,r]of Object.entries(t))o.push(qn(e,n,r));return o.length?()=>{o.forEach(n=>n())}:Nt}function Ti(e,t){let o=t==="auto"?"auto":`${t.width}px`,n=t==="auto"?"auto":`${t.height}px`;e.style.setProperty("--popup-width",o),e.style.setProperty("--popup-height",n)}function Kn(e,t){let o=t==="max-content"?"max-content":`${t.width}px`,n=t==="max-content"?"max-content":`${t.height}px`;e.style.setProperty("--positioner-width",o),e.style.setProperty("--positioner-height",n)}var Il=b(z(),1);var Ml=b(K(),1),Zn=function(t){let{direction:o="ltr"}=t,n=Il.useMemo(()=>({direction:o}),[o]);return(0,Ml.jsx)(Er.Provider,{value:n,children:t.children})};var So=b(K(),1);function zl(e){let{store:t,side:o,cssVars:n,children:r}=e,i=so(),s=t.useState("activeTriggerElement"),a=t.useState("activeTriggerId"),l=t.useState("open"),c=t.useState("payload"),d=t.useState("mounted"),f=t.useState("popupElement"),p=t.useState("positionerElement"),m=Ol(l?s:null),u=kg(a,c),g=Ne.useRef(null),[v,_]=Ne.useState(null),[w,y]=Ne.useState(null),h=Ne.useRef(null),T=Ne.useRef(null),x=po(h,!0,!1),R=lo(),[E,k]=Ne.useState(null),[C,W]=Ne.useState(!1);D(()=>(t.set("hasViewport",!0),()=>{t.set("hasViewport",!1)}),[t]);let O=Y(()=>{h.current?.style.setProperty("animation","none"),h.current?.style.setProperty("transition","none"),T.current?.style.setProperty("display","none")}),L=Y(P=>{h.current?.style.removeProperty("animation"),h.current?.style.removeProperty("transition"),T.current?.style.removeProperty("display"),P&&k(P)}),I=Ne.useRef(null);D(()=>{(!l||!d)&&(I.current=null)},[l,d]),D(()=>{if(s&&m&&s!==m&&I.current!==s&&g.current){_(g.current),W(!0);let P=Tg(m,s);y(P),R.request(()=>{Hl.flushSync(()=>{W(!1)}),x(()=>{_(null),k(null),g.current=null})}),I.current=s}},[s,m,v,x,R]),D(()=>{let P=h.current;if(!P)return;let A=xe(P).createElement("div");for(let M of Array.from(P.childNodes))A.appendChild(M.cloneNode(!0));g.current=A});let S=v!=null,N;S?N=(0,So.jsxs)(Ne.Fragment,{children:[(0,So.jsx)("div",{"data-previous":!0,inert:_l(!0),ref:T,style:{...E?{[n.popupWidth]:`${E.width}px`,[n.popupHeight]:`${E.height}px`}:null,position:"absolute"},"data-ending-style":C?void 0:""},"previous"),(0,So.jsx)("div",{"data-current":!0,ref:h,"data-starting-style":C?"":void 0,children:r},u)]}):N=(0,So.jsx)("div",{"data-current":!0,ref:h,children:r},u),D(()=>{let P=T.current;!P||!v||P.replaceChildren(...Array.from(v.childNodes))},[v]),Ll({popupElement:f,positionerElement:p,mounted:d,content:c,onMeasureLayout:O,onMeasureLayoutComplete:L,side:o,direction:i});let H={activationDirection:Eg(w),transitioning:S};return{children:N,state:H}}function Eg(e){if(e)return`${Bl(e.horizontal,5,"right","left")} ${Bl(e.vertical,5,"down","up")}`}function Bl(e,t,o,n){return e>t?o:e<-t?n:""}function Tg(e,t){let o=e.getBoundingClientRect(),n=t.getBoundingClientRect(),r={x:o.left+o.width/2,y:o.top+o.height/2},i={x:n.left+n.width/2,y:n.top+n.height/2};return{horizontal:i.x-r.x,vertical:i.y-r.y}}function kg(e,t){let[o,n]=Ne.useState(0),r=Ne.useRef(e),i=Ne.useRef(t),s=Ne.useRef(!1);return D(()=>{let a=r.current,l=i.current,c=e!==a,d=t!==l;c?(n(f=>f+1),s.current=!d):s.current&&d&&(n(f=>f+1),s.current=!1),r.current=e,i.current=t},[e,t]),`${e??"current"}-${o}`}var Qn=b(z(),1),Dl=b(Mt(),1);var jl=b(K(),1),Fl=Qn.forwardRef(function(t,o){let{children:n,container:r,className:i,render:s,style:a,...l}=t,{portalNode:c,portalSubtree:d}=qr({container:r,ref:o,componentProps:t,elementProps:l});return!d&&!c?null:(0,jl.jsxs)(Qn.Fragment,{children:[d,c&&Dl.createPortal(n,c)]})});var Ze={};Ot(Ze,{Arrow:()=>nd,Handle:()=>Zo,Popup:()=>td,Portal:()=>Ql,Positioner:()=>$l,Provider:()=>rd,Root:()=>Wl,Trigger:()=>Kl,Viewport:()=>ad,createHandle:()=>cd});var ht=b(z(),1);var Jn=b(z(),1),ki=Jn.createContext(void 0);function qe(e){let t=Jn.useContext(ki);if(t===void 0&&!e)throw new Error(ke(72));return t}var Vl=b(z(),1);var Pg={...gl,disabled:Z(e=>e.disabled),instantType:Z(e=>e.instantType),isInstantPhase:Z(e=>e.isInstantPhase),trackCursorAxis:Z(e=>e.trackCursorAxis),disableHoverablePopup:Z(e=>e.disableHoverablePopup),lastOpenChangeReason:Z(e=>e.openChangeReason),closeOnClick:Z(e=>e.closeOnClick),closeDelay:Z(e=>e.closeDelay),hasViewport:Z(e=>e.hasViewport)},Eo=class e extends wo{constructor(t,o,n=!1){let r=new jt,i={...Cg(),...t};i.floatingRootContext=pl(r,o,n),super(i,{popupRef:Vl.createRef(),onOpenChange:void 0,onOpenChangeComplete:void 0,triggerElements:r},Pg)}setOpen=(t,o)=>{rl(this,t,o,{extraState:{openChangeReason:o.reason}})};cancelPendingOpen(t){this.state.floatingRootContext.dispatchOpenChange(!1,ee(U.triggerPress,t))}static useStore(t,o){return nl(t,(r,i)=>new e(o,r,i)).store}};function Cg(){return{...fl(),disabled:!1,instantType:void 0,isInstantPhase:!1,trackCursorAxis:"none",disableHoverablePopup:!1,openChangeReason:null,closeOnClick:!0,closeDelay:0,hasViewport:!1}}var $n=b(K(),1),Wl=fi(function(t){let{disabled:o=!1,defaultOpen:n=!1,open:r,disableHoverablePopup:i=!1,trackCursorAxis:s="none",actionsRef:a,onOpenChange:l,onOpenChangeComplete:c,handle:d,triggerId:f,defaultTriggerId:p=null,children:m}=t,u=Eo.useStore(d?.store,{open:n,openProp:r,activeTriggerId:p,triggerIdProp:f});il(u,r,n,p),u.useControlledProp("openProp",r),u.useControlledProp("triggerIdProp",f),u.useContextCallback("onOpenChange",l),u.useContextCallback("onOpenChangeComplete",c);let g=u.useState("open"),v=!o&&g,_=u.useState("activeTriggerId"),w=u.useState("mounted"),y=u.useState("payload");u.useSyncedValues({trackCursorAxis:s,disableHoverablePopup:i}),u.useSyncedValue("disabled",o),al(u,{closeOnActiveTriggerUnmount:!0});let{forceUnmount:h,transitionStatus:T}=cl(v,u),x=u.useState("isInstantPhase"),R=u.useState("instantType"),E=u.useState("lastOpenChangeReason"),k=ht.useRef(null);D(()=>{g&&o&&u.setOpen(!1,ee(U.disabled))},[g,o,u]),D(()=>{T==="ending"&&E===U.none||T!=="ending"&&x?(R!=="delay"&&(k.current=R),u.set("instantType","delay")):k.current!==null&&(u.set("instantType",k.current),k.current=null)},[T,x,E,R,u]),D(()=>{v&&_==null&&u.set("payload",void 0)},[u,_,v]);let C=ht.useCallback(()=>{u.setOpen(!1,ee(U.imperativeAction))},[u]);ht.useImperativeHandle(a,()=>({unmount:h,close:C}),[h,C]);let W=v||w||!o&&s!=="none";return(0,$n.jsxs)(ki.Provider,{value:u,children:[W&&(0,$n.jsx)(Ag,{store:u,disabled:o,trackCursorAxis:s}),typeof m=="function"?m({payload:y}):m]})});function Ag({store:e,disabled:t,trackCursorAxis:o}){let n=e.useState("floatingRootContext"),r=Qr(n,{enabled:!t,referencePress:()=>e.select("closeOnClick")}),i=Zr(n,{enabled:!t&&o!=="none",axis:o==="none"?void 0:o}),s=ht.useMemo(()=>we(i.reference,r.reference),[i.reference,r.reference]),a=ht.useMemo(()=>we(i.trigger,r.trigger),[i.trigger,r.trigger]),l=ht.useMemo(()=>we(ol,i.floating,r.floating),[i.floating,r.floating]);return ll(e,{activeTriggerProps:s,inactiveTriggerProps:a,popupProps:l}),null}var tr=b(z(),1);var er=b(z(),1),Pi=er.createContext(void 0);function Yl(){return er.useContext(Pi)}var Ul=(function(e){return e[e.popupOpen=Ko.popupOpen]="popupOpen",e.triggerDisabled="data-trigger-disabled",e})({});var Xl="data-base-ui-tooltip-trigger";function Gl(e){if("composedPath"in e){let o=e.composedPath();for(let n=0;ng.select("transitionStatus")==="ending",shouldOpen(){return!A.current}}),G=hi(y,{enabled:!S}).reference,q=X=>{let pe=A.current,ue=Gl(X),_t=te(ue),Ee=h.current,Fe=Ee&&ue&&ie(Ee,ue);if(_t&&g.select("open")&&g.select("lastOpenChangeReason")===U.triggerHover){g.setOpen(!1,ee(U.triggerHover,X));return}if(pe&&!_t&&Fe&&!N.current&&!g.select("open")&&Ee&&St(Q.current)){let Xe=()=>{!A.current&&!N.current&&!g.select("open")&&g.setOpen(!0,ee(U.triggerHover,X,Ee))},Be=V();Be===0?(M.clear(),Xe()):M.start(Be,Xe)}},J=g.useState("triggerProps",E);return Pe("button",t,{state:{open:w},ref:[o,R,h],props:[se,G,E||H!=="none"?J:void 0,{onMouseOver(X){q(X.nativeEvent)},onFocus(X){oe(Gl(X.nativeEvent))&&X.preventBaseUIHandler()},onMouseLeave(){A.current=!1,M.clear(),Q.current=void 0},onPointerEnter(X){Q.current=X.pointerType},onPointerDown(X){Q.current=X.pointerType,g.set("closeOnClick",d),d&&!g.select("open")&&g.cancelPendingOpen(X.nativeEvent)},onClick(X){d&&!g.select("open")&&g.cancelPendingOpen(X.nativeEvent)},id:v,[Ul.triggerDisabled]:S?"":void 0,[Xl]:S?void 0:""},m],stateAttributesMapping:vl})});var Zl=b(z(),1);var or=b(z(),1),Ci=or.createContext(void 0);function ql(){let e=or.useContext(Ci);if(e===void 0)throw new Error(ke(70));return e}var Ai=b(K(),1),Ql=Zl.forwardRef(function(t,o){let{keepMounted:n=!1,...r}=t;return qe().useState("mounted")||n?(0,Ai.jsx)(Ci.Provider,{value:n,children:(0,Ai.jsx)(Fl,{ref:o,...r})}):null});var rr=b(z(),1);var nr=b(z(),1),Oi=nr.createContext(void 0);function To(){let e=nr.useContext(Oi);if(e===void 0)throw new Error(ke(71));return e}var Jl=b(K(),1),$l=rr.forwardRef(function(t,o){let{render:n,className:r,anchor:i,positionMethod:s="absolute",side:a="top",align:l="center",sideOffset:c=0,alignOffset:d=0,collisionBoundary:f="clipping-ancestors",collisionPadding:p=5,arrowPadding:m=5,sticky:u=!1,disableAnchorTracking:g=!1,collisionAvoidance:v=ic,style:_,...w}=t,y=qe(),h=ql(),T=y.useState("open"),x=y.useState("mounted"),R=y.useState("trackCursorAxis"),E=y.useState("disableHoverablePopup"),k=y.useState("floatingRootContext"),C=y.useState("instantType"),W=y.useState("transitionStatus"),O=y.useState("hasViewport"),L=kl({anchor:i,positionMethod:s,floatingRootContext:k,mounted:x,side:a,sideOffset:c,align:l,alignOffset:d,collisionBoundary:f,collisionPadding:p,sticky:u,arrowPadding:m,disableAnchorTracking:g,keepMounted:h,collisionAvoidance:v,adaptiveOrigin:O?Rl:void 0}),I=rr.useMemo(()=>({open:T,side:L.side,align:L.align,anchorHidden:L.anchorHidden,instant:R!=="none"?"tracking-cursor":C}),[T,L.side,L.align,L.anchorHidden,R,C]),S=Pl(t,I,{styles:L.positionerStyles,transitionStatus:W,props:w,refs:[o,y.useStateSetter("positionerElement")],hidden:!x,inert:!T||R==="both"||E});return(0,Jl.jsx)(Oi.Provider,{value:L,children:S})});var ed=b(z(),1);var Ng={...xo,...Ta},td=ed.forwardRef(function(t,o){let{render:n,className:r,style:i,...s}=t,a=qe(),{side:l,align:c}=To(),d=a.useState("open"),f=a.useState("instantType"),p=a.useState("transitionStatus"),m=a.useState("popupProps"),u=a.useState("floatingRootContext"),g=a.useState("disabled"),v=a.useState("closeDelay");kn({open:d,ref:a.context.popupRef,onComplete(){d&&a.context.onOpenChangeComplete?.(!0)}}),_i(u,{enabled:!g,closeDelay:v});let _=a.useStateSetter("popupElement");return Pe("div",t,{state:{open:d,side:l,align:c,instant:f,transitionStatus:p},ref:[o,a.context.popupRef,_],props:[m,Xn(p),s],stateAttributesMapping:Ng})});var od=b(z(),1);var nd=od.forwardRef(function(t,o){let{render:n,className:r,style:i,...s}=t,a=qe(),{arrowRef:l,side:c,align:d,arrowUncentered:f,arrowStyles:p}=To(),m=a.useState("open"),u=a.useState("instantType");return Pe("div",t,{state:{open:m,side:c,align:d,uncentered:f,instant:u},ref:[o,l],props:[{style:p,"aria-hidden":!0},s],stateAttributesMapping:xo})});var Ni=b(z(),1);var Li=b(K(),1),rd=function(t){let{delay:o,closeDelay:n,timeout:r=400}=t,i=Ni.useMemo(()=>({delay:o,closeDelay:n}),[o,n]),s=Ni.useMemo(()=>({open:o,close:n}),[o,n]);return(0,Li.jsx)(Pi.Provider,{value:i,children:(0,Li.jsx)(Xr,{delay:s,timeoutMs:r,children:t.children})})};var sd=b(z(),1);var id=(function(e){return e.popupWidth="--popup-width",e.popupHeight="--popup-height",e})({});var Lg={activationDirection:e=>e?{"data-activation-direction":e}:null},ad=sd.forwardRef(function(t,o){let{render:n,className:r,style:i,children:s,...a}=t,l=qe(),c=To(),d=l.useState("instantType"),{children:f,state:p}=zl({store:l,side:c.side,cssVars:id,children:s}),m={activationDirection:p.activationDirection,transitioning:p.transitioning,instant:d};return Pe("div",t,{state:m,ref:o,props:[a,{children:f}],stateAttributesMapping:Lg})});var Zo=class{constructor(){this.store=new Eo}open(t){let o=t?this.store.context.triggerElements.getById(t):void 0;if(t&&!o)throw new Error(ke(81,t));this.store.setOpen(!0,ee(U.imperativeAction,void 0,o))}close(){this.store.setOpen(!1,ee(U.imperativeAction,void 0,void 0))}get isOpen(){return this.store.select("open")}};function cd(){return new Zo}function Qe(e){return Pe(e.defaultTagName??"div",e,e)}var ud=b(ce(),1),Ii="data-wp-hash";function Mi(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Mg(document)),e.__wpStyleRuntime}function Ig(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Ii}]`))if(o.getAttribute(Ii)===t)return!0;return!1}function fd(e,t,o){if(!e.head)return;let n=Mi(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Ig(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Ii,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Mg(e){let t=Mi();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)fd(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function pd(e,t){let o=Mi();o.styles.set(e,t);for(let n of o.documents.keys())fd(n,e,t)}typeof process>"u",pd("a495f9d138",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._83ed8a8da5dd50ea__text{margin:0}._14437cfb77831647__heading-2xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-2xl,32px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-2xl,32px);--_gcd-p-line-height:var(--wpds-typography-line-height-2xl,40px);font-size:var(--wpds-typography-font-size-2xl,32px);line-height:var(--wpds-typography-line-height-2xl,40px)}._14437cfb77831647__heading-2xl,._3c78b7fa9b4072dd__heading-xl{font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-emphasis,600)}._3c78b7fa9b4072dd__heading-xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-p-line-height:var(--wpds-typography-line-height-md,24px);font-size:var(--wpds-typography-font-size-xl,20px);line-height:var(--wpds-typography-line-height-md,24px)}.aa58f227716bcde2__heading-lg{--_gcd-heading-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-lg,15px)}.aa58f227716bcde2__heading-lg,.fc4da56d8dfe52c4__heading-md{font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:var(--wpds-typography-line-height-sm,20px)}.fc4da56d8dfe52c4__heading-md{--_gcd-heading-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-md,13px)}.a9b78c7c82e8dff7__heading-sm{--_gcd-heading-font-size:var(--wpds-typography-font-size-xs,11px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-xs,11px);--_gcd-p-line-height:var(--wpds-typography-line-height-xs,16px);font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-xs,11px);font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:var(--wpds-typography-line-height-xs,16px);text-transform:uppercase}._305ff559e52180d5__body-xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-p-line-height:var(--wpds-typography-line-height-xl,32px);font-size:var(--wpds-typography-font-size-xl,20px);line-height:var(--wpds-typography-line-height-xl,32px)}._305ff559e52180d5__body-xl,.ca1aa3fc2029e958__body-lg{font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-default,400)}.ca1aa3fc2029e958__body-lg{--_gcd-heading-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-p-line-height:var(--wpds-typography-line-height-md,24px);font-size:var(--wpds-typography-font-size-lg,15px);line-height:var(--wpds-typography-line-height-md,24px)}._131101940be12424__body-md{--_gcd-heading-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-md,13px);line-height:var(--wpds-typography-line-height-sm,20px)}._0e8d87a42c1f75fa__body-sm,._131101940be12424__body-md{font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-default,400)}._0e8d87a42c1f75fa__body-sm{--_gcd-heading-font-size:var(--wpds-typography-font-size-sm,12px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-sm,12px);--_gcd-p-line-height:var(--wpds-typography-line-height-xs,16px);font-size:var(--wpds-typography-font-size-sm,12px);line-height:var(--wpds-typography-line-height-xs,16px)}}}');var ld={text:"_83ed8a8da5dd50ea__text","heading-2xl":"_14437cfb77831647__heading-2xl","heading-xl":"_3c78b7fa9b4072dd__heading-xl","heading-lg":"aa58f227716bcde2__heading-lg","heading-md":"fc4da56d8dfe52c4__heading-md","heading-sm":"a9b78c7c82e8dff7__heading-sm","body-xl":"_305ff559e52180d5__body-xl","body-lg":"ca1aa3fc2029e958__body-lg","body-md":"_131101940be12424__body-md","body-sm":"_0e8d87a42c1f75fa__body-sm"};typeof process>"u",pd("af6d9984a6","._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}");var dd={button:"_6defc79820e382c6__button",input:"d2cff2e5dea83bd1__input",textarea:"_547d86373d02e108__textarea",div:"_8c15fd0ed9f28ba4__div",p:"_43cec3e1eec1066d__p",heading:"e97669c6d9a38497__heading",a:"_2c0831b0499dbd6e__a"},Je=(0,ud.forwardRef)(function({variant:t="body-md",render:o,className:n,...r},i){return Qe({render:o,defaultTagName:"span",ref:i,props:we(r,{className:$(ld.text,dd.heading,dd.p,ld[t],n)})})});var hd=b(K(),1),Bi="data-wp-hash";function Hi(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Hg(document)),e.__wpStyleRuntime}function Bg(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Bi}]`))if(o.getAttribute(Bi)===t)return!0;return!1}function bd(e,t,o){if(!e.head)return;let n=Hi(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Bg(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Bi,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Hg(e){let t=Hi();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)bd(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function zg(e,t){let o=Hi();o.styles.set(e,t);for(let n of o.documents.keys())bd(n,e,t)}typeof process>"u",zg("9db2873e7f","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._96e6251aad1a6136__badge{border-radius:var(--wpds-border-radius-lg,8px);padding-block:var(--wpds-dimension-padding-xs,4px);padding-inline:var(--wpds-dimension-padding-sm,8px)}._99f7158cb520f750__is-high-intent{background-color:var(--wpds-color-background-surface-error,#f6e6e3);color:var(--wpds-color-foreground-content-error,#470000)}.c20ebef2365bc8b7__is-medium-intent{background-color:var(--wpds-color-background-surface-warning,#fde6be);color:var(--wpds-color-foreground-content-warning,#2e1900)}._365e1626c6202e52__is-low-intent{background-color:var(--wpds-color-background-surface-caution,#fee995);color:var(--wpds-color-foreground-content-caution,#281d00)}._33f8198127ddf4ef__is-stable-intent{background-color:var(--wpds-color-background-surface-success,#c6f7cd);color:var(--wpds-color-foreground-content-success,#002900)}._04c1aca8fc449412__is-informational-intent{background-color:var(--wpds-color-background-surface-info,#deebfa);color:var(--wpds-color-foreground-content-info,#001b4f)}._90726e69d495ec19__is-draft-intent{background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);color:var(--wpds-color-foreground-content-neutral,#1e1e1e)}._898f4a544993bd39__is-none-intent{background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);padding-block:calc(var(--wpds-dimension-padding-xs, 4px) - var(--wpds-border-width-xs, 1px));padding-inline:calc(var(--wpds-dimension-padding-sm, 8px) - var(--wpds-border-width-xs, 1px))}}}");var md={badge:"_96e6251aad1a6136__badge","is-high-intent":"_99f7158cb520f750__is-high-intent","is-medium-intent":"c20ebef2365bc8b7__is-medium-intent","is-low-intent":"_365e1626c6202e52__is-low-intent","is-stable-intent":"_33f8198127ddf4ef__is-stable-intent","is-informational-intent":"_04c1aca8fc449412__is-informational-intent","is-draft-intent":"_90726e69d495ec19__is-draft-intent","is-none-intent":"_898f4a544993bd39__is-none-intent"},zi=(0,gd.forwardRef)(function({intent:t="none",className:o,...n},r){return(0,hd.jsx)(Je,{ref:r,className:$(md.badge,md[`is-${t}-intent`],o),...n,variant:"body-sm"})});var ir=b(ce(),1),wd=b(lt(),1),_d=b(K(),1);import{speak as Dg}from"@wordpress/a11y";var Di="data-wp-hash";function ji(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Fg(document)),e.__wpStyleRuntime}function jg(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Di}]`))if(o.getAttribute(Di)===t)return!0;return!1}function vd(e,t,o){if(!e.head)return;let n=ji(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(jg(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Di,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Fg(e){let t=ji();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)vd(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function sr(e,t){let o=ji();o.styles.set(e,t);for(let n of o.documents.keys())vd(n,e,t)}typeof process>"u",sr("b74f1ac304",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._97b0fc33c028be1a__button,.abbb272e2ce49bd6__is-unstyled{appearance:none;padding:0}._97b0fc33c028be1a__button{--wp-ui-button-font-weight:var(--wpds-typography-font-weight-emphasis,600);--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-strong,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-strong-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 93%,#000));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand-strong,#fff);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-strong-active,#fff);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-strong-disabled,#8d8d8d);--wp-ui-button-padding-block:var(--wpds-dimension-padding-xs,4px);--wp-ui-button-padding-inline:var(--wpds-dimension-padding-md,12px);--wp-ui-button-height:var(--wpds-dimension-size-lg,40px);--wp-ui-button-aspect-ratio:auto;--wp-ui-button-font-size:var(--wpds-typography-font-size-md,13px);--wp-ui-button-min-width:calc(4ch + var(--wp-ui-button-padding-inline)*2);--wp-ui-button-icon-margin:calc((var(--wpds-dimension-size-2xs, 16px) - var(--wpds-dimension-size-sm, 24px))/2);--wp-ui-button-border-color:var(--wp-ui-button-background-color);--wp-ui-button-border-color-active:var(--wp-ui-button-background-color-active);--wp-ui-button-border-color-disabled:var(--wp-ui-button-background-color-disabled);--_gcd-button-font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);--_gcd-button-font-size:var(--wp-ui-button-font-size);--_gcd-button-font-weight:var(--wp-ui-button-font-weight);align-items:center;aspect-ratio:var(--wp-ui-button-aspect-ratio);background-clip:border-box;background-color:var(--wp-ui-button-background-color);border-color:var(--wp-ui-button-border-color);border-radius:var(--wpds-border-radius-sm,2px);border-style:solid;border-width:1px;color:var(--wp-ui-button-foreground-color);display:inline-flex;font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wp-ui-button-font-size);font-weight:var(--wp-ui-button-font-weight);gap:var(--wpds-dimension-gap-sm,8px);justify-content:center;line-height:var(--wpds-typography-line-height-sm,20px);max-width:100%;min-height:var(--wp-ui-button-height);min-width:var(--wp-ui-button-min-width);overflow-wrap:anywhere;padding-block:var(--wp-ui-button-padding-block);padding-inline:var(--wp-ui-button-padding-inline);position:relative;text-align:center;text-decoration:none;&:not([data-disabled]){cursor:var(--wpds-cursor-control,pointer)}@media not (prefers-reduced-motion){transition:color .1s ease-out;*{transition:opacity .1s ease-out}}&[href]{cursor:pointer}[href]{color:inherit;text-decoration:inherit}&:not([data-disabled]):is(:hover,:active,:focus){background-color:var(--wp-ui-button-background-color-active);border-color:var(--wp-ui-button-border-color-active);color:var(--wp-ui-button-foreground-color-active)}&[data-disabled]:not(._914b42f315c0e580__is-loading){background-color:var(--wp-ui-button-background-color-disabled);border-color:var(--wp-ui-button-border-color-disabled);color:var(--wp-ui-button-foreground-color-disabled);@media (forced-colors:active){border-bottom-color:GrayText;border-left-color:GrayText;border-right-color:GrayText;border-top-color:GrayText;color:GrayText}}&:before{aspect-ratio:1;border:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid;border-block-end-color:transparent;border-block-start-color:var(--wp-ui-button-foreground-color);border-inline-end-color:var(--wp-ui-button-foreground-color);border-inline-start-color:transparent;border-radius:50%;box-sizing:border-box;content:"";display:block;height:var(--wp-ui-button-font-size);inset-inline-start:50%;opacity:0;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);@media not (prefers-reduced-motion){transition:opacity .1s ease-out}@media (forced-colors:active){border-block-end-style:none;border-bottom-color:ButtonText;border-inline-start-style:none;border-left-color:ButtonText;border-right-color:ButtonText;border-top-color:ButtonText}}}._908205475f9f2a92__is-small{--wp-ui-button-padding-block:0px;--wp-ui-button-padding-inline:var(--wpds-dimension-padding-sm,8px);--wp-ui-button-height:var(--wpds-dimension-size-sm,24px)}._9f6fc6553aeb36fe__icon{margin:var(--wp-ui-button-icon-margin)}.dd460c965226cc77__is-brand{&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 85%,#000));--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-brand-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000)}}.e722a8f96726aa99__is-neutral{&.ad0619a3217c6a5b__is-minimal[aria-pressed=true],&.b50b3358c5fb4d0b__is-solid{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-strong,#2d2d2d);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-strong-active,#1e1e1e);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral-strong,#f0f0f0);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-strong-active,#f0f0f0);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-strong-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d);--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-neutral-active,#6e6e6e);--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-neutral-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000)}}.abbb272e2ce49bd6__is-unstyled{background:none;border:none;min-width:unset}.cf59cf1b69629838__is-compact{--wp-ui-button-height:var(--wpds-dimension-size-md,32px)}._914b42f315c0e580__is-loading:not(.abbb272e2ce49bd6__is-unstyled){color:transparent;&:not([data-disabled]):is(:hover,:active,:focus){color:transparent}@media (forced-colors:active){color:ButtonFace}*{opacity:0}&:before{opacity:1;transition-delay:.05s;@media not (prefers-reduced-motion){animation:_5a1d53da6f830c8d__loading-animation 1s linear infinite}}}}@keyframes _5a1d53da6f830c8d__loading-animation{0%{transform:translate(-50%,-50%) rotate(0deg)}to{transform:translate(-50%,-50%) rotate(1turn)}}}');var Qo={button:"_97b0fc33c028be1a__button","is-unstyled":"abbb272e2ce49bd6__is-unstyled","is-loading":"_914b42f315c0e580__is-loading","is-small":"_908205475f9f2a92__is-small",icon:"_9f6fc6553aeb36fe__icon","is-brand":"dd460c965226cc77__is-brand","is-outline":"_62d5a778b7b258ee__is-outline","is-minimal":"ad0619a3217c6a5b__is-minimal","is-neutral":"e722a8f96726aa99__is-neutral","is-solid":"b50b3358c5fb4d0b__is-solid","is-compact":"cf59cf1b69629838__is-compact","loading-animation":"_5a1d53da6f830c8d__loading-animation"};typeof process>"u",sr("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var Vg={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",sr("2ffedd8246","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._64de9947bf305b7a__outset-ring--focus-within-visible:focus-within:has(:focus-visible),.af79fb116edb0dd7__outset-ring--focus:focus,.dfcfdc28396e5d98__outset-ring--focus-visible:focus-visible,.e5cd9ee879f6403a__outset-ring--focus-within:focus-within,:focus-visible ._81935a08e952f267__outset-ring--focus-parent-visible{--focus-color:var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color);outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within,.abc777e9713fa711__outset-ring--focus-except-active:focus{outline:none}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within:not(:has(:active)),.abc777e9713fa711__outset-ring--focus-except-active:focus:not(:active){--focus-color:var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color);outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}}}");var Wg={"outset-ring--focus":"af79fb116edb0dd7__outset-ring--focus","outset-ring--focus-visible":"dfcfdc28396e5d98__outset-ring--focus-visible","outset-ring--focus-within":"e5cd9ee879f6403a__outset-ring--focus-within","outset-ring--focus-within-visible":"_64de9947bf305b7a__outset-ring--focus-within-visible","outset-ring--focus-parent-visible":"_81935a08e952f267__outset-ring--focus-parent-visible","outset-ring--focus-except-active":"abc777e9713fa711__outset-ring--focus-except-active","outset-ring--focus-within-except-active":"_3c9f5ee9fc9c136d__outset-ring--focus-within-except-active"};typeof process>"u",sr("af6d9984a6","._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}");var Yg={button:"_6defc79820e382c6__button",input:"d2cff2e5dea83bd1__input",textarea:"_547d86373d02e108__textarea",div:"_8c15fd0ed9f28ba4__div",p:"_43cec3e1eec1066d__p",heading:"e97669c6d9a38497__heading",a:"_2c0831b0499dbd6e__a"},yd=(0,ir.forwardRef)(function({tone:t="brand",variant:o="solid",size:n="default",className:r,focusableWhenDisabled:i=!0,disabled:s,loading:a,loadingAnnouncement:l=(0,wd.__)("Loading"),children:c,...d},f){let p=$(Yg.button,Vg["box-sizing"],Wg["outset-ring--focus-except-active"],o!=="unstyled"&&Qo.button,Qo[`is-${t}`],Qo[`is-${o}`],Qo[`is-${n}`],a&&Qo["is-loading"],r);return(0,ir.useEffect)(()=>{a&&l&&Dg(l)},[a,l]),(0,_d.jsx)(Si,{ref:f,className:p,focusableWhenDisabled:i,disabled:s??a,...d,children:c})});var Td=b(ce(),1);var Rd=b(ce(),1),Sd=b($t(),1),Ed=b(K(),1),eo=(0,Rd.forwardRef)(function({icon:t,size:o=24,...n},r){return(0,Ed.jsx)(Sd.SVG,{ref:r,...t.props,...n,width:o,height:o})});var Pd=b(K(),1),Fi="data-wp-hash";function Vi(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Gg(document)),e.__wpStyleRuntime}function Ug(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Fi}]`))if(o.getAttribute(Fi)===t)return!0;return!1}function kd(e,t,o){if(!e.head)return;let n=Vi(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Ug(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Fi,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Gg(e){let t=Vi();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)kd(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Xg(e,t){let o=Vi();o.styles.set(e,t);for(let n of o.documents.keys())kd(n,e,t)}typeof process>"u",Xg("b74f1ac304",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._97b0fc33c028be1a__button,.abbb272e2ce49bd6__is-unstyled{appearance:none;padding:0}._97b0fc33c028be1a__button{--wp-ui-button-font-weight:var(--wpds-typography-font-weight-emphasis,600);--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-strong,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-strong-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 93%,#000));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand-strong,#fff);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-strong-active,#fff);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-strong-disabled,#8d8d8d);--wp-ui-button-padding-block:var(--wpds-dimension-padding-xs,4px);--wp-ui-button-padding-inline:var(--wpds-dimension-padding-md,12px);--wp-ui-button-height:var(--wpds-dimension-size-lg,40px);--wp-ui-button-aspect-ratio:auto;--wp-ui-button-font-size:var(--wpds-typography-font-size-md,13px);--wp-ui-button-min-width:calc(4ch + var(--wp-ui-button-padding-inline)*2);--wp-ui-button-icon-margin:calc((var(--wpds-dimension-size-2xs, 16px) - var(--wpds-dimension-size-sm, 24px))/2);--wp-ui-button-border-color:var(--wp-ui-button-background-color);--wp-ui-button-border-color-active:var(--wp-ui-button-background-color-active);--wp-ui-button-border-color-disabled:var(--wp-ui-button-background-color-disabled);--_gcd-button-font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);--_gcd-button-font-size:var(--wp-ui-button-font-size);--_gcd-button-font-weight:var(--wp-ui-button-font-weight);align-items:center;aspect-ratio:var(--wp-ui-button-aspect-ratio);background-clip:border-box;background-color:var(--wp-ui-button-background-color);border-color:var(--wp-ui-button-border-color);border-radius:var(--wpds-border-radius-sm,2px);border-style:solid;border-width:1px;color:var(--wp-ui-button-foreground-color);display:inline-flex;font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wp-ui-button-font-size);font-weight:var(--wp-ui-button-font-weight);gap:var(--wpds-dimension-gap-sm,8px);justify-content:center;line-height:var(--wpds-typography-line-height-sm,20px);max-width:100%;min-height:var(--wp-ui-button-height);min-width:var(--wp-ui-button-min-width);overflow-wrap:anywhere;padding-block:var(--wp-ui-button-padding-block);padding-inline:var(--wp-ui-button-padding-inline);position:relative;text-align:center;text-decoration:none;&:not([data-disabled]){cursor:var(--wpds-cursor-control,pointer)}@media not (prefers-reduced-motion){transition:color .1s ease-out;*{transition:opacity .1s ease-out}}&[href]{cursor:pointer}[href]{color:inherit;text-decoration:inherit}&:not([data-disabled]):is(:hover,:active,:focus){background-color:var(--wp-ui-button-background-color-active);border-color:var(--wp-ui-button-border-color-active);color:var(--wp-ui-button-foreground-color-active)}&[data-disabled]:not(._914b42f315c0e580__is-loading){background-color:var(--wp-ui-button-background-color-disabled);border-color:var(--wp-ui-button-border-color-disabled);color:var(--wp-ui-button-foreground-color-disabled);@media (forced-colors:active){border-bottom-color:GrayText;border-left-color:GrayText;border-right-color:GrayText;border-top-color:GrayText;color:GrayText}}&:before{aspect-ratio:1;border:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid;border-block-end-color:transparent;border-block-start-color:var(--wp-ui-button-foreground-color);border-inline-end-color:var(--wp-ui-button-foreground-color);border-inline-start-color:transparent;border-radius:50%;box-sizing:border-box;content:"";display:block;height:var(--wp-ui-button-font-size);inset-inline-start:50%;opacity:0;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);@media not (prefers-reduced-motion){transition:opacity .1s ease-out}@media (forced-colors:active){border-block-end-style:none;border-bottom-color:ButtonText;border-inline-start-style:none;border-left-color:ButtonText;border-right-color:ButtonText;border-top-color:ButtonText}}}._908205475f9f2a92__is-small{--wp-ui-button-padding-block:0px;--wp-ui-button-padding-inline:var(--wpds-dimension-padding-sm,8px);--wp-ui-button-height:var(--wpds-dimension-size-sm,24px)}._9f6fc6553aeb36fe__icon{margin:var(--wp-ui-button-icon-margin)}.dd460c965226cc77__is-brand{&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 85%,#000));--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-brand-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000)}}.e722a8f96726aa99__is-neutral{&.ad0619a3217c6a5b__is-minimal[aria-pressed=true],&.b50b3358c5fb4d0b__is-solid{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-strong,#2d2d2d);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-strong-active,#1e1e1e);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral-strong,#f0f0f0);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-strong-active,#f0f0f0);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-strong-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d);--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-neutral-active,#6e6e6e);--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-neutral-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000)}}.abbb272e2ce49bd6__is-unstyled{background:none;border:none;min-width:unset}.cf59cf1b69629838__is-compact{--wp-ui-button-height:var(--wpds-dimension-size-md,32px)}._914b42f315c0e580__is-loading:not(.abbb272e2ce49bd6__is-unstyled){color:transparent;&:not([data-disabled]):is(:hover,:active,:focus){color:transparent}@media (forced-colors:active){color:ButtonFace}*{opacity:0}&:before{opacity:1;transition-delay:.05s;@media not (prefers-reduced-motion){animation:_5a1d53da6f830c8d__loading-animation 1s linear infinite}}}}@keyframes _5a1d53da6f830c8d__loading-animation{0%{transform:translate(-50%,-50%) rotate(0deg)}to{transform:translate(-50%,-50%) rotate(1turn)}}}');var Kg={button:"_97b0fc33c028be1a__button","is-unstyled":"abbb272e2ce49bd6__is-unstyled","is-loading":"_914b42f315c0e580__is-loading","is-small":"_908205475f9f2a92__is-small",icon:"_9f6fc6553aeb36fe__icon","is-brand":"dd460c965226cc77__is-brand","is-outline":"_62d5a778b7b258ee__is-outline","is-minimal":"ad0619a3217c6a5b__is-minimal","is-neutral":"e722a8f96726aa99__is-neutral","is-solid":"b50b3358c5fb4d0b__is-solid","is-compact":"cf59cf1b69629838__is-compact","loading-animation":"_5a1d53da6f830c8d__loading-animation"},Wi=(0,Td.forwardRef)(function({className:t,icon:o,...n},r){return(0,Pd.jsx)(eo,{ref:r,icon:o,className:$(Kg.icon,t),size:24,...n})});Wi.displayName="Button.Icon";var ar=Object.assign(yd,{Icon:Wi});var cr=b($t(),1),Yi=b(K(),1),Ui=(0,Yi.jsx)(cr.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,Yi.jsx)(cr.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M5.5 12a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0ZM12 4a8 8 0 1 0 0 16 8 8 0 0 0 0-16Zm-.75 12v-1.5h1.5V16h-1.5Zm0-8v5h1.5V8h-1.5Z"})});var lr=b($t(),1),Gi=b(K(),1),Xi=(0,Gi.jsx)(lr.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,Gi.jsx)(lr.Path,{d:"M12 13.06l3.712 3.713 1.061-1.06L13.061 12l3.712-3.712-1.06-1.06L12 10.938 8.288 7.227l-1.061 1.06L10.939 12l-3.712 3.712 1.06 1.061L12 13.061z"})});var dr=b($t(),1),Ki=b(K(),1),qi=(0,Ki.jsx)(dr.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,Ki.jsx)(dr.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M12.218 5.377a.25.25 0 0 0-.436 0l-7.29 12.96a.25.25 0 0 0 .218.373h14.58a.25.25 0 0 0 .218-.372l-7.29-12.96Zm-1.743-.735c.669-1.19 2.381-1.19 3.05 0l7.29 12.96a1.75 1.75 0 0 1-1.525 2.608H4.71a1.75 1.75 0 0 1-1.525-2.608l7.29-12.96ZM12.75 17.46h-1.5v-1.5h1.5v1.5Zm-1.5-3h1.5v-5h-1.5v5Z"})});var ur=b($t(),1),Zi=b(K(),1),Qi=(0,Zi.jsx)(ur.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,Zi.jsx)(ur.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M5.5 12a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0ZM12 4a8 8 0 1 0 0 16 8 8 0 0 0 0-16Zm.75 4v1.5h-1.5V8h1.5Zm0 8v-5h-1.5v5h1.5Z"})});var fr=b($t(),1),Ji=b(K(),1),$i=(0,Ji.jsx)(fr.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,Ji.jsx)(fr.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M12 18.5a6.5 6.5 0 1 1 0-13 6.5 6.5 0 0 1 0 13ZM4 12a8 8 0 1 1 16 0 8 8 0 0 1-16 0Zm11.53-1.47-1.06-1.06L11 12.94l-1.47-1.47-1.06 1.06L11 15.06l4.53-4.53Z"})});var Cd=b(ce(),1);function es(e,t,o){return(0,Cd.cloneElement)(e??t,{children:o})}var qg=b(Od(),1);var Ld=b(ts(),1),{lock:D4,unlock:Id}=(0,Ld.__dangerousOptInToUnstableAPIsOnlyForCoreModules)("I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.","@wordpress/ui");function Zg(){let e=qg;if(e.ThemeProvider)return e.ThemeProvider;if(!e.privateApis)throw new Error("@wordpress/ui: @wordpress/theme must expose `ThemeProvider` or `privateApis.ThemeProvider`.");return Id(e.privateApis).ThemeProvider}var Md=Zg();var Bd=b(ce(),1),os="data-wp-hash";function ns(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Jg(document)),e.__wpStyleRuntime}function Qg(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${os}]`))if(o.getAttribute(os)===t)return!0;return!1}function Hd(e,t,o){if(!e.head)return;let n=ns(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Qg(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(os,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Jg(e){let t=ns();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Hd(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function $g(e,t){let o=ns();o.styles.set(e,t);for(let n of o.documents.keys())Hd(n,e,t)}typeof process>"u",$g("32aba35fe1","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._19ce0419607e1896__stack{display:flex}}}");var eb={stack:"_19ce0419607e1896__stack"},tb={xs:"var(--wpds-dimension-gap-xs, 4px)",sm:"var(--wpds-dimension-gap-sm, 8px)",md:"var(--wpds-dimension-gap-md, 12px)",lg:"var(--wpds-dimension-gap-lg, 16px)",xl:"var(--wpds-dimension-gap-xl, 24px)","2xl":"var(--wpds-dimension-gap-2xl, 32px)","3xl":"var(--wpds-dimension-gap-3xl, 40px)"},ko=(0,Bd.forwardRef)(function({direction:t,gap:o,align:n,justify:r,wrap:i,render:s,...a},l){let c={gap:o&&tb[o],alignItems:n,justifyContent:r,flexDirection:t,flexWrap:i};return Qe({render:s,ref:l,props:we(a,{style:c,className:eb.stack})})});var du=b(ce(),1);var Zd=b(ce(),1);var Vd=b(ce(),1);var is="data-wp-hash";function ss(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&nb(document)),e.__wpStyleRuntime}function ob(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${is}]`))if(o.getAttribute(is)===t)return!0;return!1}function Dd(e,t,o){if(!e.head)return;let n=ss(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(ob(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(is,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function nb(e){let t=ss();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Dd(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function rb(e,t){let o=ss();o.styles.set(e,t);for(let n of o.documents.keys())Dd(n,e,t)}typeof process>"u",rb("be37f31c1e","._11fc52b637ff8a7e__slot{inset:0;isolation:isolate;pointer-events:none;position:fixed;z-index:1000000003}@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._11fc52b637ff8a7e__slot>*{pointer-events:auto}}}");var zd={slot:"_11fc52b637ff8a7e__slot"},jd="data-wp-compat-overlay-slot";function ib(){return typeof document>"u"?null:document}function sb(){let e;try{e=window.top?.wp}catch{}let t=e??window.wp;return typeof t?.components=="object"&&t.components!==null}var wt=null;function rs(e){return e.setAttribute("aria-hidden","false"),e}function ab(e){let t=e.createElement("div");return t.setAttribute(jd,""),zd.slot&&t.classList.add(zd.slot),e.body.appendChild(t),t}function Fd(){if(typeof window>"u"||!sb()&&window.__wpUiCompatOverlaySlotEnabled!==!0)return;let e=ib();if(!e||!e.body)return;if(wt&&wt.ownerDocument===e&&wt.isConnected)return rs(wt);let t=e.querySelector(`[${jd}]`);return t instanceof HTMLDivElement?(wt=rs(t),wt):(wt?.isConnected&&wt.remove(),wt=rs(ab(e)),wt)}var Wd=b(K(),1),Yd=(0,Vd.forwardRef)(function({container:t,...o},n){return(0,Wd.jsx)(Ze.Portal,{container:t??Fd(),...o,ref:n})});var Ud=b(ce(),1),Kd=b(K(),1),as="data-wp-hash";function cs(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&lb(document)),e.__wpStyleRuntime}function cb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${as}]`))if(o.getAttribute(as)===t)return!0;return!1}function Gd(e,t,o){if(!e.head)return;let n=cs(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(cb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(as,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function lb(e){let t=cs();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Gd(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Xd(e,t){let o=cs();o.styles.set(e,t);for(let n of o.documents.keys())Gd(n,e,t)}typeof process>"u",Xd("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var db={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",Xd("19fcc06039",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}');var ub={positioner:"_480b748dd3510e64__positioner",popup:"_50096b232db7709d__popup"},qd=(0,Ud.forwardRef)(function({align:t="center",className:o,side:n="top",sideOffset:r=4,...i},s){return(0,Kd.jsx)(Ze.Positioner,{ref:s,align:t,side:n,sideOffset:r,...i,className:$(db["box-sizing"],ub.positioner,o)})});var Jo=b(K(),1),ls="data-wp-hash";function ds(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&pb(document)),e.__wpStyleRuntime}function fb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${ls}]`))if(o.getAttribute(ls)===t)return!0;return!1}function Qd(e,t,o){if(!e.head)return;let n=ds(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(fb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(ls,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function pb(e){let t=ds();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Qd(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function mb(e,t){let o=ds();o.styles.set(e,t);for(let n of o.documents.keys())Qd(n,e,t)}typeof process>"u",mb("19fcc06039",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}');var gb={positioner:"_480b748dd3510e64__positioner",popup:"_50096b232db7709d__popup"},bb={background:"#1e1e1e"},us=(0,Zd.forwardRef)(function({portal:t,positioner:o,children:n,className:r,...i},s){let a=(0,Jo.jsx)(Md,{color:bb,children:(0,Jo.jsx)(Ze.Popup,{ref:s,className:$(gb.popup,r),...i,children:n})}),l=es(o,(0,Jo.jsx)(qd,{}),a);return es(t,(0,Jo.jsx)(Yd,{}),l)});var Jd=b(ce(),1),$d=b(K(),1),fs=(0,Jd.forwardRef)(function(t,o){return(0,$d.jsx)(Ze.Trigger,{ref:o,...t})});var eu=b(lt(),1),tu=b(K(),1);function ou({children:e}){return(0,tu.jsx)(Zn,{direction:(0,eu.isRTL)()?"rtl":"ltr",children:e})}var ps=b(K(),1);function ms(e){return(0,ps.jsx)(ou,{children:(0,ps.jsx)(Ze.Root,{...e})})}var iu=b(ce(),1),mr=b(lt(),1);var nu=b(ce(),1),gs="data-wp-hash";function bs(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&vb(document)),e.__wpStyleRuntime}function wb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${gs}]`))if(o.getAttribute(gs)===t)return!0;return!1}function ru(e,t,o){if(!e.head)return;let n=bs(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(wb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(gs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function vb(e){let t=bs();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)ru(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function _b(e,t){let o=bs();o.styles.set(e,t);for(let n of o.documents.keys())ru(n,e,t)}typeof process>"u",_b("fa606a57ae","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.f37b9e2e191ebd66__visually-hidden{word-wrap:normal;border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-break:normal}}}");var yb={"visually-hidden":"f37b9e2e191ebd66__visually-hidden"},hs=(0,nu.forwardRef)(function({render:t,...o},n){return Qe({render:t,ref:n,props:we({className:yb["visually-hidden"]},o,{"data-visually-hidden":""})})});var pr=b(K(),1);function su({"aria-describedby":e,"aria-keyshortcuts":t,shortcut:o}){let n=(0,iu.useId)(),r=o?n:void 0,i=[e,r].filter(Boolean).join(" ");return{descriptionId:r,targetProps:{"aria-describedby":i||void 0,"aria-keyshortcuts":o?.ariaKeyShortcut??t}}}function au({descriptionId:e,shortcut:t}){return(0,pr.jsx)(hs,{id:e,"aria-hidden":"true",render:(0,pr.jsx)("span",{}),children:(0,mr.sprintf)((0,mr.__)("Keyboard shortcut: %s"),t.label??t.ariaKeyShortcut)})}function cu({className:e,shortcut:t}){return(0,pr.jsx)("span",{"aria-hidden":"true",className:e,dir:"ltr",children:t.displayShortcut})}var $e=b(K(),1),ws="data-wp-hash";function vs(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Rb(document)),e.__wpStyleRuntime}function xb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${ws}]`))if(o.getAttribute(ws)===t)return!0;return!1}function uu(e,t,o){if(!e.head)return;let n=vs(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(xb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(ws,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Rb(e){let t=vs();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)uu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Sb(e,t){let o=vs();o.styles.set(e,t);for(let n of o.documents.keys())uu(n,e,t)}typeof process>"u",Sb("c5cdafb1bc","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer compositions{._28cfdc260e755391__icon-button{--wp-ui-button-aspect-ratio:1;--wp-ui-button-padding-inline:0px;--wp-ui-button-min-width:unset}.f1c70d719989a85a__icon{margin:-1px}}}");var lu={"icon-button":"_28cfdc260e755391__icon-button",icon:"f1c70d719989a85a__icon"},_s=(0,du.forwardRef)(function({label:t,className:o,children:n,disabled:r,focusableWhenDisabled:i=!0,icon:s,size:a,shortcut:l,positioner:c,"aria-describedby":d,"aria-keyshortcuts":f,...p},m){let u=$(lu["icon-button"],o),{descriptionId:g,targetProps:v}=su({"aria-describedby":d,"aria-keyshortcuts":f,shortcut:l});return(0,$e.jsxs)(ms,{children:[(0,$e.jsxs)(fs,{ref:m,...v,disabled:r&&!i,render:(0,$e.jsx)(ar,{...p,size:a,"aria-label":t,disabled:r,focusableWhenDisabled:i}),className:u,children:[(0,$e.jsx)(eo,{icon:s,size:24,className:lu.icon}),l&&g&&(0,$e.jsx)(au,{descriptionId:g,shortcut:l})]}),(0,$e.jsxs)(us,{positioner:c,children:[t,l&&(0,$e.jsxs)($e.Fragment,{children:[" ",(0,$e.jsx)(cu,{shortcut:l})]})]})]})});var fu=b(ce(),1),pu=b(lt(),1),Po=b(K(),1),ys="data-wp-hash";function xs(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Tb(document)),e.__wpStyleRuntime}function Eb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${ys}]`))if(o.getAttribute(ys)===t)return!0;return!1}function mu(e,t,o){if(!e.head)return;let n=xs(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Eb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(ys,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Tb(e){let t=xs();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)mu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function br(e,t){let o=xs();o.styles.set(e,t);for(let n of o.documents.keys())mu(n,e,t)}typeof process>"u",br("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var kb={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",br("2ffedd8246","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._64de9947bf305b7a__outset-ring--focus-within-visible:focus-within:has(:focus-visible),.af79fb116edb0dd7__outset-ring--focus:focus,.dfcfdc28396e5d98__outset-ring--focus-visible:focus-visible,.e5cd9ee879f6403a__outset-ring--focus-within:focus-within,:focus-visible ._81935a08e952f267__outset-ring--focus-parent-visible{--focus-color:var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color);outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within,.abc777e9713fa711__outset-ring--focus-except-active:focus{outline:none}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within:not(:has(:active)),.abc777e9713fa711__outset-ring--focus-except-active:focus:not(:active){--focus-color:var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color);outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}}}");var Pb={"outset-ring--focus":"af79fb116edb0dd7__outset-ring--focus","outset-ring--focus-visible":"dfcfdc28396e5d98__outset-ring--focus-visible","outset-ring--focus-within":"e5cd9ee879f6403a__outset-ring--focus-within","outset-ring--focus-within-visible":"_64de9947bf305b7a__outset-ring--focus-within-visible","outset-ring--focus-parent-visible":"_81935a08e952f267__outset-ring--focus-parent-visible","outset-ring--focus-except-active":"abc777e9713fa711__outset-ring--focus-except-active","outset-ring--focus-within-except-active":"_3c9f5ee9fc9c136d__outset-ring--focus-within-except-active"};typeof process>"u",br("e8e6a9be37",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.d4250949359b05ce__link{text-decoration-thickness:from-font;text-underline-offset:.2em}.c6055659b8e2cd2c__is-brand,.c6055659b8e2cd2c__is-brand:visited{--_gcd-a-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9))}.c6055659b8e2cd2c__is-brand:active,.c6055659b8e2cd2c__is-brand:hover{--_gcd-a-color:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));color:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000))}._92e0dfcaeee15b88__is-neutral,._92e0dfcaeee15b88__is-neutral:visited{--_gcd-a-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);text-decoration-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d)}._92e0dfcaeee15b88__is-neutral:active,._92e0dfcaeee15b88__is-neutral:hover{--_gcd-a-color:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);color:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e)}.cf122a9bf1035d42__is-unstyled{--_gcd-a-color:inherit;color:inherit;text-decoration:none}._0cb411afac4c86c7__link-icon{display:inline-block;font-weight:var(--wpds-typography-font-weight-default,400);line-height:1;margin-inline-start:var(--wpds-dimension-padding-xs,4px);text-decoration:none}._0cb411afac4c86c7__link-icon:after{content:"\\2197"}._0cb411afac4c86c7__link-icon:dir(rtl):after{content:"\\2196"}}}');var gr={link:"d4250949359b05ce__link","is-brand":"c6055659b8e2cd2c__is-brand","is-neutral":"_92e0dfcaeee15b88__is-neutral","is-unstyled":"cf122a9bf1035d42__is-unstyled","link-icon":"_0cb411afac4c86c7__link-icon"};typeof process>"u",br("af6d9984a6","._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}");var Cb={button:"_6defc79820e382c6__button",input:"d2cff2e5dea83bd1__input",textarea:"_547d86373d02e108__textarea",div:"_8c15fd0ed9f28ba4__div",p:"_43cec3e1eec1066d__p",heading:"e97669c6d9a38497__heading",a:"_2c0831b0499dbd6e__a"},$o=(0,fu.forwardRef)(function({children:t,variant:o="default",tone:n="brand",openInNewTab:r=!1,render:i,className:s,...a},l){return Qe({render:i,defaultTagName:"a",ref:l,props:we(a,{className:$(Cb.a,kb["box-sizing"],Pb["outset-ring--focus-except-active"],o!=="unstyled"&&gr.link,o!=="unstyled"&&gr[`is-${n}`],o==="unstyled"&&gr["is-unstyled"],s),target:r?"_blank":void 0,children:(0,Po.jsxs)(Po.Fragment,{children:[t,r&&(0,Po.jsx)("span",{className:gr["link-icon"],role:"img","aria-label":(0,pu.__)("(opens in a new tab)")})]})})})});var en={};Ot(en,{ActionButton:()=>zu,ActionLink:()=>Fu,Actions:()=>Pu,CloseIcon:()=>Lu,Description:()=>Eu,Root:()=>hu,Title:()=>yu});var Co=b(ce(),1);import{speak as Ab}from"@wordpress/a11y";var Ao=b(K(),1),Ss="data-wp-hash";function Es(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Nb(document)),e.__wpStyleRuntime}function Ob(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Ss}]`))if(o.getAttribute(Ss)===t)return!0;return!1}function gu(e,t,o){if(!e.head)return;let n=Es(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Ob(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Ss,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Nb(e){let t=Es();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)gu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function bu(e,t){let o=Es();o.styles.set(e,t);for(let n of o.documents.keys())gu(n,e,t)}typeof process>"u",bu("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var Lb={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",bu("726c480820","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var Rs={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},Ib={neutral:null,info:Qi,warning:Ui,success:$i,error:qi};function Mb(e){return e==="error"?"assertive":"polite"}function Bb(e){if(e){if(typeof e=="string")return e;try{return(0,Co.renderToString)(e)}catch{return}}}function Hb(e,t){let o=Bb(e);(0,Co.useEffect)(()=>{o&&Ab(o,t)},[o,t])}var hu=(0,Co.forwardRef)(function({intent:t="neutral",children:o,icon:n,spokenMessage:r=o,politeness:i=Mb(t),render:s,...a},l){Hb(r,i);let c=n===null?null:n??Ib[t],d=$(Rs.notice,Rs[`is-${t}`],Lb["box-sizing"]);return Qe({defaultTagName:"div",render:s,ref:l,props:we({className:d,children:(0,Ao.jsxs)(Ao.Fragment,{children:[o,c&&(0,Ao.jsx)(eo,{className:Rs.icon,icon:c})]})},a)})});var wu=b(ce(),1);var _u=b(K(),1),Ts="data-wp-hash";function ks(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Db(document)),e.__wpStyleRuntime}function zb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Ts}]`))if(o.getAttribute(Ts)===t)return!0;return!1}function vu(e,t,o){if(!e.head)return;let n=ks(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(zb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Ts,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Db(e){let t=ks();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)vu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function jb(e,t){let o=ks();o.styles.set(e,t);for(let n of o.documents.keys())vu(n,e,t)}typeof process>"u",jb("726c480820","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var Fb={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},yu=(0,wu.forwardRef)(function({className:t,...o},n){return(0,_u.jsx)(Je,{ref:n,variant:"heading-md",className:$(Fb.title,t),...o})});var xu=b(ce(),1);var Su=b(K(),1),Ps="data-wp-hash";function Cs(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Wb(document)),e.__wpStyleRuntime}function Vb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Ps}]`))if(o.getAttribute(Ps)===t)return!0;return!1}function Ru(e,t,o){if(!e.head)return;let n=Cs(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Vb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Ps,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Wb(e){let t=Cs();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Ru(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Yb(e,t){let o=Cs();o.styles.set(e,t);for(let n of o.documents.keys())Ru(n,e,t)}typeof process>"u",Yb("726c480820","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var Ub={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},Eu=(0,xu.forwardRef)(function({className:t,...o},n){return(0,Su.jsx)(Je,{ref:n,variant:"body-md",className:$(Ub.description,t),...o})});var Tu=b(ce(),1);var As="data-wp-hash";function Os(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Xb(document)),e.__wpStyleRuntime}function Gb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${As}]`))if(o.getAttribute(As)===t)return!0;return!1}function ku(e,t,o){if(!e.head)return;let n=Os(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Gb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(As,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Xb(e){let t=Os();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)ku(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Kb(e,t){let o=Os();o.styles.set(e,t);for(let n of o.documents.keys())ku(n,e,t)}typeof process>"u",Kb("726c480820","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var qb={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},Pu=(0,Tu.forwardRef)(function({render:t,...o},n){return Qe({defaultTagName:"div",render:t,ref:n,props:we({className:qb.actions},o)})});var Cu=b(ce(),1),Au=b(lt(),1);var Nu=b(K(),1),Ns="data-wp-hash";function Ls(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Qb(document)),e.__wpStyleRuntime}function Zb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Ns}]`))if(o.getAttribute(Ns)===t)return!0;return!1}function Ou(e,t,o){if(!e.head)return;let n=Ls(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Zb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Ns,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Qb(e){let t=Ls();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Ou(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Jb(e,t){let o=Ls();o.styles.set(e,t);for(let n of o.documents.keys())Ou(n,e,t)}typeof process>"u",Jb("726c480820","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var $b={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},Lu=(0,Cu.forwardRef)(function({className:t,icon:o=Xi,label:n=(0,Au.__)("Dismiss"),...r},i){return(0,Nu.jsx)(_s,{...r,ref:i,className:$($b["close-icon"],t),variant:"minimal",size:"small",tone:"neutral",icon:o,label:n})});var Mu=b(ce(),1);var Hu=b(K(),1),Is="data-wp-hash";function Ms(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&t0(document)),e.__wpStyleRuntime}function e0(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Is}]`))if(o.getAttribute(Is)===t)return!0;return!1}function Bu(e,t,o){if(!e.head)return;let n=Ms(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(e0(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Is,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function t0(e){let t=Ms();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Bu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function o0(e,t){let o=Ms();o.styles.set(e,t);for(let n of o.documents.keys())Bu(n,e,t)}typeof process>"u",o0("726c480820","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var Iu={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},zu=(0,Mu.forwardRef)(function({className:t,loading:o,loadingAnnouncement:n,variant:r,...i},s){return(0,Hu.jsx)(ar,{...i,...o!==void 0?{loading:o,loadingAnnouncement:n??""}:{},ref:s,size:"compact",tone:"neutral",variant:r,className:$(Iu["action-button"],Iu[`is-action-button-${r}`],t)})});var Du=b(ce(),1);var Hs=b(K(),1),Bs="data-wp-hash";function zs(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&r0(document)),e.__wpStyleRuntime}function n0(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Bs}]`))if(o.getAttribute(Bs)===t)return!0;return!1}function ju(e,t,o){if(!e.head)return;let n=zs(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(n0(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Bs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function r0(e){let t=zs();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)ju(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function i0(e,t){let o=zs();o.styles.set(e,t);for(let n of o.documents.keys())ju(n,e,t)}typeof process>"u",i0("726c480820","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var s0={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},Fu=(0,Du.forwardRef)(function({className:t,render:o,...n},r){return(0,Hs.jsx)(Je,{ref:r,className:$(s0["action-link"],t),...n,variant:"body-md",render:(0,Hs.jsx)($o,{tone:"neutral",variant:"default",render:o})})});var Vu=b(ce(),1),Wu=b(K(),1),Yu=(0,Vu.forwardRef)(({children:e,className:t,ariaLabel:o,as:n="div",...r},i)=>(0,Wu.jsx)(n,{ref:i,className:$("admin-ui-navigable-region",t),"aria-label":o,role:"region",tabIndex:"-1",...r,children:e}));Yu.displayName="NavigableRegion";var Uu=Yu;var Xu=b(tn(),1),{Fill:Ku,Slot:qu}=(0,Xu.createSlotFill)("SidebarToggle");var et=b(K(),1),Ds="data-wp-hash";function js(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&c0(document)),e.__wpStyleRuntime}function a0(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Ds}]`))if(o.getAttribute(Ds)===t)return!0;return!1}function Zu(e,t,o){if(!e.head)return;let n=js(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(a0(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Ds,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function c0(e){let t=js();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Zu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function l0(e,t){let o=js();o.styles.set(e,t);for(let n of o.documents.keys())Zu(n,e,t)}typeof process>"u",l0("ddd9aab364","._956b6df0898efed0__page{text-wrap:pretty;background-color:var(--wpds-color-background-surface-neutral,#fcfcfc);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);display:flex;flex-flow:column;height:100%;position:relative;z-index:1}._0625b55e82a0d93d__header{background:var(--wpds-color-background-surface-neutral-strong,#fff);border-block-end:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral-weak,#f0f0f0);inset-block-start:0;padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px);position:sticky;z-index:1}.a43c44d5ae28b2e8__header-content{min-height:var(--wpds-dimension-size-md,32px)}.b7cb5b9daf3a3b25__header-actions{flex-shrink:0}._8113be94e7caf73c__header-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._9a776c7f70996f61__header-visual{display:grid;flex-shrink:0;grid-template-columns:1fr;grid-template-rows:1fr;height:var(--wpds-dimension-size-sm,24px);width:var(--wpds-dimension-size-sm,24px);>*{grid-column:1/-1;grid-row:1/-1;max-height:100%;max-width:100%}}.d5e0920cd15d35bc__sidebar-toggle-slot:empty{display:none}._60fea2f6bf5319cd__header-subtitle{color:var(--wpds-color-foreground-content-neutral-weak,#707070);padding-block-end:var(--wpds-dimension-padding-xs,4px)}.be5e57d029ec4036__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;&._128806d0b26e3a50__has-padding{padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px)}}");var to={page:"_956b6df0898efed0__page",header:"_0625b55e82a0d93d__header","header-content":"a43c44d5ae28b2e8__header-content","header-actions":"b7cb5b9daf3a3b25__header-actions","header-title":"_8113be94e7caf73c__header-title","header-visual":"_9a776c7f70996f61__header-visual","sidebar-toggle-slot":"d5e0920cd15d35bc__sidebar-toggle-slot","header-subtitle":"_60fea2f6bf5319cd__header-subtitle",content:"be5e57d029ec4036__content","has-padding":"_128806d0b26e3a50__has-padding"};function Qu({headingLevel:e=1,breadcrumbs:t,badges:o,visual:n,title:r,subTitle:i,actions:s,showSidebarToggle:a=!0}){let l=`h${e}`;return(0,et.jsxs)(ko,{direction:"column",className:to.header,children:[(0,et.jsxs)(ko,{className:to["header-content"],direction:"row",gap:"sm",justify:"space-between",children:[(0,et.jsxs)(ko,{direction:"row",gap:"sm",align:"center",justify:"start",children:[a&&(0,et.jsx)(qu,{bubblesVirtually:!0,className:to["sidebar-toggle-slot"]}),n&&(0,et.jsx)("div",{className:to["header-visual"],"aria-hidden":"true",children:n}),r&&(0,et.jsx)(Je,{className:to["header-title"],render:(0,et.jsx)(l,{}),variant:"heading-lg",children:r}),t,o]}),s&&(0,et.jsx)(ko,{align:"center",className:to["header-actions"],direction:"row",gap:"sm",children:s})]}),i&&(0,et.jsx)(Je,{render:(0,et.jsx)("p",{}),variant:"body-md",className:to["header-subtitle"],children:i})]})}var on=b(K(),1),Vs="data-wp-hash";function Ws(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&u0(document)),e.__wpStyleRuntime}function d0(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Vs}]`))if(o.getAttribute(Vs)===t)return!0;return!1}function Ju(e,t,o){if(!e.head)return;let n=Ws(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(d0(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Vs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function u0(e){let t=Ws();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Ju(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function f0(e,t){let o=Ws();o.styles.set(e,t);for(let n of o.documents.keys())Ju(n,e,t)}typeof process>"u",f0("ddd9aab364","._956b6df0898efed0__page{text-wrap:pretty;background-color:var(--wpds-color-background-surface-neutral,#fcfcfc);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);display:flex;flex-flow:column;height:100%;position:relative;z-index:1}._0625b55e82a0d93d__header{background:var(--wpds-color-background-surface-neutral-strong,#fff);border-block-end:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral-weak,#f0f0f0);inset-block-start:0;padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px);position:sticky;z-index:1}.a43c44d5ae28b2e8__header-content{min-height:var(--wpds-dimension-size-md,32px)}.b7cb5b9daf3a3b25__header-actions{flex-shrink:0}._8113be94e7caf73c__header-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._9a776c7f70996f61__header-visual{display:grid;flex-shrink:0;grid-template-columns:1fr;grid-template-rows:1fr;height:var(--wpds-dimension-size-sm,24px);width:var(--wpds-dimension-size-sm,24px);>*{grid-column:1/-1;grid-row:1/-1;max-height:100%;max-width:100%}}.d5e0920cd15d35bc__sidebar-toggle-slot:empty{display:none}._60fea2f6bf5319cd__header-subtitle{color:var(--wpds-color-foreground-content-neutral-weak,#707070);padding-block-end:var(--wpds-dimension-padding-xs,4px)}.be5e57d029ec4036__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;&._128806d0b26e3a50__has-padding{padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px)}}");var Fs={page:"_956b6df0898efed0__page",header:"_0625b55e82a0d93d__header","header-content":"a43c44d5ae28b2e8__header-content","header-actions":"b7cb5b9daf3a3b25__header-actions","header-title":"_8113be94e7caf73c__header-title","header-visual":"_9a776c7f70996f61__header-visual","sidebar-toggle-slot":"d5e0920cd15d35bc__sidebar-toggle-slot","header-subtitle":"_60fea2f6bf5319cd__header-subtitle",content:"be5e57d029ec4036__content","has-padding":"_128806d0b26e3a50__has-padding"};function $u({headingLevel:e,breadcrumbs:t,badges:o,visual:n,title:r,subTitle:i,children:s,className:a,actions:l,ariaLabel:c,hasPadding:d=!1,showSidebarToggle:f=!0}){let p=$(Fs.page,a);return(0,on.jsxs)(Uu,{className:p,ariaLabel:c??(typeof r=="string"?r:""),children:[(r||t||o||l||n)&&(0,on.jsx)(Qu,{headingLevel:e,breadcrumbs:t,badges:o,visual:n,title:r,subTitle:i,actions:l,showSidebarToggle:f}),d?(0,on.jsx)("div",{className:$(Fs.content,Fs["has-padding"]),children:s}):s]})}$u.SidebarToggleFill=Ku;var Ys=$u;var at=b(tn()),Ef=b(nn()),Tf=b(ce()),kt=b(lt()),kf=b(hr());import{privateApis as C0}from"@wordpress/connectors";var of=b(ts()),{lock:V3,unlock:Oo}=(0,of.__dangerousOptInToUnstableAPIsOnlyForCoreModules)("I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.","@wordpress/routes");if(typeof document<"u"&&!document.head.querySelector("style[data-wp-hash='09e9b056ea']")){let e=document.createElement("style");e.setAttribute("data-wp-hash","09e9b056ea"),e.appendChild(document.createTextNode(".connectors-page{box-sizing:border-box;margin:0 auto;max-width:680px;padding:24px;width:100%}.connectors-page .components-item{background:#fff;border:1px solid #ddd;border-radius:8px;overflow:hidden;padding:20px;scroll-margin-top:120px}.connectors-page .connector-settings__error{color:#cc1818}.connectors-page .connector-settings .components-text-control__input{font-family:monospace;scroll-margin-top:120px}.connectors-page__file-mods-notice{margin-bottom:16px}.connectors-page--empty{align-items:center;display:flex;flex-direction:column;flex-grow:1;gap:32px;justify-content:center;text-align:center}.connectors-page .ai-plugin-callout{background-color:#e7d4e4;background-image:radial-gradient(ellipse 70% 120% at 18% 115%,rgba(202,158,198,.75) 0,rgba(202,158,198,0) 60%),radial-gradient(ellipse 55% 110% at 92% -15%,rgba(208,175,217,.7) 0,rgba(208,175,217,0) 65%),radial-gradient(ellipse 40% 85% at 58% -10%,rgba(170,130,184,.45) 0,rgba(170,130,184,0) 70%);border-radius:8px;overflow:hidden;padding:24px;padding-inline-end:150px;position:relative}[dir=rtl] .connectors-page .ai-plugin-callout{background-image:radial-gradient(ellipse 70% 120% at 82% 115%,rgba(202,158,198,.75) 0,rgba(202,158,198,0) 60%),radial-gradient(ellipse 55% 110% at 8% -15%,rgba(208,175,217,.7) 0,rgba(208,175,217,0) 65%),radial-gradient(ellipse 40% 85% at 42% -10%,rgba(170,130,184,.45) 0,rgba(170,130,184,0) 70%)}.connectors-page .ai-plugin-callout__content{align-items:flex-start;display:flex;flex-direction:column;gap:12px;padding-top:2px}.connectors-page .ai-plugin-callout__content p{font-size:13px;line-height:20px;margin:0}.connectors-page .ai-plugin-callout__decoration{height:110px;inset-inline-end:16px;position:absolute;top:12px;width:110px}.connectors-page>p{color:#949494}@media (max-width:680px){.connectors-page .ai-plugin-callout{padding:12px;padding-inline-end:100px}.connectors-page .ai-plugin-callout__decoration{height:75px;inset-inline-end:8px;top:8px;width:75px}}@media (max-width:480px){.connectors-page{padding:8px}.connectors-page .ai-plugin-callout{padding-inline-end:130px}.connectors-page .components-item{padding:12px}.connectors-page .components-item>.components-v-stack>.components-h-stack:first-child svg{height:32px;width:32px}.connectors-page .components-item>.components-v-stack>.components-h-stack:first-child>.components-h-stack:last-child{align-items:flex-end;flex-direction:column}}")),document.head.appendChild(e)}var an=b(tn()),Qs=b(hr()),cn=b(nn()),vt=b(ce()),Ge=b(lt()),yf=b(Us()),xf=b(sf());var wr=b(tn()),Ks=b(ce()),mf=b(nn()),oo=b(lt());import{__experimentalRegisterConnector as p0,__experimentalConnectorItem as pf,__experimentalDefaultConnectorSettings as m0,__experimentalApplicationPasswordConnectorSettings as g0,privateApis as b0}from"@wordpress/connectors";var Gs=b(hr()),sn=b(nn()),rn=b(ce()),fe=b(lt()),af=b(Us());function Xs({file:e,settingName:t,connectorName:o,isInstalled:n,isActivated:r,keySource:i="none",initialIsConnected:s=!1}){let[a,l]=(0,rn.useState)(!1),[c,d]=(0,rn.useState)(!1),[f,p]=(0,rn.useState)(s),[m,u]=(0,rn.useState)(null),g=e?.replace(/\.php$/,""),v=g?.includes("/")?g.split("/")[0]:g,{derivedPluginStatus:_,canManagePlugins:w,currentApiKey:y,currentUsername:h,hasStoredCredentials:T,hasResolvedSettings:x,canInstallPlugins:R}=(0,sn.useSelect)(q=>{let J=q(Gs.store),ge=J.getEntityRecord("root","site")?.[t],de=typeof ge=="string"?ge:"",X=typeof ge=="object"&&ge!==null?ge:void 0,pe=X!==void 0?!!X.username&&!!X.password:!!de,ue=J.hasFinishedResolution("getEntityRecord",["root","site"]),_t=!!J.canUser("create",{kind:"root",name:"plugin"}),Ee={currentApiKey:de,currentUsername:X?.username??"",hasStoredCredentials:pe,hasResolvedSettings:ue,canInstallPlugins:_t};if(!e)return{...Ee,derivedPluginStatus:ue?"active":"checking",canManagePlugins:void 0};let Fe=J.getEntityRecord("root","plugin",g);if(!J.hasFinishedResolution("getEntityRecord",["root","plugin",g]))return{...Ee,derivedPluginStatus:"checking",canManagePlugins:void 0};if(Fe){let no=Fe.status==="active"||Fe.status==="network-active";return{...Ee,derivedPluginStatus:no?"active":"inactive",canManagePlugins:!0}}let Be="not-installed";return r?Be="active":n&&(Be="inactive"),{...Ee,derivedPluginStatus:Be,canManagePlugins:!1}},[e,g,t,n,r]),E=m??_,k=w,C=E==="active"&&f||m==="active"&&T,{saveEntityRecord:W,invalidateResolution:O}=(0,sn.useDispatch)(Gs.store),{createSuccessNotice:L,createErrorNotice:I}=(0,sn.useDispatch)(af.store),S=q=>W("root","site",{[t]:q},{throwOnError:!0}),N=()=>{L((0,fe.sprintf)((0,fe.__)("%s connected successfully."),o),{id:"connector-connect-success",type:"snackbar"})},H=()=>{L((0,fe.sprintf)((0,fe.__)("%s disconnected."),o),{id:"connector-disconnect-success",type:"snackbar"})},P=()=>{I((0,fe.sprintf)((0,fe.__)("Failed to disconnect %s."),o),{id:"connector-disconnect-error",type:"snackbar"})},A=async()=>{if(v){d(!0);try{await W("root","plugin",{slug:v,status:"active"},{throwOnError:!0}),u("active"),O("getEntityRecord",["root","site"]),l(!0),L((0,fe.sprintf)((0,fe.__)("Plugin for %s installed and activated successfully."),o),{id:"connector-plugin-install-success",type:"snackbar"})}catch{I((0,fe.sprintf)((0,fe.__)("Failed to install plugin for %s."),o),{id:"connector-plugin-install-error",type:"snackbar"})}finally{d(!1)}}},M=async()=>{if(e){d(!0);try{await W("root","plugin",{plugin:g,status:"active"},{throwOnError:!0}),u("active"),O("getEntityRecord",["root","site"]),l(!0),L((0,fe.sprintf)((0,fe.__)("Plugin for %s activated successfully."),o),{id:"connector-plugin-activate-success",type:"snackbar"})}catch{I((0,fe.sprintf)((0,fe.__)("Failed to activate plugin for %s."),o),{id:"connector-plugin-activate-error",type:"snackbar"})}finally{d(!1)}}};return{pluginStatus:E,canInstallPlugins:R,canActivatePlugins:k,isExpanded:a,setIsExpanded:l,isBusy:c,isConnected:C,currentApiKey:y,currentUsername:h,hasResolvedSettings:x,keySource:i,handleButtonClick:()=>{if(E==="not-installed"){if(R===!1)return;A()}else if(E==="inactive"){if(k===!1)return;M()}else l(!a)},getButtonLabel:()=>{if(c)return E==="not-installed"?(0,fe.__)("Installing\u2026"):(0,fe.__)("Activating\u2026");if(a)return(0,fe.__)("Cancel");if(C)return(0,fe.__)("Edit");switch(E){case"checking":return(0,fe.__)("Checking\u2026");case"not-installed":return(0,fe.__)("Install");case"inactive":return(0,fe.__)("Activate");case"active":return(0,fe.__)("Set up")}},saveApiKey:async q=>{let J=y;try{let de=(await S(q))?.[t];if(q&&(de===J||!de))throw new Error("It was not possible to connect to the provider using this key.");p(!0),N()}catch(ne){throw console.error("Failed to save API key:",ne),ne}},removeApiKey:async()=>{try{await S(""),p(!1),H()}catch(q){console.error("Failed to remove API key:",q),P()}},saveCredentials:async({username:q,applicationPassword:J})=>{try{let de=(await S({username:q,password:J}))?.[t];if(!de?.username||!de?.password)throw new Error((0,fe.__)("It was not possible to save these credentials."));p(!0),N()}catch(ne){throw console.error("Failed to save credentials:",ne),ne}},removeCredentials:async()=>{try{await S({username:"",password:""}),p(!1),H()}catch(q){console.error("Failed to remove credentials:",q),P()}}}}var cf=()=>React.createElement("svg",{width:"40",height:"40",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true"},React.createElement("path",{d:"M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364l2.0201-1.1685a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.4043-.6813zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z",fill:"currentColor"})),lf=()=>React.createElement("svg",{width:"40",height:"40",viewBox:"0 0 32 32",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true"},React.createElement("path",{d:"M6.2 21.024L12.416 17.536L12.52 17.232L12.416 17.064H12.112L11.072 17L7.52 16.904L4.44 16.776L1.456 16.616L0.704 16.456L0 15.528L0.072 15.064L0.704 14.64L1.608 14.72L3.608 14.856L6.608 15.064L8.784 15.192L12.008 15.528H12.52L12.592 15.32L12.416 15.192L12.28 15.064L9.176 12.96L5.816 10.736L4.056 9.456L3.104 8.808L2.624 8.2L2.416 6.872L3.28 5.92L4.44 6L4.736 6.08L5.912 6.984L8.424 8.928L11.704 11.344L12.184 11.744L12.376 11.608L12.4 11.512L12.184 11.152L10.4 7.928L8.496 4.648L7.648 3.288L7.424 2.472C7.344 2.136 7.288 1.856 7.288 1.512L8.272 0.176L8.816 0L10.128 0.176L10.68 0.656L11.496 2.52L12.816 5.456L14.864 9.448L15.464 10.632L15.784 11.728L15.904 12.064H16.112V11.872L16.28 9.624L16.592 6.864L16.896 3.312L17 2.312L17.496 1.112L18.48 0.464L19.248 0.832L19.88 1.736L19.792 2.32L19.416 4.76L18.68 8.584L18.2 11.144H18.48L18.8 10.824L20.096 9.104L22.272 6.384L23.232 5.304L24.352 4.112L25.072 3.544H26.432L27.432 5.032L26.984 6.568L25.584 8.344L24.424 9.848L22.76 12.088L21.72 13.88L21.816 14.024L22.064 14L25.824 13.2L27.856 12.832L30.28 12.416L31.376 12.928L31.496 13.448L31.064 14.512L28.472 15.152L25.432 15.76L20.904 16.832L20.848 16.872L20.912 16.952L22.952 17.144L23.824 17.192H25.96L29.936 17.488L30.976 18.176L31.6 19.016L31.496 19.656L29.896 20.472L27.736 19.96L22.696 18.76L20.968 18.328H20.728V18.472L22.168 19.88L24.808 22.264L28.112 25.336L28.28 26.096L27.856 26.696L27.408 26.632L24.504 24.448L23.384 23.464L20.848 21.328H20.68V21.552L21.264 22.408L24.352 27.048L24.512 28.472L24.288 28.936L23.488 29.216L22.608 29.056L20.8 26.52L18.936 23.664L17.432 21.104L17.248 21.208L16.36 30.768L15.944 31.256L14.984 31.624L14.184 31.016L13.76 30.032L14.184 28.088L14.696 25.552L15.112 23.536L15.488 21.032L15.712 20.2L15.696 20.144L15.512 20.168L13.624 22.76L10.752 26.64L8.48 29.072L7.936 29.288L6.992 28.8L7.08 27.928L7.608 27.152L10.752 23.152L12.648 20.672L13.872 19.24L13.864 19.032H13.792L5.44 24.456L3.952 24.648L3.312 24.048L3.392 23.064L3.696 22.744L6.208 21.016L6.2 21.024Z",fill:"#D97757"})),df=()=>React.createElement("svg",{width:"40",height:"40",viewBox:"0 0 32 32",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true"},React.createElement("path",{d:"M0 4C0 1.79086 1.79086 0 4 0H28C30.2091 0 32 1.79086 32 4V28C32 30.2091 30.2091 32 28 32H4C1.79086 32 0 30.2091 0 28V4Z",fill:"#F0F0F0"}),React.createElement("path",{d:"M14.5 8V12H17.5V8H19V12H20.5C20.7652 12 21.0196 12.1054 21.2071 12.2929C21.3946 12.4804 21.5 12.7348 21.5 13V17L18.5 21V23C18.5 23.2652 18.3946 23.5196 18.2071 23.7071C18.0196 23.8946 17.7652 24 17.5 24H14.5C14.2348 24 13.9804 23.8946 13.7929 23.7071C13.6054 23.5196 13.5 23.2652 13.5 23V21L10.5 17V13C10.5 12.7348 10.6054 12.4804 10.7929 12.2929C10.9804 12.1054 11.2348 12 11.5 12H13V8H14.5ZM15 20.5V22.5H17V20.5L20 16.5V13.5H12V16.5L15 20.5Z",fill:"#949494"})),uf=()=>React.createElement("svg",{width:"40",height:"40",viewBox:"0 0 44 44",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true"},React.createElement("rect",{width:"44",height:"44",fill:"#357B49",rx:"6"}),React.createElement("path",{fill:"#fff",fillRule:"evenodd",d:"m29.746 28.31-6.392-16.797c-.152-.397-.305-.672-.789-.675-.673 0-1.408.611-1.746 1.316l-7.378 16.154c-.072.16-.143.311-.214.454-.5.995-1.045 1.546-2.357 1.626a.399.399 0 0 0-.16.033l-.01.004a.399.399 0 0 0-.23.392v.01c0 .054.01.106.03.155l.004.01a.416.416 0 0 0 .394.252h6.212a.417.417 0 0 0 .307-.12.416.416 0 0 0 .124-.305.398.398 0 0 0-.105-.302.399.399 0 0 0-.294-.127c-.757 0-2.197-.062-2.197-1.164.02-.318.103-.63.245-.916l1.399-3.152c.52-1.163 1.654-1.163 2.572-1.163h5.843c.023 0 .044 0 .062.003.13.014.16.081.214.242l1.534 4.07a2.857 2.857 0 0 1 .216 1.04c0 .054-.003.104-.01.153-.09.726-.831.887-1.49.887a.4.4 0 0 0-.294.127l-.007.008-.007.008a.401.401 0 0 0-.092.286v.01c0 .054.01.106.03.155l.005.01a.42.42 0 0 0 .395.252h7.011a.413.413 0 0 0 .279-.13.412.412 0 0 0 .11-.297.387.387 0 0 0-.09-.294.388.388 0 0 0-.277-.135c-1.448-.122-2.295-.643-2.847-2.08Zm-11.985-5.844 2.847-6.304c.361-.728.659-1.486.889-2.265 0-.06.03-.092.06-.092s.061.032.061.091c.02.122.045.247.073.374.197.888.584 1.878.914 2.723l.176.453 1.684 4.529a.927.927 0 0 1 .092.4.473.473 0 0 1-.009.094c-.041.202-.228.272-.602.272h-6.063c-.122 0-.184-.03-.184-.092a.36.36 0 0 1 .062-.183Zm17.107-.721c0 .786-.446 1.231-1.25 1.231-.806 0-1.125-.409-1.125-1.034 0-.786.465-1.231 1.25-1.231.785 0 1.125.427 1.125 1.034ZM9.629 23.002c.803 0 1.25-.447 1.25-1.231 0-.607-.343-1.036-1.128-1.036-.785 0-1.25.447-1.25 1.231 0 .625.325 1.036 1.128 1.036Z",clipRule:"evenodd"})),ff=()=>React.createElement("svg",{width:"40",height:"40",style:{flex:"none",lineHeight:1},viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true"},React.createElement("path",{d:"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z",fill:"#3186FF"}),React.createElement("path",{d:"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z",fill:"url(#lobe-icons-gemini-fill-0)"}),React.createElement("path",{d:"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z",fill:"url(#lobe-icons-gemini-fill-1)"}),React.createElement("path",{d:"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z",fill:"url(#lobe-icons-gemini-fill-2)"}),React.createElement("defs",null,React.createElement("linearGradient",{gradientUnits:"userSpaceOnUse",id:"lobe-icons-gemini-fill-0",x1:"7",x2:"11",y1:"15.5",y2:"12"},React.createElement("stop",{stopColor:"#08B962"}),React.createElement("stop",{offset:"1",stopColor:"#08B962",stopOpacity:"0"})),React.createElement("linearGradient",{gradientUnits:"userSpaceOnUse",id:"lobe-icons-gemini-fill-1",x1:"8",x2:"11.5",y1:"5.5",y2:"11"},React.createElement("stop",{stopColor:"#F94543"}),React.createElement("stop",{offset:"1",stopColor:"#F94543",stopOpacity:"0"})),React.createElement("linearGradient",{gradientUnits:"userSpaceOnUse",id:"lobe-icons-gemini-fill-2",x1:"3.5",x2:"17.5",y1:"13.5",y2:"12"},React.createElement("stop",{stopColor:"#FABC12"}),React.createElement("stop",{offset:".46",stopColor:"#FABC12",stopOpacity:"0"}))));var{store:h0}=Oo(b0);function gf(){try{return JSON.parse(document.getElementById("wp-script-module-data-options-connectors-wp-admin")?.textContent??"{}")}catch{return{}}}function qs(){return gf().connectors??{}}function bf(){return!!gf().isFileModDisabled}var w0={google:ff,openai:cf,anthropic:lf,akismet:uf};function v0(e,t){if(t)return React.createElement("img",{src:t,alt:"",width:40,height:40});let o=w0[e];return React.createElement(o||df,null)}var _0=()=>React.createElement("span",{style:{color:"#345b37",backgroundColor:"#eff8f0",padding:"4px 12px",borderRadius:"2px",fontSize:"13px",fontWeight:"var(--wpds-typography-font-weight-emphasis)",whiteSpace:"nowrap"}},(0,oo.__)("Connected")),y0=({slug:e})=>React.createElement($o,{href:(0,oo.sprintf)((0,oo.__)("https://wordpress.org/plugins/%s/"),e),openInNewTab:!0},(0,oo.__)("Learn more")),x0=()=>React.createElement(zi,null,(0,oo.__)("Not available"));function hf({isConnected:e,showUnavailableBadge:t,pluginSlug:o,isExpanded:n,isBusy:r,pluginStatus:i,actionButtonRef:s,handleButtonClick:a,getButtonLabel:l}){return React.createElement(wr.__experimentalHStack,{spacing:3,expanded:!1},e&&React.createElement(_0,null),t&&(o?React.createElement(y0,{slug:o}):React.createElement(x0,null)),!t&&React.createElement(wr.Button,{ref:s,variant:n||e?"tertiary":"secondary",size:"compact",onClick:a,disabled:i==="checking"||r,isBusy:r,accessibleWhenDisabled:!0},l()))}function wf(e){let t=e?.replace(/\.php$/,"");return t?.includes("/")?t.split("/")[0]:t}function R0({name:e,description:t,logo:o,authentication:n,plugin:r}){let i=n?.method==="api_key"?n:void 0,s=i?.settingName??"",a=i?.credentialsUrl??void 0,l=wf(r?.file),{pluginStatus:c,canInstallPlugins:d,canActivatePlugins:f,isExpanded:p,setIsExpanded:m,isBusy:u,isConnected:g,currentApiKey:v,hasResolvedSettings:_,keySource:w,handleButtonClick:y,getButtonLabel:h,saveApiKey:T,removeApiKey:x}=Xs({file:r?.file,settingName:s,connectorName:e,isInstalled:r?.isInstalled,isActivated:r?.isActivated,keySource:i?.keySource,initialIsConnected:i?.isConnected}),R=w==="env"||w==="constant",E=c==="not-installed"&&d===!1||c==="inactive"&&f===!1,k=(0,Ks.useRef)(null);return React.createElement(pf,{className:l?`connector-item--${l}`:void 0,logo:o,name:e,description:t,actionArea:React.createElement(hf,{isConnected:g,showUnavailableBadge:E,pluginSlug:l,isExpanded:p,isBusy:u,pluginStatus:c,actionButtonRef:k,handleButtonClick:y,getButtonLabel:h})},p&&c==="active"&&_&&React.createElement(m0,{key:g?"connected":"setup",initialValue:R?"\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022":v,helpUrl:a,readOnly:g||R,keySource:w,onRemove:R?void 0:async()=>{await x(),k.current?.focus()},onSave:async C=>{await T(C),m(!1),k.current?.focus()}}))}function S0({name:e,description:t,logo:o,authentication:n,plugin:r}){let i=n?.method==="application_password"?n:void 0,s=i?.settingName??"",a=i?.credentialsUrl??void 0,l=wf(r?.file),{pluginStatus:c,canInstallPlugins:d,canActivatePlugins:f,isExpanded:p,setIsExpanded:m,isBusy:u,isConnected:g,currentUsername:v,hasResolvedSettings:_,keySource:w,handleButtonClick:y,getButtonLabel:h,saveCredentials:T,removeCredentials:x}=Xs({file:r?.file,settingName:s,connectorName:e,isInstalled:r?.isInstalled,isActivated:r?.isActivated,keySource:i?.keySource,initialIsConnected:i?.isConnected}),R=w==="env"||w==="constant",E=(0,Ks.useRef)(null),k=c==="not-installed"&&d===!1||c==="inactive"&&f===!1;return React.createElement(pf,{className:l?`connector-item--${l}`:void 0,logo:o,name:e,description:t,actionArea:React.createElement(hf,{isConnected:g,showUnavailableBadge:k,pluginSlug:l,isExpanded:p,isBusy:u,pluginStatus:c,actionButtonRef:E,handleButtonClick:y,getButtonLabel:h})},p&&c==="active"&&_&&React.createElement(g0,{key:g?"connected":"setup",initialUsername:R?"\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022":v,helpUrl:a,readOnly:g||R,keySource:w,onRemove:R?void 0:async()=>{await x(),E.current?.focus()},onSave:async C=>{await T(C),m(!1),E.current?.focus()}}))}function vf(){let e=qs(),t=o=>o.replace(/[^a-z0-9-_]/gi,"-");for(let[o,n]of Object.entries(e)){if(o==="akismet"&&!n.plugin?.isInstalled)continue;let{authentication:r}=n,i=t(o),s={name:n.name,description:n.description,type:n.type,logo:v0(o,n.logoUrl),authentication:r,plugin:n.plugin},a=Oo((0,mf.select)(h0)).getConnector(i);r.method==="api_key"&&!a?.render?s.render=R0:r.method==="application_password"&&!a?.render&&(s.render=S0),p0(i,s)}}function _f(){return React.createElement("div",{className:"ai-plugin-callout__decoration","aria-hidden":"true"},React.createElement("svg",{viewBox:"0 0 248 248",xmlns:"http://www.w3.org/2000/svg",xmlnsXlink:"http://www.w3.org/1999/xlink",focusable:"false",style:{width:"100%",height:"100%"}},React.createElement("image",{href:"data:image/png;base64,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",width:"248",height:"248",style:{mixBlendMode:"multiply"}})))}var E0="ai",T0="ai-wp-admin",Zs="ai/ai",k0="https://wordpress.org/plugins/ai/",Js=Object.values(qs()),P0=Js.some(e=>e.type==="ai_provider"),Rf=[];for(let e of Js)e.type==="ai_provider"&&e.authentication.method==="api_key"&&Rf.push(e.authentication.settingName);function Sf(){let[e,t]=(0,vt.useState)(!1),[o,n]=(0,vt.useState)(!1),r=(0,vt.useRef)(null);(0,vt.useEffect)(()=>{o&&r.current?.focus()},[o]);let i=(0,vt.useRef)(Js.some(T=>T.type==="ai_provider"&&T.authentication.method==="api_key"&&T.authentication.isConnected)).current,{pluginStatus:s,canInstallPlugins:a,canManagePlugins:l,hasConnectedProvider:c}=(0,cn.useSelect)(T=>{let x=T(Qs.store),R=!!x.canUser("create",{kind:"root",name:"plugin"}),E=x.getEntityRecord("root","site"),k=i||Rf.some(O=>!!E?.[O]),C=x.getEntityRecord("root","plugin",Zs);return x.hasFinishedResolution("getEntityRecord",["root","plugin",Zs])?C?{pluginStatus:C.status==="active"?"active":"inactive",canInstallPlugins:R,canManagePlugins:!0,hasConnectedProvider:k}:{pluginStatus:"not-installed",canInstallPlugins:R,canManagePlugins:R,hasConnectedProvider:k}:{pluginStatus:"checking",canInstallPlugins:R,canManagePlugins:void 0,hasConnectedProvider:k}},[]),{saveEntityRecord:d}=(0,cn.useDispatch)(Qs.store),{createSuccessNotice:f,createErrorNotice:p}=(0,cn.useDispatch)(yf.store),m=async()=>{t(!0);try{await d("root","plugin",{slug:E0,status:"active"},{throwOnError:!0}),n(!0),f((0,Ge.__)("AI plugin installed and activated successfully."),{id:"ai-plugin-install-success",type:"snackbar"})}catch{p((0,Ge.__)("Failed to install the AI plugin."),{id:"ai-plugin-install-error",type:"snackbar"})}finally{t(!1)}},u=async()=>{t(!0);try{await d("root","plugin",{plugin:Zs,status:"active"},{throwOnError:!0}),n(!0),f((0,Ge.__)("AI plugin activated successfully."),{id:"ai-plugin-activate-success",type:"snackbar"})}catch{p((0,Ge.__)("Failed to activate the AI plugin."),{id:"ai-plugin-activate-error",type:"snackbar"})}finally{t(!1)}};if(!P0||s==="checking"||s==="active"&&i&&!o||s==="inactive"&&l===!1)return null;let g=s==="active"&&!c,v=s==="active"&&c&&(!i||o),_=s==="not-installed"||s==="inactive",w=s==="not-installed"&&a===!1,y=()=>v?(0,Ge.__)("The AI plugin is ready to use. You can use it to generate featured images, alt text, titles, excerpts and more. Learn more"):g?(0,Ge.__)("The AI plugin is installed. Connect an AI provider below to generate featured images, alt text, titles, excerpts, and more. Learn more"):(0,Ge.__)("The AI plugin can use your AI connectors to generate featured images, alt text, titles, excerpts and more. Learn more"),h=()=>s==="not-installed"?{label:e?(0,Ge.__)("Installing\u2026"):(0,Ge.__)("Install the AI plugin"),disabled:e,onClick:e?void 0:m}:{label:e?(0,Ge.__)("Activating\u2026"):(0,Ge.__)("Activate the AI plugin"),disabled:e,onClick:e?void 0:u};return React.createElement("div",{className:"ai-plugin-callout"},React.createElement("div",{className:"ai-plugin-callout__content"},React.createElement("p",null,(0,vt.createInterpolateElement)(y(),{strong:React.createElement("strong",null),a:React.createElement(an.ExternalLink,{href:k0})})),!w&&(_?React.createElement(an.Button,{variant:"primary",size:"compact",isBusy:e,disabled:h().disabled,accessibleWhenDisabled:!0,onClick:h().onClick},h().label):React.createElement(an.Button,{ref:r,variant:"secondary",size:"compact",href:(0,xf.addQueryArgs)("options-general.php",{page:T0})},(0,Ge.__)("Control features in the AI plugin")))),React.createElement(_f,null))}var{store:A0}=Oo(C0);vf();function O0(){let e=bf(),{connectors:t,canInstallPlugins:o,isAiPluginInstalled:n}=(0,Ef.useSelect)(c=>{let d=c(kf.store),f=d.getEntityRecord("root","plugin","ai/ai");return{connectors:Oo(c(A0)).getConnectors(),canInstallPlugins:d.canUser("create",{kind:"root",name:"plugin"}),isAiPluginInstalled:!!f}},[]),r=t.filter(c=>c.render),i=Array.from(new Set(t.filter(c=>c.type==="ai_provider").map(c=>c.plugin?.file?.split("/")[0]).filter(c=>!!c))).sort(),s=new Set(t.filter(c=>c.plugin?.isInstalled).map(c=>c.plugin?.file?.split("/")[0]).filter(c=>!!c));n&&s.add("ai");let a=["ai",...i].filter(c=>!s.has(c)),l=r.length===0;return React.createElement(Ys,{title:(0,kt.__)("Connectors"),subTitle:(0,kt.__)("All of your API keys and credentials are stored here and shared across plugins. Configure once and use everywhere.")},React.createElement("div",{className:`connectors-page${l?" connectors-page--empty":""}`},a.length>0&&(e||!o)&&React.createElement(en.Root,{intent:"info",className:"connectors-page__file-mods-notice"},React.createElement(en.Description,null,e?(0,kt.__)("Plugins cannot be installed here due to your site configuration. Install them manually using your normal deployment workflow."):(0,kt.__)("You do not have permission to install plugins. Please ask a site administrator to install them for you."))),l?React.createElement(at.__experimentalVStack,{alignment:"center",spacing:3,style:{maxWidth:480}},React.createElement(at.__experimentalVStack,{alignment:"center",spacing:2},React.createElement(at.__experimentalHeading,{level:2,size:15},(0,kt.__)("No connectors yet")),React.createElement(at.__experimentalText,{size:12},(0,kt.__)("Connectors appear here when you install plugins that use external services. Each plugin registers the API keys it needs, and you manage them all in one place."))),React.createElement(at.Button,{variant:"secondary",href:"plugin-install.php",__next40pxDefaultSize:!0},(0,kt.__)("Learn more"))):React.createElement(at.__experimentalVStack,{spacing:3},React.createElement(Sf,null),React.createElement(at.__experimentalVStack,{spacing:3,role:"list"},t.map(c=>c.render?React.createElement(c.render,{key:c.slug,slug:c.slug,name:c.name,description:c.description,type:c.type,logo:c.logo,authentication:c.authentication,plugin:c.plugin}):null))),o&&!e&&React.createElement("p",null,(0,Tf.createInterpolateElement)((0,kt.__)("If the connector you need is not listed, search the plugin directory to see if a connector is available."),{a:React.createElement("a",{href:"plugin-install.php?s=connector&tab=search&type=tag"})}))))}function N0(){return React.createElement(O0,null)}var L0=N0;export{L0 as stage}; +var Zf=Object.create;var Ir=Object.defineProperty;var Qf=Object.getOwnPropertyDescriptor;var Jf=Object.getOwnPropertyNames;var $f=Object.getPrototypeOf,ep=Object.prototype.hasOwnProperty;var Te=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),Mt=(e,t)=>{for(var o in t)Ir(e,o,{get:t[o],enumerable:!0})},tp=(e,t,o,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of Jf(t))!ep.call(e,r)&&r!==o&&Ir(e,r,{get:()=>t[r],enumerable:!(n=Qf(t,r))||n.enumerable});return e};var b=(e,t,o)=>(o=e!=null?Zf($f(e)):{},tp(t||!e||!e.__esModule?Ir(o,"default",{value:e,enumerable:!0}):o,e));var st=Te(($h,da)=>{da.exports=window.wp.i18n});var ce=Te((t0,fa)=>{fa.exports=window.wp.element});var z=Te((o0,pa)=>{pa.exports=window.React});var W=Te((l0,ha)=>{ha.exports=window.ReactJSXRuntime});var Ht=Te((bw,Ua)=>{Ua.exports=window.ReactDOM});var Gc=Te(Uc=>{"use strict";var xo=z();function ng(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var rg=typeof Object.is=="function"?Object.is:ng,ig=xo.useState,sg=xo.useEffect,ag=xo.useLayoutEffect,cg=xo.useDebugValue;function lg(e,t){var o=t(),n=ig({inst:{value:o,getSnapshot:t}}),r=n[0].inst,i=n[1];return ag(function(){r.value=o,r.getSnapshot=t,bi(r)&&i({inst:r})},[e,o,t]),sg(function(){return bi(r)&&i({inst:r}),e(function(){bi(r)&&i({inst:r})})},[e]),cg(o),o}function bi(e){var t=e.getSnapshot;e=e.value;try{var o=t();return!rg(e,o)}catch{return!0}}function dg(e,t){return t()}var ug=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?dg:lg;Uc.useSyncExternalStore=xo.useSyncExternalStore!==void 0?xo.useSyncExternalStore:ug});var Un=Te((av,Kc)=>{"use strict";Kc.exports=Gc()});var qc=Te(Xc=>{"use strict";var Gn=z(),fg=Un();function pg(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var mg=typeof Object.is=="function"?Object.is:pg,gg=fg.useSyncExternalStore,bg=Gn.useRef,hg=Gn.useEffect,wg=Gn.useMemo,vg=Gn.useDebugValue;Xc.useSyncExternalStoreWithSelector=function(e,t,o,n,r){var i=bg(null);if(i.current===null){var s={hasValue:!1,value:null};i.current=s}else s=i.current;i=wg(function(){function l(f){if(!c){if(c=!0,d=f,f=n(f),r!==void 0&&s.hasValue){var p=s.value;if(r(p,f))return m=p}return m=f}if(p=m,mg(d,f))return p;var g=n(f);return r!==void 0&&r(p,g)?(d=f,p):(d=f,m=g)}var c=!1,d,m,u=o===void 0?null:o;return[function(){return l(t())},u===null?void 0:function(){return l(u())}]},[t,o,n,r]);var a=gg(e,i[0],i[1]);return hg(function(){s.hasValue=!0,s.value=a},[a]),vg(a),a}});var Qc=Te((lv,Zc)=>{"use strict";Zc.exports=qc()});var so=Te((C4,Bd)=>{Bd.exports=window.wp.primitives});var nu=Te((r3,ou)=>{ou.exports=window.wp.theme});var fs=Te((i3,ru)=>{ru.exports=window.wp.privateApis});var rn=Te((U5,lf)=>{lf.exports=window.wp.components});var an=Te((i8,hf)=>{hf.exports=window.wp.data});var Tr=Te((s8,wf)=>{wf.exports=window.wp.coreData});var ea=Te((l8,_f)=>{_f.exports=window.wp.notices});var xf=Te((d8,yf)=>{yf.exports=window.wp.url});function ua(e){var t,o,n="";if(typeof e=="string"||typeof e=="number")n+=e;else if(typeof e=="object")if(Array.isArray(e)){var r=e.length;for(t=0;te();function Y(e){let t=ke(ip).current;return t.next=e,rp(t.effect),t.trampoline}function ip(){let e={next:void 0,callback:sp,trampoline:(...t)=>e.callback?.(...t),effect:()=>{e.callback=e.next}};return e}function sp(){}var ba=b(z(),1),ap=()=>{},F=typeof document<"u"?ba.useLayoutEffect:ap;function cp(e,t){return function(n,...r){let i=new URL(e);return i.searchParams.set("code",n.toString()),r.forEach(s=>i.searchParams.append("args[]",s)),`${t} error #${n}; visit ${i} for the full message.`}}var lp=cp("https://base-ui.com/production-error","Base UI"),De=lp;var qt=b(z(),1);function Mr(e,t,o,n){let r=ke(va).current;return dp(r,e,t,o,n)&&_a(r,[e,t,o,n]),r.callback}function wa(e){let t=ke(va).current;return up(t,e)&&_a(t,e),t.callback}function va(){return{callback:null,cleanup:null,refs:[]}}function dp(e,t,o,n,r){return e.refs[0]!==t||e.refs[1]!==o||e.refs[2]!==n||e.refs[3]!==r}function up(e,t){return e.refs.length!==t.length||e.refs.some((o,n)=>o!==t[n])}function _a(e,t){if(e.refs=t,t.every(o=>o==null)){e.callback=null;return}e.callback=o=>{if(e.cleanup&&(e.cleanup(),e.cleanup=null),o!=null){let n=Array(t.length).fill(null);for(let r=0;r{for(let r=0;r=e}function Br(e){if(!xa.isValidElement(e))return null;let t=e,o=t.props;return(po(19)?o?.ref:t.ref)??null}function zo(e,t){if(e&&!t)return e;if(!e&&t)return t;if(e||t)return{...e,...t}}function Ge(){}var Sa=Object.freeze([]),me=Object.freeze({});function Ra(e,t){let o={};for(let n in e){let r=e[n];if(t?.hasOwnProperty(n)){let i=t[n](r);i!=null&&Object.assign(o,i);continue}r===!0?o[`data-${n.toLowerCase()}`]="":r&&(o[`data-${n.toLowerCase()}`]=r.toString())}return o}function Ea(e,t){return typeof e=="function"?e(t):e}function Ta(e,t){return typeof e=="function"?e(t):e}var Hr={};function ve(e,t,o,n,r){if(!o&&!n&&!r&&!e)return _n(t);let i=_n(e);return t&&(i=Do(i,t)),o&&(i=Do(i,o)),n&&(i=Do(i,n)),r&&(i=Do(i,r)),i}function ka(e){if(e.length===0)return Hr;if(e.length===1)return _n(e[0]);let t=_n(e[0]);for(let o=1;o=65&&r<=90&&(typeof t=="function"||typeof t>"u")}function zr(e){return typeof e=="function"}function Ca(e,t){return zr(e)?e(t):e??Hr}function gp(e,t){return t?e?(...o)=>{let n=o[0];if(Oa(n)){let i=n;jo(i);let s=t(...o);return i.baseUIHandlerPrevented||e?.(...o),s}let r=t(...o);return e?.(...o),r}:Aa(t):e}function Aa(e){return e&&((...t)=>{let o=t[0];return Oa(o)&&jo(o),e(...t)})}function jo(e){return e.preventBaseUIHandler=()=>{e.baseUIHandlerPrevented=!0},e}function Dr(e,t){return t?e?t+" "+e:t:e}function Oa(e){return e!=null&&typeof e=="object"&&"nativeEvent"in e}var jr=b(z(),1);function Oe(e,t,o={}){let n=t.render,r=bp(t,o);if(o.enabled===!1)return null;let i=o.state??me;return vp(e,n,r,i)}function bp(e,t={}){let{className:o,style:n,render:r}=e,{state:i=me,ref:s,props:a,stateAttributesMapping:l,enabled:c=!0}=t,d=c?Ea(o,i):void 0,m=c?Ta(n,i):void 0,u=c?Ra(i,l):me,f=c&&a?hp(a):void 0,p=c?zo(u,f)??{}:me;return typeof document<"u"&&(c?Array.isArray(s)?p.ref=wa([p.ref,Br(r),...s]):p.ref=Mr(p.ref,Br(r),s):Mr(null,null)),c?(d!==void 0&&(p.className=Dr(p.className,d)),m!==void 0&&(p.style=zo(p.style,m)),p):me}function hp(e){return Array.isArray(e)?ka(e):ve(void 0,e)}var wp=Symbol.for("react.lazy");function vp(e,t,o,n){if(t){if(typeof t=="function")return t(o,n);let r=ve(o,t.props);r.ref=o.ref;let i=t;return i?.$$typeof===wp&&(i=qt.Children.toArray(t)[0]),qt.cloneElement(i,r)}if(e&&typeof e=="string")return _p(e,o);throw new Error(De(8))}function _p(e,t){return e==="button"?(0,jr.createElement)("button",{type:"button",...t,key:t.key}):e==="img"?(0,jr.createElement)("img",{alt:"",...t,key:t.key}):qt.createElement(e,t)}var yn=b(z(),1);var Na=0;function yp(e,t="mui"){let[o,n]=yn.useState(e),r=e||o;return yn.useEffect(()=>{o==null&&(Na+=1,n(`${t}-${Na}`))},[o,t]),r}var Ia=Ho.useId;function mo(e,t){if(Ia!==void 0){let o=Ia();return e??(t?`${t}-${o}`:o)}return yp(e,t)}function La(e){return mo(e,"base-ui")}var G={};Mt(G,{cancelOpen:()=>qp,chipRemovePress:()=>Op,clearPress:()=>Ap,closePress:()=>Pp,closeWatcher:()=>Vp,decrementPress:()=>Lp,disabled:()=>Qp,drag:()=>Gp,escapeKey:()=>Fp,focusOut:()=>jp,imperativeAction:()=>em,incrementPress:()=>Ip,initial:()=>$p,inputBlur:()=>Hp,inputChange:()=>Mp,inputClear:()=>Bp,inputPaste:()=>zp,inputPress:()=>Dp,itemPress:()=>kp,keyboard:()=>Yp,linkPress:()=>Cp,listNavigation:()=>Wp,missing:()=>Jp,none:()=>xp,outsidePress:()=>Tp,pointer:()=>Up,scrub:()=>Xp,siblingOpen:()=>Zp,swipe:()=>tm,trackPress:()=>Np,triggerFocus:()=>Ep,triggerHover:()=>Rp,triggerPress:()=>Sp,wheel:()=>Kp,windowResize:()=>om});var xp="none",Sp="trigger-press",Rp="trigger-hover",Ep="trigger-focus",Tp="outside-press",kp="item-press",Pp="close-press",Cp="link-press",Ap="clear-press",Op="chip-remove-press",Np="track-press",Ip="increment-press",Lp="decrement-press",Mp="input-change",Bp="input-clear",Hp="input-blur",zp="input-paste",Dp="input-press",jp="focus-out",Fp="escape-key",Vp="close-watcher",Wp="list-navigation",Yp="keyboard",Up="pointer",Gp="drag",Kp="wheel",Xp="scrub",qp="cancel-open",Zp="sibling-open",Qp="disabled",Jp="missing",$p="initial",em="imperative-action",tm="swipe",om="window-resize";function ee(e,t,o,n){let r=!1,i=!1,s=n??me;return{reason:e,event:t??new Event("base-ui"),cancel(){r=!0},allowPropagation(){i=!0},get isCanceled(){return r},get isPropagationAllowed(){return i},trigger:o,...s}}var Vr=b(z(),1);var Ma=b(z(),1);function go(e){Ma.useEffect(e,Sa)}var xn=null,Y0=globalThis.requestAnimationFrame,Fr=class{callbacks=[];callbacksCount=0;nextId=1;startId=1;isScheduled=!1;tick=t=>{this.isScheduled=!1;let o=this.callbacks,n=this.callbacksCount;if(this.callbacks=[],this.callbacksCount=0,this.startId=this.nextId,n>0)for(let r=0;r=this.callbacks.length||(this.callbacks[o]=null,this.callbacksCount-=1)}},Sn=new Fr;var gt=class e{static create(){return new e}static request(t){return Sn.request(t)}static cancel(t){return Sn.cancel(t)}currentId=xn;request(t){this.cancel(),this.currentId=Sn.request(()=>{this.currentId=xn,t()})}cancel=()=>{this.currentId!==xn&&(Sn.cancel(this.currentId),this.currentId=xn)};disposeEffect=()=>this.cancel};function bo(){let e=ke(gt.create).current;return go(e.disposeEffect),e}function Ba(e,t=!1,o=!1){let[n,r]=Vr.useState(e&&t?"idle":void 0),[i,s]=Vr.useState(e);return e&&!i&&(s(!0),r("starting")),!e&&i&&n!=="ending"&&!o&&r("ending"),!e&&!i&&n==="ending"&&r(void 0),F(()=>{if(!e&&i&&n!=="ending"&&o){let a=gt.request(()=>{r("ending")});return()=>{gt.cancel(a)}}},[e,i,n,o]),F(()=>{if(!e||t)return;let a=gt.request(()=>{r(void 0)});return()=>{gt.cancel(a)}},[t,e]),F(()=>{if(!e||!t)return;e&&i&&n!=="idle"&&r("starting");let a=gt.request(()=>{r("idle")});return()=>{gt.cancel(a)}},[t,e,i,n]),{mounted:i,setMounted:s,transitionStatus:n}}var Wr=(function(e){return e.startingStyle="data-starting-style",e.endingStyle="data-ending-style",e})({}),nm={"data-starting-style":""},rm={"data-ending-style":""},Ha={transitionStatus(e){return e==="starting"?nm:e==="ending"?rm:null}};var wo=b(z(),1);function Rn(){return typeof window<"u"}function Qt(e){return En(e)?(e.nodeName||"").toLowerCase():"#document"}function fe(e){var t;return(e==null||(t=e.ownerDocument)==null?void 0:t.defaultView)||window}function ht(e){var t;return(t=(En(e)?e.ownerDocument:e.document)||window.document)==null?void 0:t.documentElement}function En(e){return Rn()?e instanceof Node||e instanceof fe(e).Node:!1}function U(e){return Rn()?e instanceof Element||e instanceof fe(e).Element:!1}function he(e){return Rn()?e instanceof HTMLElement||e instanceof fe(e).HTMLElement:!1}function ho(e){return!Rn()||typeof ShadowRoot>"u"?!1:e instanceof ShadowRoot||e instanceof fe(e).ShadowRoot}function Fo(e){let{overflow:t,overflowX:o,overflowY:n,display:r}=Le(e);return/auto|scroll|overlay|hidden|clip/.test(t+n+o)&&r!=="inline"&&r!=="contents"}function za(e){return/^(table|td|th)$/.test(Qt(e))}function Vo(e){try{if(e.matches(":popover-open"))return!0}catch{}try{return e.matches(":modal")}catch{return!1}}var im=/transform|translate|scale|rotate|perspective|filter/,sm=/paint|layout|strict|content/,Zt=e=>!!e&&e!=="none",Yr;function Tn(e){let t=U(e)?Le(e):e;return Zt(t.transform)||Zt(t.translate)||Zt(t.scale)||Zt(t.rotate)||Zt(t.perspective)||!kn()&&(Zt(t.backdropFilter)||Zt(t.filter))||im.test(t.willChange||"")||sm.test(t.contain||"")}function Da(e){let t=bt(e);for(;he(t)&&!wt(t);){if(Tn(t))return t;if(Vo(t))return null;t=bt(t)}return null}function kn(){return Yr==null&&(Yr=typeof CSS<"u"&&CSS.supports&&CSS.supports("-webkit-backdrop-filter","none")),Yr}function wt(e){return/^(html|body|#document)$/.test(Qt(e))}function Le(e){return fe(e).getComputedStyle(e)}function Wo(e){return U(e)?{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}:{scrollLeft:e.scrollX,scrollTop:e.scrollY}}function bt(e){if(Qt(e)==="html")return e;let t=e.assignedSlot||e.parentNode||ho(e)&&e.host||ht(e);return ho(t)?t.host:t}function ja(e){let t=bt(e);return wt(t)?(e.ownerDocument||e).body:he(t)&&Fo(t)?t:ja(t)}function Bt(e,t,o){var n;t===void 0&&(t=[]),o===void 0&&(o=!0);let r=ja(e),i=r===((n=e.ownerDocument)==null?void 0:n.body),s=fe(r);if(i){let a=Pn(s);return t.concat(s,s.visualViewport||[],Fo(r)?r:[],a&&o?Bt(a):[])}else return t.concat(r,Bt(r,[],o))}function Pn(e){return e.parent&&Object.getPrototypeOf(e.parent)?e.frameElement:null}var Cn=b(z(),1),am=Cn.createContext(void 0);function Fa(e=!1){let t=Cn.useContext(am);if(t===void 0&&!e)throw new Error(De(16));return t}var Va=b(z(),1);function Wa(e){let{focusableWhenDisabled:t,disabled:o,composite:n=!1,tabIndex:r=0,isNativeButton:i}=e,s=n&&t!==!1,a=n&&t===!1;return{props:Va.useMemo(()=>{let c={onKeyDown(d){o&&t&&d.key!=="Tab"&&d.preventDefault()}};return n||(c.tabIndex=r,!i&&o&&(c.tabIndex=t?r:-1)),(i&&(t||s)||!i&&o)&&(c["aria-disabled"]=o),i&&(!t||a)&&(c.disabled=o),c},[n,o,t,s,a,i,r])}}function Pe(e){return e?.ownerDocument||document}function An(e,t,{detail:o=0}={}){e.dispatchEvent(new(fe(e)).PointerEvent("click",{bubbles:!0,cancelable:!0,composed:!0,detail:o,shiftKey:t.shiftKey,ctrlKey:t.ctrlKey,altKey:t.altKey,metaKey:t.metaKey}))}function Ya(e={}){let{disabled:t=!1,focusableWhenDisabled:o,tabIndex:n=0,native:r=!0,composite:i}=e,s=wo.useRef(null),a=Fa(!0),l=i??a!==void 0,{props:c}=Wa({focusableWhenDisabled:o,disabled:t,composite:l,tabIndex:n,isNativeButton:r}),d=wo.useCallback(()=>{let f=s.current;Ur(f)&&l&&t&&c.disabled===void 0&&f.disabled&&(f.disabled=!1)},[t,c.disabled,l]);F(d,[d]);let m=wo.useCallback((f={})=>{let{onClick:p,onMouseDown:g,onKeyUp:h,onKeyDown:y,onPointerDown:_,...v}=f;return ve({onClick(w){if(t){w.preventDefault();return}p?.(w)},onMouseDown(w){t||g?.(w)},onKeyDown(w){if(t||(jo(w),y?.(w),w.baseUIHandlerPrevented))return;let R=w.target===w.currentTarget,x=w.currentTarget,S=Ur(x),E=!r&&cm(x),T=R&&(r?S:!E),P=w.key==="Enter",N=w.key===" ",H=x.getAttribute("role"),j=H?.startsWith("menuitem")||H==="option"||H==="gridcell";if(R&&l&&N){if(w.defaultPrevented&&j)return;w.preventDefault(),(!r||S)&&(w.preventBaseUIHandler(),An(x,w));return}if(!T||r||!N&&!P){R&&E&&N&&w.preventDefault();return}w.defaultPrevented||(w.preventDefault(),P&&(w.preventBaseUIHandler(),An(x,w)))},onKeyUp(w){if(!t){if(jo(w),h?.(w),w.target===w.currentTarget&&r&&l&&Ur(w.currentTarget)&&w.key===" "){w.preventDefault();return}w.baseUIHandlerPrevented||w.target===w.currentTarget&&!r&&!l&&!w.defaultPrevented&&w.key===" "&&(w.preventBaseUIHandler(),An(w.currentTarget,w))}},onPointerDown(w){if(t){w.preventDefault();return}_?.(w)}},r?{type:"button"}:{role:"button"},c,v)},[t,c,l,r]),u=Y(f=>{s.current=f,d()});return{getButtonProps:m,buttonRef:u}}function Ur(e){return he(e)&&e.tagName==="BUTTON"}function cm(e){return he(e)&&e.tagName==="A"&&!!e.href}function oe(e,t,o,n){return e.addEventListener(t,o,n),()=>{e.removeEventListener(t,o,n)}}function je(e){let t=ke(lm,e).current;return t.next=e,F(t.effect),t}function lm(e){let t={current:e,next:e,effect:()=>{t.current=t.next}};return t}var Xa=b(z(),1);var Ka=b(Ht(),1);function Ga(e){return e==null?e:"current"in e?e.current:e}function vo(e,t=!1){let o=bo();return Y((n,r=null)=>{o.cancel();let i=Ga(e);if(i==null)return;let s=i,a=()=>{Ka.flushSync(n)};if(typeof s.getAnimations!="function"||globalThis.BASE_UI_ANIMATIONS_DISABLED){n();return}function l(){Promise.all(s.getAnimations().map(c=>c.finished)).then(()=>{r?.aborted||a()},()=>{if(r?.aborted)return;if(s.getAnimations().some(d=>d.pending||d.playState!=="finished")){l();return}a()})}if(t){let c="data-starting-style";if(!s.hasAttribute(c)){o.request(l);return}let d=new MutationObserver(()=>{s.hasAttribute(c)||(d.disconnect(),l())});d.observe(s,{attributes:!0,attributeFilter:[c]}),r?.addEventListener("abort",()=>d.disconnect(),{once:!0});return}o.request(l)})}function On(e){let{enabled:t=!0,open:o,ref:n,onComplete:r}=e,i=Y(r),s=vo(n,o);Xa.useEffect(()=>{if(!t)return;let a=new AbortController;return s(i,a.signal),()=>{a.abort()}},[t,o,i,s])}var kt={};Mt(kt,{engine:()=>Zr,env:()=>Jr,os:()=>Xr,screenReader:()=>Qr});var Xr={};Mt(Xr,{android:()=>Qa,apple:()=>Kr,ios:()=>Gr,linux:()=>mm,mac:()=>Ja,windows:()=>pm});function dm(){return typeof navigator>"u"?{userAgent:"",platform:"",maxTouchPoints:0}:{userAgent:navigator.userAgent,platform:navigator.platform??"",maxTouchPoints:navigator.maxTouchPoints??0}}var{userAgent:um,platform:fm,maxTouchPoints:qa}=dm(),Jt=um.toLowerCase(),$t=fm.toLowerCase();var Gr=/^i(os$|p)/.test($t)||$t==="macintel"&&qa>1,Za="android",Qa=$t===Za||Jt.includes(Za),Ja=!Gr&&$t.startsWith("mac"),pm=$t.startsWith("win"),mm=!Qa&&/^(linux|chrome os)/.test($t),Kr=Ja||Gr;var Zr={};Mt(Zr,{blink:()=>bm,gecko:()=>gm,webkit:()=>qr});var qr=typeof CSS<"u"&&!!CSS.supports?.("-webkit-backdrop-filter:none"),gm=!qr&&Jt.includes("firefox"),bm=!qr&&Jt.includes("chrom");var Qr={};Mt(Qr,{voiceOver:()=>hm});var hm=Kr;var Jr={};Mt(Jr,{jsdom:()=>wm});var wm=/jsdom|happydom/.test(Jt);var Yo=0,Ke=class e{static create(){return new e}currentId=Yo;start(t,o){this.clear(),this.currentId=setTimeout(()=>{this.currentId=Yo,o()},t)}isStarted(){return this.currentId!==Yo}clear=()=>{this.currentId!==Yo&&(clearTimeout(this.currentId),this.currentId=Yo)};disposeEffect=()=>this.clear};function at(){let e=ke(Ke.create).current;return go(e.disposeEffect),e}var Be=b(z(),1);function $a(e){return"nativeEvent"in e}function Pt(e,t){let o=["mouse","pen"];return t||o.push("",void 0),o.includes(e)}function ec(e){let t=e.type;return t==="click"||t==="mousedown"||t==="keydown"||t==="keyup"}var $r="data-base-ui-focusable";var ei="input:not([type='hidden']):not([disabled]),[contenteditable]:not([contenteditable='false']),textarea:not([disabled])";function Nn(e){let t=e.activeElement;for(;t?.shadowRoot?.activeElement!=null;)t=t.shadowRoot.activeElement;return t}function re(e,t){if(!e||!t)return!1;let o=t.getRootNode?.();if(e.contains(t))return!0;if(o&&ho(o)){let n=t;for(;n;){if(e===n)return!0;n=n.parentNode||n.host}}return!1}function Me(e){return"composedPath"in e?e.composedPath()[0]:e.target}function zt(e,t){if(!U(e))return!1;let o=e;if(t.hasElement(o))return!o.hasAttribute("data-trigger-disabled");for(let[,n]of t.entries())if(re(n,o))return!n.hasAttribute("data-trigger-disabled");return!1}function In(e,t){if(t==null)return!1;if("composedPath"in e)return e.composedPath().includes(t);let o=e;return o.target!=null&&t.contains(o.target)}function tc(e){return e.matches("html,body")}function oc(e){return he(e)&&e.matches(ei)}function ti(e){return e?.closest(`button,a[href],[role="button"],select,[tabindex]:not([tabindex="-1"]),${ei}`)!=null}function nc(e){if(!e||kt.env.jsdom)return!0;try{return e.matches(":focus-visible")}catch{return!0}}function vm(e,t){return t!=null&&!Pt(t)?0:typeof e=="function"?e():e}function $e(e,t,o){let n=vm(e,o);return typeof n=="number"?n:n?.[t]}function oi(e){return typeof e=="function"?e():e}function Ln(e,t){return t||e==="click"||e==="mousedown"}function rc(e){return e?.includes("mouse")&&e!=="mousedown"}var ic=b(W(),1),sc=Be.createContext({hasProvider:!1,timeoutMs:0,delayRef:{current:0},initialDelayRef:{current:0},timeout:new Ke,currentIdRef:{current:null},currentContextRef:{current:null}});function _m(e,t){e.current=t.current}function ni(e){let{children:t,delay:o,timeoutMs:n=0}=e,r=Be.useRef(o),i=Be.useRef(o),s=Be.useRef(null),a=Be.useRef(null),l=at();return F(()=>{if(i.current=o,!s.current){r.current=o;return}r.current={open:$e(r.current,"open"),close:$e(o,"close")}},[o,s,r,i]),(0,ic.jsx)(sc.Provider,{value:Be.useMemo(()=>({hasProvider:!0,delayRef:r,initialDelayRef:i,currentIdRef:s,timeoutMs:n,currentContextRef:a,timeout:l}),[n,l]),children:t})}function ri(e,t={open:!1}){let{open:o}=t,n="rootStore"in e?e.rootStore:e,r=n.useState("floatingId"),i=Be.useContext(sc),{currentIdRef:s,delayRef:a,timeoutMs:l,initialDelayRef:c,currentContextRef:d,hasProvider:m,timeout:u}=i,[f,p]=Be.useState(!1),g=Be.useRef(o);return F(()=>{g.current=o},[o]),F(()=>{function h(){d.current?.setIsInstantPhase(!1),s.current=null,d.current=null,a.current=c.current,u.clear()}if(s.current&&!o&&s.current===r){if(p(!1),l){let y=r;return u.start(l,()=>{n.select("open")||s.current&&s.current!==y||h()}),()=>{(g.current||s.current!==y)&&u.clear()}}h()}},[o,r,s,a,l,c,d,u,n]),F(()=>{if(!o)return;let h=d.current,y=s.current;u.clear(),d.current={onOpenChange:n.setOpen,setIsInstantPhase:p},s.current=r,a.current={open:0,close:$e(c.current,"close")},y!==null&&y!==r?(p(!0),h?.setIsInstantPhase(!0),h?.onOpenChange(!1,ee(G.none))):(p(!1),h?.setIsInstantPhase(!1))},[o,r,n,s,a,c,d,u]),F(()=>()=>{if(s.current===r){if(d.current=null,!g.current)return;s.current=null,_m(a,c),u.clear()}},[d,s,a,r,c,u]),Be.useMemo(()=>({hasProvider:m,delayRef:a,isInstantPhase:f}),[m,a,f])}function ct(...e){return()=>{for(let t=0;t({x:e,y:e}),ym={left:"right",right:"left",bottom:"top",top:"bottom"};function Bn(e,t,o){return lt(e,Dt(t,o))}function _t(e,t){return typeof e=="function"?e(t):e}function Ne(e){return e.split("-")[0]}function dt(e){return e.split("-")[1]}function Hn(e){return e==="x"?"y":"x"}function Ko(e){return e==="y"?"height":"width"}function Fe(e){let t=e[0];return t==="t"||t==="b"?"y":"x"}function Xo(e){return Hn(Fe(e))}function lc(e,t,o){o===void 0&&(o=!1);let n=dt(e),r=Xo(e),i=Ko(r),s=r==="x"?n===(o?"end":"start")?"right":"left":n==="start"?"bottom":"top";return t.reference[i]>t.floating[i]&&(s=Uo(s)),[s,Uo(s)]}function dc(e){let t=Uo(e);return[Mn(e),t,Mn(t)]}function Mn(e){return e.includes("start")?e.replace("start","end"):e.replace("end","start")}var ac=["left","right"],cc=["right","left"],xm=["top","bottom"],Sm=["bottom","top"];function Rm(e,t,o){switch(e){case"top":case"bottom":return o?t?cc:ac:t?ac:cc;case"left":case"right":return t?xm:Sm;default:return[]}}function uc(e,t,o,n){let r=dt(e),i=Rm(Ne(e),o==="start",n);return r&&(i=i.map(s=>s+"-"+r),t&&(i=i.concat(i.map(Mn)))),i}function Uo(e){let t=Ne(e);return ym[t]+e.slice(t.length)}function Em(e){var t,o,n,r;return{top:(t=e.top)!=null?t:0,right:(o=e.right)!=null?o:0,bottom:(n=e.bottom)!=null?n:0,left:(r=e.left)!=null?r:0}}function zn(e){return typeof e!="number"?Em(e):{top:e,right:e,bottom:e,left:e}}function eo(e){let{x:t,y:o,width:n,height:r}=e;return{width:n,height:r,top:o,left:t,right:t+n,bottom:o+r,x:t,y:o}}function Ct(e,t,o=!0){return e.filter(r=>r.parentId===t).flatMap(r=>[...!o||r.context?.open?[r]:[],...Ct(e,r.id,o)])}function _o(e){return`data-base-ui-${e}`}var He=b(z(),1),mc=b(Ht(),1);var fc={style:{transition:"none"}};var Tm="data-base-ui-swipe-ignore",km="data-swipe-ignore",o1=`[${Tm}]`,n1=`[${km}]`;var pc={fallbackAxisSide:"end"};var gc=b(W(),1),Pm=He.createContext(null),Cm=()=>He.useContext(Pm),Am=_o("portal");function bc(e={}){let{ref:t,container:o,componentProps:n=me,elementProps:r}=e,i=mo(),a=Cm()?.portalNode,[l,c]=He.useState(null),[d,m]=He.useState(null),u=Y(h=>{h!==null&&m(h)}),f=He.useRef(null);F(()=>{if(o===null){f.current&&(f.current=null,m(null),c(null));return}let h=(o&&(En(o)?o:o.current))??a??document.body;if(h==null){f.current&&(f.current=null,m(null),c(null));return}f.current!==h&&(f.current=h,m(null),c(h))},[o,a]);let p=Oe("div",n,{ref:[t,u],props:[{id:i,[Am]:""},r]}),g=l&&p?mc.createPortal(p,l):null;return{node:d,nodeId:He.isValidElement(p)?p.props.id:void 0,subtree:g}}var to=b(z(),1);function hc(){let e=new Map;return{emit(t,o){e.get(t)?.forEach(n=>n(o))},on(t,o){e.has(t)||e.set(t,new Set),e.get(t).add(o)},off(t,o){e.get(t)?.delete(o)}}}var Om=b(W(),1),Nm=to.createContext(null),Im=to.createContext(null),Dn=()=>to.useContext(Nm)?.id||null,Ft=e=>{let t=to.useContext(Im);return e??t};var Ve=b(z(),1);function Lm(e,t){let o=null,n=null,r=!1;return{contextElement:e||void 0,getBoundingClientRect(){let i=e?.getBoundingClientRect()||{width:0,height:0,x:0,y:0},s=t.axis==="x"||t.axis==="both",a=t.axis==="y"||t.axis==="both",l=["mouseenter","mousemove"].includes(t.dataRef.current.openEvent?.type||"")&&t.pointerType!=="touch",c=i.width,d=i.height,m=i.x,u=i.y;return o==null&&t.x&&s&&(o=i.x-t.x),n==null&&t.y&&a&&(n=i.y-t.y),m-=o||0,u-=n||0,c=0,d=0,!r||l?(c=t.axis==="y"?i.width:0,d=t.axis==="x"?i.height:0,m=s&&t.x!=null?t.x:m,u=a&&t.y!=null?t.y:u):r&&!l&&(d=t.axis==="x"?i.height:d,c=t.axis==="y"?i.width:c),r=!0,{width:c,height:d,x:m,y:u,top:u,right:m+c,bottom:u+d,left:m}}}}function wc(e){return e!=null&&e.clientX!=null}function ii(e,t={}){let{enabled:o=!0,axis:n="both"}=t,r="rootStore"in e?e.rootStore:e,i=r.useState("open"),s=r.useState("floatingElement"),a=r.useState("domReferenceElement"),l=r.context.dataRef,c=Ve.useRef(!1),d=Ve.useRef(null),[m,u]=Ve.useState(),[f,p]=Ve.useState([]),g=Y(w=>{r.set("positionReference",w)}),h=Y((w,R,x)=>{c.current||l.current.openEvent&&!wc(l.current.openEvent)||r.set("positionReference",Lm(x??a,{x:w,y:R,axis:n,dataRef:l,pointerType:m}))}),y=Y(w=>{i?d.current||(h(w.clientX,w.clientY,w.currentTarget),p([])):h(w.clientX,w.clientY,w.currentTarget)}),_=Pt(m)?s:i;Ve.useEffect(()=>{if(!o){g(a);return}if(!_)return;function w(){d.current?.(),d.current=null}let R=fe(s);function x(S){let E=Me(S);re(s,E)?w():h(S.clientX,S.clientY)}return!l.current.openEvent||wc(l.current.openEvent)?d.current=oe(R,"mousemove",x):g(a),w},[_,o,s,l,a,r,h,g,f]),Ve.useEffect(()=>()=>{r.set("positionReference",null)},[r]),Ve.useEffect(()=>{o&&!s&&(c.current=!1)},[o,s]),Ve.useEffect(()=>{!o&&i&&(c.current=!0)},[o,i]);let v=Ve.useMemo(()=>{function w(R){u(R.pointerType)}return{onPointerDown:w,onPointerEnter:w,onMouseMove:y,onMouseEnter:y}},[y]);return Ve.useMemo(()=>o?{reference:v,trigger:v}:{},[o,v])}var Xe=b(z(),1);function Mm(){return!1}function Bm(e){return{escapeKey:typeof e=="boolean"?e:e?.escapeKey??!1,outsidePress:typeof e=="boolean"?e:e?.outsidePress??!0}}function si(e,t={}){let{enabled:o=!0,escapeKey:n=!0,outsidePress:r=!0,outsidePressEvent:i="sloppy",referencePress:s=Mm,bubbles:a,externalTree:l}=t,c="rootStore"in e?e.rootStore:e,d=c.useState("open"),m=c.useState("floatingElement"),{dataRef:u}=c.context,f=Ft(l),p=Y(typeof r=="function"?r:()=>!1),g=typeof r=="function"?p:r,h=g!==!1,y=Y(()=>i),{escapeKey:_,outsidePress:v}=Bm(a),w=Xe.useRef(!1),R=Xe.useRef(!1),x=Xe.useRef(!1),S=Xe.useRef(!1),E=Xe.useRef(""),T=Xe.useRef(null),P=at(),N=at(),H=Y(()=>{N.clear(),u.current.insideReactTree=!1}),j=Y(O=>{let V=u.current.floatingContext?.nodeId;return(f?Ct(f.nodesRef.current,V):[]).some(ie=>ie.context?.open&&!ie.context.dataRef.current[O])}),L=Y(O=>In(O,c.select("floatingElement"))||In(O,c.select("domReferenceElement"))),k=Y(O=>{s()&&c.setOpen(!1,ee(G.triggerPress,O.nativeEvent))}),I=Y(O=>{if(!d||!o||!n||O.key!=="Escape"||S.current||!_&&j("__escapeKeyBubbles"))return;let V=$a(O)?O.nativeEvent:O,Z=ee(G.escapeKey,V);c.setOpen(!1,Z),Z.isCanceled||O.preventDefault(),!_&&!Z.isPropagationAllowed&&O.stopPropagation()}),C=Y(()=>{u.current.insideReactTree=!0,N.start(0,H)}),A=Y(O=>{if(!d||!o||O.button!==0)return;let V=Me(O.nativeEvent);re(c.select("floatingElement"),V)&&(w.current||(w.current=!0,R.current=!1))}),M=Y(O=>{!d||!o||(O.defaultPrevented||O.nativeEvent.defaultPrevented)&&w.current&&(R.current=!0)});Xe.useEffect(()=>{if(!d||!o)return H;u.current.__escapeKeyBubbles=_,u.current.__outsidePressBubbles=v;let O=new Ke,V=new Ke;function Z(){O.clear(),S.current=!0}function ie(){O.start(kt.engine.webkit?5:0,()=>{S.current=!1})}function K(){x.current=!0,V.start(0,()=>{x.current=!1})}function Q(){w.current=!1,R.current=!1}function q(){let B=E.current,D=B==="pen"||!B?"mouse":B,Se=y(),Ae=typeof Se=="function"?Se():Se;return typeof Ae=="string"?Ae:Ae[D]}function $(B){let D=q();return D==="intentional"&&B.type!=="click"||D==="sloppy"&&B.type==="click"}function ne(B){let D=u.current.floatingContext?.nodeId,Se=f&&Ct(f.nodesRef.current,D).some(Ae=>In(B,Ae.context?.elements.floating));return L(B)||Se}function se(B){if($(B)){B.type!=="click"&&!L(B)&&(V.clear(),x.current=!1),H();return}if(u.current.insideReactTree){H();return}let D=Me(B),Se=`[${_o("inert")}]`,Ae=U(D)?D.getRootNode():null,Nt=Array.from((ho(Ae)?Ae:Pe(c.select("floatingElement"))).querySelectorAll(Se)),it=c.context.triggerElements;if(D&&(it.hasElement(D)||it.hasMatchingElement(Ye=>re(Ye,D))))return;let It=U(D)?D:null;for(;It&&!wt(It);){let Ye=bt(It);if(wt(Ye)||!U(Ye))break;It=Ye}if(!(Nt.length&&U(D)&&!tc(D)&&!re(D,c.select("floatingElement"))&&Nt.every(Ye=>!re(It,Ye)))){if(he(D)&&!("touches"in B)){let Ye=wt(D),uo=Le(D),Xt=/auto|scroll/,pn=Ye||Xt.test(uo.overflowX),fo=Ye||Xt.test(uo.overflowY),Lt=pn&&D.clientWidth>0&&D.scrollWidth>D.clientWidth,mn=fo&&D.clientHeight>0&&D.scrollHeight>D.clientHeight,gn=uo.direction==="rtl",bn=mn&&(gn?B.offsetX<=D.offsetWidth-D.clientWidth:B.offsetX>D.clientWidth),hn=Lt&&B.offsetY>D.clientHeight;if(bn||hn)return}if(!ne(B)){if(q()==="intentional"&&x.current){V.clear(),x.current=!1;return}typeof g=="function"&&!g(B)||j("__outsidePressBubbles")||(c.setOpen(!1,ee(G.outsidePress,B)),H())}}}function ze(B){q()!=="sloppy"||B.pointerType==="touch"||!c.select("open")||!o||L(B)||se(B)}function ae(B){if(q()!=="sloppy"||!c.select("open")||!o||L(B))return;let D=B.touches[0];D&&(T.current={startTime:Date.now(),startX:D.clientX,startY:D.clientY,dismissOnTouchEnd:!1,dismissOnMouseDown:!0},P.start(1e3,()=>{T.current&&(T.current.dismissOnTouchEnd=!1,T.current.dismissOnMouseDown=!1)}))}function ge(B,D){let Se=Me(B);if(!Se)return;let Ae=oe(Se,B.type,()=>{D(B),Ae()})}function be(B){E.current="touch",ge(B,ae)}function Ee(B){P.clear(),B.type==="pointerdown"&&(E.current=B.pointerType),!(B.type==="mousedown"&&T.current&&!T.current.dismissOnMouseDown)&&ge(B,D=>{D.type==="pointerdown"?ze(D):se(D)})}function ye(B){if(!w.current)return;let D=R.current;if(Q(),q()==="intentional"){if(B.type==="pointercancel"){D&&K();return}if(!ne(B)){if(D){K();return}typeof g=="function"&&!g(B)||(V.clear(),x.current=!0,H())}}}function Kt(B){if(q()!=="sloppy"||!T.current||L(B))return;let D=B.touches[0];if(!D)return;let Se=Math.abs(D.clientX-T.current.startX),Ae=Math.abs(D.clientY-T.current.startY),Nt=Math.sqrt(Se*Se+Ae*Ae);Nt>5&&(T.current.dismissOnTouchEnd=!0),Nt>10&&(se(B),P.clear(),T.current=null)}function rt(B){ge(B,Kt)}function ft(B){q()!=="sloppy"||!T.current||L(B)||(T.current.dismissOnTouchEnd&&se(B),P.clear(),T.current=null)}function Ot(B){ge(B,ft)}let xe=Pe(m),fn=ct(n&&ct(oe(xe,"keydown",I),oe(xe,"compositionstart",Z),oe(xe,"compositionend",ie)),h&&ct(oe(xe,"click",Ee,!0),oe(xe,"pointerdown",Ee,!0),oe(xe,"pointerup",ye,!0),oe(xe,"pointercancel",ye,!0),oe(xe,"mousedown",Ee,!0),oe(xe,"mouseup",ye,!0),oe(xe,"touchstart",be,!0),oe(xe,"touchmove",rt,!0),oe(xe,"touchend",Ot,!0)));return()=>{fn(),O.clear(),V.clear(),Q(),x.current=!1,H()}},[u,m,n,h,g,d,o,_,v,I,H,y,j,L,f,c,P]);let X=Xe.useMemo(()=>({onKeyDown:I,onPointerDown:k,onClick:k}),[I,k]),de=Xe.useMemo(()=>({onKeyDown:I,onPointerDown:M,onMouseDown:M,onClickCapture:C,onMouseDownCapture(O){C(),A(O)},onPointerDownCapture(O){C(),A(O)},onMouseUpCapture:C,onTouchEndCapture:C,onTouchMoveCapture:C}),[I,C,A,M]);return Xe.useMemo(()=>o?{reference:X,floating:de,trigger:X}:{},[o,X,de])}var Ie=b(z(),1);function vc(e,t,o){let{reference:n,floating:r}=e,i=Fe(t),s=Xo(t),a=Ko(s),l=Ne(t),c=i==="y",d=n.x+n.width/2-r.width/2,m=n.y+n.height/2-r.height/2,u=n[a]/2-r[a]/2,f;switch(l){case"top":f={x:d,y:n.y-r.height};break;case"bottom":f={x:d,y:n.y+n.height};break;case"right":f={x:n.x+n.width,y:m};break;case"left":f={x:n.x-r.width,y:m};break;default:f={x:n.x,y:n.y}}let p=dt(t);return p&&(f[s]+=u*(p==="end"?1:-1)*(o&&c?-1:1)),f}async function _c(e,t){var o;t===void 0&&(t={});let{x:n,y:r,platform:i,rects:s,elements:a,strategy:l}=e,{boundary:c="clippingAncestors",rootBoundary:d="viewport",elementContext:m="floating",altBoundary:u=!1,padding:f=0}=_t(t,e),p=zn(f),h=a[u?m==="floating"?"reference":"floating":m],y=eo(await i.getClippingRect({element:(o=await(i.isElement==null?void 0:i.isElement(h)))==null||o?h:h.contextElement||await(i.getDocumentElement==null?void 0:i.getDocumentElement(a.floating)),boundary:c,rootBoundary:d,strategy:l})),_=m==="floating"?{x:n,y:r,width:s.floating.width,height:s.floating.height}:s.reference,v=await(i.getOffsetParent==null?void 0:i.getOffsetParent(a.floating)),w=await(i.isElement==null?void 0:i.isElement(v))&&await(i.getScale==null?void 0:i.getScale(v))||{x:1,y:1},R=eo(i.convertOffsetParentRelativeRectToViewportRelativeRect?await i.convertOffsetParentRelativeRectToViewportRelativeRect({elements:a,rect:_,offsetParent:v,strategy:l}):_);return{top:(y.top-R.top+p.top)/w.y,bottom:(R.bottom-y.bottom+p.bottom)/w.y,left:(y.left-R.left+p.left)/w.x,right:(R.right-y.right+p.right)/w.x}}var Hm=50,yc=async(e,t,o)=>{let{placement:n="bottom",strategy:r="absolute",middleware:i=[],platform:s}=o,a=s.detectOverflow?s:{...s,detectOverflow:_c},l=await(s.isRTL==null?void 0:s.isRTL(t)),c=await s.getElementRects({reference:e,floating:t,strategy:r}),{x:d,y:m}=vc(c,n,l),u=n,f=0,p={};for(let g=0;gL<=0)){var N,H;let L=(((N=i.flip)==null?void 0:N.index)||0)+1,k=S[L];if(k&&(!(m==="alignment"?_!==Fe(k):!1)||P.every(A=>Fe(A.placement)===_?A.overflows[0]>0:!0)))return{data:{index:L,overflows:P},reset:{placement:k}};let I=(H=P.filter(C=>C.overflows[0]<=0).sort((C,A)=>C.overflows[1]-A.overflows[1])[0])==null?void 0:H.placement;if(!I)switch(f){case"bestFit":{var j;let C=(j=P.filter(A=>{if(x){let M=Fe(A.placement);return M===_||M==="y"}return!0}).map(A=>[A.placement,A.overflows.filter(M=>M>0).reduce((M,X)=>M+X,0)]).sort((A,M)=>A[1]-M[1])[0])==null?void 0:j[0];C&&(I=C);break}case"initialPlacement":I=a;break}if(r!==I)return{reset:{placement:I}}}return{}}}};var Sc=new Set(["left","top"]);async function zm(e,t){let{placement:o,platform:n,elements:r}=e,i=await(n.isRTL==null?void 0:n.isRTL(r.floating)),s=Ne(o),a=dt(o),l=Fe(o)==="y",c=Sc.has(s)?-1:1,d=i&&l?-1:1,m=_t(t,e),{mainAxis:u,crossAxis:f,alignmentAxis:p}=typeof m=="number"?{mainAxis:m,crossAxis:0,alignmentAxis:null}:{mainAxis:m.mainAxis||0,crossAxis:m.crossAxis||0,alignmentAxis:m.alignmentAxis};return a&&typeof p=="number"&&(f=a==="end"?p*-1:p),l?{x:f*d,y:u*c}:{x:u*c,y:f*d}}var Rc=function(e){return e===void 0&&(e=0),{name:"offset",options:e,async fn(t){var o,n;let{x:r,y:i,placement:s,middlewareData:a}=t,l=await zm(t,e);return s===((o=a.offset)==null?void 0:o.placement)&&(n=a.arrow)!=null&&n.alignmentOffset?{}:{x:r+l.x,y:i+l.y,data:{...l,placement:s}}}}},Ec=function(e){return e===void 0&&(e={}),{name:"shift",options:e,async fn(t){let{x:o,y:n,placement:r,platform:i}=t,{mainAxis:s=!0,crossAxis:a=!1,limiter:l={fn:_=>{let{x:v,y:w}=_;return{x:v,y:w}}},...c}=_t(e,t),d={x:o,y:n},m=await i.detectOverflow(t,c),u=Fe(r),f=Hn(u),p=d[f],g=d[u],h=(_,v)=>Bn(v+m[_==="y"?"top":"left"],v,v-m[_==="y"?"bottom":"right"]);s&&(p=h(f,p)),a&&(g=h(u,g));let y=l.fn({...t,[f]:p,[u]:g});return{...y,data:{x:y.x-o,y:y.y-n,enabled:{[f]:s,[u]:a}}}}}},Tc=function(e){return e===void 0&&(e={}),{options:e,fn(t){var o,n;let{x:r,y:i,placement:s,rects:a,middlewareData:l}=t,{offset:c=0,mainAxis:d=!0,crossAxis:m=!0}=_t(e,t),u={x:r,y:i},f=Fe(s),p=Hn(f),g=u[p],h=u[f],y=_t(c,t),_=typeof y=="number"?{mainAxis:y,crossAxis:0}:{mainAxis:(o=y.mainAxis)!=null?o:0,crossAxis:(n=y.crossAxis)!=null?n:0};if(d){let R=p==="y"?"height":"width",x=a.reference[p]-a.floating[R]+_.mainAxis,S=a.reference[p]+a.reference[R]-_.mainAxis;gS&&(g=S)}if(m){var v,w;let R=p==="y"?"width":"height",x=Sc.has(Ne(s)),S=a.reference[f]-a.floating[R]+(x&&((v=l.offset)==null?void 0:v[f])||0)+(x?0:_.crossAxis),E=a.reference[f]+a.reference[R]+(x?0:((w=l.offset)==null?void 0:w[f])||0)-(x?_.crossAxis:0);hE&&(h=E)}return{[p]:g,[f]:h}}}},kc=function(e){return e===void 0&&(e={}),{name:"size",options:e,async fn(t){let{placement:o,rects:n,platform:r,elements:i}=t,{apply:s=()=>{},...a}=_t(e,t),l=await r.detectOverflow(t,a),c=Ne(o),d=dt(o),m=Fe(o)==="y",{width:u,height:f}=n.floating,p,g;c==="top"||c==="bottom"?(p=c,g=d===(await(r.isRTL==null?void 0:r.isRTL(i.floating))?"start":"end")?"left":"right"):(g=c,p=d==="end"?"top":"bottom");let h=f-l.top-l.bottom,y=u-l.left-l.right,_=Dt(f-l[p],h),v=Dt(u-l[g],y),w=t.middlewareData.shift,R=!w,x=_,S=v;w!=null&&w.enabled.x&&(S=y),w!=null&&w.enabled.y&&(x=h),R&&!d&&(m?S=u-2*lt(l.left,l.right):x=f-2*lt(l.top,l.bottom)),await s({...t,availableWidth:S,availableHeight:x});let E=await r.getDimensions(i.floating);return u!==E.width||f!==E.height?{reset:{rects:!0}}:{}}}};function Ac(e){let t=Le(e),o=parseFloat(t.width)||0,n=parseFloat(t.height)||0,r=he(e),i=r?e.offsetWidth:o,s=r?e.offsetHeight:n,a=jt(o)!==i||jt(n)!==s;return a&&(o=i,n=s),{width:o,height:n,$:a}}function ci(e){return U(e)?e:e.contextElement}function yo(e){let t=ci(e);if(!he(t))return vt(1);let o=t.getBoundingClientRect(),{width:n,height:r,$:i}=Ac(t),s=(i?jt(o.width):o.width)/n,a=(i?jt(o.height):o.height)/r;return(!s||!Number.isFinite(s))&&(s=1),(!a||!Number.isFinite(a))&&(a=1),{x:s,y:a}}var Dm=vt(0);function Oc(e){let t=fe(e);return!kn()||!t.visualViewport?Dm:{x:t.visualViewport.offsetLeft,y:t.visualViewport.offsetTop}}function jm(e,t,o){return t===void 0&&(t=!1),!!o&&t&&o===fe(e)}function oo(e,t,o,n){t===void 0&&(t=!1),o===void 0&&(o=!1);let r=e.getBoundingClientRect(),i=ci(e),s=vt(1);t&&(n?U(n)&&(s=yo(n)):s=yo(e));let a=jm(i,o,n)?Oc(i):vt(0),l=(r.left+a.x)/s.x,c=(r.top+a.y)/s.y,d=r.width/s.x,m=r.height/s.y;if(i&&n){let u=fe(i),f=U(n)?fe(n):n,p=u,g=Pn(p);for(;g&&f!==p;){let h=yo(g),y=g.getBoundingClientRect(),_=Le(g),v=y.left+(g.clientLeft+parseFloat(_.paddingLeft))*h.x,w=y.top+(g.clientTop+parseFloat(_.paddingTop))*h.y;l*=h.x,c*=h.y,d*=h.x,m*=h.y,l+=v,c+=w,p=fe(g),g=Pn(p)}}return eo({width:d,height:m,x:l,y:c})}function jn(e,t){let o=Wo(e).scrollLeft;return t?t.left+o:oo(ht(e)).left+o}function Nc(e,t){let o=e.getBoundingClientRect(),n=o.left+t.scrollLeft-jn(e,o),r=o.top+t.scrollTop;return{x:n,y:r}}function Fm(e){let{elements:t,rect:o,offsetParent:n,strategy:r}=e,i=r==="fixed",s=ht(n),a=t?Vo(t.floating):!1;if(n===s||a&&i)return o;let l={scrollLeft:0,scrollTop:0},c=vt(1),d=vt(0),m=he(n);if((m||!i)&&((Qt(n)!=="body"||Fo(s))&&(l=Wo(n)),m)){let f=oo(n);c=yo(n),d.x=f.x+n.clientLeft,d.y=f.y+n.clientTop}let u=s&&!m&&!i?Nc(s,l):vt(0);return{width:o.width*c.x,height:o.height*c.y,x:o.x*c.x-l.scrollLeft*c.x+d.x+u.x,y:o.y*c.y-l.scrollTop*c.y+d.y+u.y}}function Vm(e){return e.getClientRects?Array.from(e.getClientRects()):[]}function Wm(e){let t=Wo(e),o=e.ownerDocument.body,n=lt(e.scrollWidth,e.clientWidth,o.scrollWidth,o.clientWidth),r=lt(e.scrollHeight,e.clientHeight,o.scrollHeight,o.clientHeight),i=-t.scrollLeft+jn(e),s=-t.scrollTop;return Le(o).direction==="rtl"&&(i+=lt(e.clientWidth,o.clientWidth)-n),{width:n,height:r,x:i,y:s}}var Ym=25;function Um(e,t,o){o===void 0&&(o="viewport");let n=o==="layoutViewport",r=fe(e),i=ht(e),s=r.visualViewport,a=i.clientWidth,l=i.clientHeight,c=0,d=0;if(s){let u=!kn()||t==="fixed";n?u||(c=-s.offsetLeft,d=-s.offsetTop):(a=s.width,l=s.height,u&&(c=s.offsetLeft,d=s.offsetTop))}if(jn(i)<=0){let u=i.ownerDocument,f=u.body,p=getComputedStyle(f),g=u.compatMode==="CSS1Compat"&&parseFloat(p.marginLeft)+parseFloat(p.marginRight)||0,h=Math.abs(i.clientWidth-f.clientWidth-g),y=getComputedStyle(i).scrollbarGutter==="stable both-edges"?h/2:h;y<=Ym&&(a-=y)}return{width:a,height:l,x:c,y:d}}function Gm(e,t){let o=oo(e,!0,t==="fixed"),n=o.top+e.clientTop,r=o.left+e.clientLeft,i=yo(e),s=e.clientWidth*i.x,a=e.clientHeight*i.y,l=r*i.x,c=n*i.y;return{width:s,height:a,x:l,y:c}}function Pc(e,t,o){let n;if(t==="viewport"||t==="layoutViewport")n=Um(e,o,t);else if(t==="document")n=Wm(ht(e));else if(U(t))n=Gm(t,o);else{let r=Oc(e);n={x:t.x-r.x,y:t.y-r.y,width:t.width,height:t.height}}return eo(n)}function Km(e,t){let o=t.get(e);if(o)return o;let n=Bt(e,[],!1).filter(a=>U(a)&&Qt(a)!=="body"),r=null,i=Le(e).position==="fixed",s=i?bt(e):e;for(;U(s)&&!wt(s);){let a=Le(s),l=Tn(s),c=r?r.position:i?"fixed":"";!l&&(c==="fixed"||c==="absolute"&&a.position==="static")?n=n.filter(m=>m!==s):r=a,s=bt(s)}return t.set(e,n),n}function Xm(e){let{element:t,boundary:o,rootBoundary:n,strategy:r}=e,s=[...o==="clippingAncestors"?Vo(t)?[]:Km(t,this._c):[].concat(o),n],a=Pc(t,s[0],r),l=a.top,c=a.right,d=a.bottom,m=a.left;for(let u=1;u{a(!1,1e-7)},1e3)}S=!1}try{n=new IntersectionObserver(E,{...x,root:i.ownerDocument})}catch{n=new IntersectionObserver(E,x)}n.observe(e)}let l=fe(e),c=()=>a(o);return l.addEventListener("resize",c),a(!0),()=>{l.removeEventListener("resize",c),s()}}function qo(e,t,o,n){n===void 0&&(n={});let{ancestorScroll:r=!0,ancestorResize:i=!0,elementResize:s=typeof ResizeObserver=="function",layoutShift:a=typeof IntersectionObserver=="function",animationFrame:l=!1}=n,c=ci(e),d=r||i?[...c?Bt(c):[],...t?Bt(t):[]]:[];d.forEach(y=>{r&&y.addEventListener("scroll",o),i&&y.addEventListener("resize",o)});let m=c&&a?$m(c,o,i):null,u=-1,f=null;s&&(f=new ResizeObserver(y=>{let[_]=y;_&&_.target===c&&f&&t&&(f.unobserve(t),cancelAnimationFrame(u),u=requestAnimationFrame(()=>{var v;(v=f)==null||v.observe(t)})),o()}),c&&!l&&f.observe(c),t&&f.observe(t));let p,g=l?oo(e):null;l&&h();function h(){let y=oo(e);g&&!Lc(g,y)&&o(),g=y,p=requestAnimationFrame(h)}return o(),()=>{var y;d.forEach(_=>{r&&_.removeEventListener("scroll",o),i&&_.removeEventListener("resize",o)}),m?.(),(y=f)==null||y.disconnect(),f=null,l&&cancelAnimationFrame(p)}}var Mc=Rc;var Bc=Ec,Hc=xc,zc=kc;var Dc=Tc,Fn=(e,t,o)=>{let n=new Map,r=o??{},i={...li,...r.platform,_c:n};return yc(e,t,{...r,platform:i})};var we=b(z(),1),Fc=b(z(),1),Vc=b(Ht(),1),tg=typeof document<"u",og=function(){},Vn=tg?Fc.useLayoutEffect:og;function Wn(e,t){if(e===t)return!0;if(typeof e!=typeof t)return!1;if(typeof e=="function"&&e.toString()===t.toString())return!0;let o,n,r;if(e&&t&&typeof e=="object"){if(Array.isArray(e)){if(o=e.length,o!==t.length)return!1;for(n=o;n--!==0;)if(!Wn(e[n],t[n]))return!1;return!0}if(r=Object.keys(e),o=r.length,o!==Object.keys(t).length)return!1;for(n=o;n--!==0;)if(!{}.hasOwnProperty.call(t,r[n]))return!1;for(n=o;n--!==0;){let i=r[n];if(!(i==="_owner"&&e.$$typeof)&&!Wn(e[i],t[i]))return!1}return!0}return e!==e&&t!==t}function Wc(e){return typeof window>"u"?1:(e.ownerDocument.defaultView||window).devicePixelRatio||1}function jc(e,t){let o=Wc(e);return Math.round(t*o)/o}function di(e){let t=we.useRef(e);return Vn(()=>{t.current=e}),t}function Yc(e){e===void 0&&(e={});let{placement:t="bottom",strategy:o="absolute",middleware:n=[],platform:r,elements:{reference:i,floating:s}={},transform:a=!0,whileElementsMounted:l,open:c}=e,[d,m]=we.useState({x:0,y:0,strategy:o,placement:t,middlewareData:{},isPositioned:!1}),[u,f]=we.useState(n);Wn(u,n)||f(n);let[p,g]=we.useState(null),[h,y]=we.useState(null),_=we.useCallback(A=>{A!==x.current&&(x.current=A,g(A))},[]),v=we.useCallback(A=>{A!==S.current&&(S.current=A,y(A))},[]),w=i||p,R=s||h,x=we.useRef(null),S=we.useRef(null),E=we.useRef(d),T=l!=null,P=di(l),N=di(r),H=di(c),j=we.useCallback(()=>{if(!x.current||!S.current)return;let A={placement:t,strategy:o,middleware:u};N.current&&(A.platform=N.current),Fn(x.current,S.current,A).then(M=>{let X={...M,isPositioned:H.current!==!1};L.current&&!Wn(E.current,X)&&(E.current=X,Vc.flushSync(()=>{m(X)}))})},[u,t,o,N,H]);Vn(()=>{c===!1&&E.current.isPositioned&&(E.current.isPositioned=!1,m(A=>({...A,isPositioned:!1})))},[c]);let L=we.useRef(!1);Vn(()=>(L.current=!0,()=>{L.current=!1}),[]),Vn(()=>{if(w&&(x.current=w),R&&(S.current=R),w&&R){if(P.current)return P.current(w,R,j);j()}},[w,R,j,P,T]);let k=we.useMemo(()=>({reference:x,floating:S,setReference:_,setFloating:v}),[_,v]),I=we.useMemo(()=>({reference:w,floating:R}),[w,R]),C=we.useMemo(()=>{let A={position:o,left:0,top:0};if(!I.floating)return A;let M=jc(I.floating,d.x),X=jc(I.floating,d.y);return a?{...A,transform:"translate("+M+"px, "+X+"px)",...Wc(I.floating)>=1.5&&{willChange:"transform"}}:{position:o,left:M,top:X}},[o,a,I.floating,d.x,d.y]);return we.useMemo(()=>({...d,update:j,refs:k,elements:I,floatingStyles:C}),[d,j,k,I,C])}var ui=(e,t)=>{let o=Mc(e);return{name:o.name,fn:o.fn,options:[e,t]}},fi=(e,t)=>{let o=Bc(e);return{name:o.name,fn:o.fn,options:[e,t]}},pi=(e,t)=>({fn:Dc(e).fn,options:[e,t]}),mi=(e,t)=>{let o=Hc(e);return{name:o.name,fn:o.fn,options:[e,t]}},gi=(e,t)=>{let o=zc(e);return{name:o.name,fn:o.fn,options:[e,t]}};var Yn=class{attachedStores=[];attachedStoreValue=null;storeListeners=new Set;constructor(t,o,n=!0){this.fallbackStore=t,this.componentName=o,this.throwOnMissingTrigger=n}get attachedStore(){return this.attachedStoreValue}get store(){return this.attachedStoreValue??this.fallbackStore}get serverStore(){return this.fallbackStore}subscribeStore(t){return this.storeListeners.add(t),()=>{this.storeListeners.delete(t)}}attachStore(t){return this.attachedStores.push(t),this.setActiveStore(t),()=>{let o=this.attachedStores.lastIndexOf(t);o!==-1&&this.attachedStores.splice(o,1),this.setActiveStore(this.attachedStores[this.attachedStores.length-1]??null)}}setActiveStore(t){this.attachedStoreValue!==t&&(this.attachedStoreValue=t,this.storeListeners.forEach(o=>{o()}))}openByTrigger(t){let o=this.attachedStore;if(o===null)return;let n;if(t){for(let r=this.attachedStores.length-1;r>=0&&!n;r-=1)n=this.attachedStores[r].context.triggerElements.getById(t);n??=this.fallbackStore.context.triggerElements.getById(t)}if(t&&!n&&this.throwOnMissingTrigger)throw new Error(De(99,this.componentName,t,this.componentName));o.setOpen(!0,ee(G.imperativeAction,void 0,n))}closePopup(){let t=this.attachedStore;t!==null&&t.setOpen(!1,ee(G.imperativeAction))}};var ro=b(z(),1),sl=b(Ht(),1);var rl=b(z(),1);var ol=b(z(),1),_i=b(Un(),1),nl=b(Qc(),1);var Jc=b(z(),1);var hi=[],wi;function $c(){return wi}function el(e){hi.push(e)}function vi(e){let t=(o,n)=>{let r=ke(_g).current,i;try{wi=r;for(let s of hi)s.before(r);i=e(o,n);for(let s of hi)s.after(r);r.didInitialize=!0}finally{wi=void 0}return i};return t.displayName=e.displayName||e.name,t}function tl(e){return Jc.forwardRef(vi(e))}function _g(){return{didInitialize:!1}}var yg=po(19),xg=yg?Rg:Eg;function Kn(e,t,o,n,r){return xg(e,t,o,n,r)}function Sg(e,t,o,n,r){let i=ol.useCallback(()=>t(e.getSnapshot(),o,n,r),[e,t,o,n,r]);return(0,_i.useSyncExternalStore)(e.subscribe,i,i)}el({before(e){e.syncIndex=0,e.didInitialize||(e.syncTick=1,e.syncHooks=[],e.didChangeStore=!0,e.getSnapshot=()=>{let t=!1;for(let o=0;o0&&(e.didChangeStore&&(e.didChangeStore=!1,e.subscribe=t=>{let o=new Set;for(let r of e.syncHooks)o.add(r.store);let n=[];for(let r of o)n.push(r.subscribe(t));return()=>{for(let r of n)r()}}),(0,_i.useSyncExternalStore)(e.subscribe,e.getSnapshot,e.getSnapshot))}});function Rg(e,t,o,n,r){let i=$c();if(!i)return Sg(e,t,o,n,r);let s=i.syncIndex;i.syncIndex+=1;let a;return i.didInitialize?(a=i.syncHooks[s],(a.store!==e||a.selector!==t||!Object.is(a.a1,o)||!Object.is(a.a2,n)||!Object.is(a.a3,r))&&(a.store!==e&&(i.didChangeStore=!0),a.store=e,a.selector=t,a.a1=o,a.a2=n,a.a3=r,a.value=t(e.getSnapshot(),o,n,r))):(a={store:e,selector:t,a1:o,a2:n,a3:r,value:t(e.getSnapshot(),o,n,r)},i.syncHooks.push(a)),a.value}function Eg(e,t,o,n,r){return(0,nl.useSyncExternalStoreWithSelector)(e.subscribe,e.getSnapshot,e.getSnapshot,i=>t(i,o,n,r))}var Xn=class{constructor(t){this.state=t,this.listeners=new Set,this.updateTick=0}subscribe=t=>(this.listeners.add(t),()=>{this.listeners.delete(t)});getSnapshot=()=>this.state;setState(t){if(this.state===t)return;this.state=t,this.updateTick+=1;let o=this.updateTick;for(let n of this.listeners){if(o!==this.updateTick)return;n(t)}}update(t){for(let o in t)if(!Object.is(this.state[o],t[o])){this.setState({...this.state,...t});return}}set(t,o){Object.is(this.state[t],o)||this.setState({...this.state,[t]:o})}notifyAll(){let t={...this.state};this.setState(t)}use(t,o,n,r){return Kn(this,t,o,n,r)}};var no=b(z(),1);var Vt=class extends Xn{constructor(t,o={},n){super(t),this.context=o,this.selectors=n}useSyncedValue(t,o){no.useDebugValue(t);let n=this;F(()=>{n.state[t]!==o&&n.set(t,o)},[n,t,o])}useSyncedValueWithCleanup(t,o){let n=this;F(()=>(n.state[t]!==o&&n.set(t,o),()=>{n.set(t,void 0)}),[n,t,o])}useSyncedValues(t){let o=this,n=Object.values(t);F(()=>{o.update(t)},[o,...n])}useControlledProp(t,o){no.useDebugValue(t);let n=this,r=o!==void 0;F(()=>{r&&!Object.is(n.state[t],o)&&n.setState({...n.state,[t]:o})},[n,t,o,r])}select(t,o,n,r){let i=this.selectors[t];return i(this.state,o,n,r)}useState(t,o,n,r){return no.useDebugValue(t),Kn(this,this.selectors[t],o,n,r)}useContextCallback(t,o){no.useDebugValue(t);let n=Y(o??Ge);this.context[t]=n}useStateSetter(t){let o=no.useRef(void 0);return o.current===void 0&&(o.current=n=>{this.set(t,n)}),o.current}observe(t,o){let n;typeof t=="function"?n=t:n=this.selectors[t];let r=n(this.state);return o(r,r,this),this.subscribe(i=>{let s=n(i);if(!Object.is(r,s)){let a=r;r=s,o(s,a,this)}})}};var Tg={open:e=>e.open,transitionStatus:e=>e.transitionStatus,domReferenceElement:e=>e.domReferenceElement,referenceElement:e=>e.positionReference??e.referenceElement,floatingElement:e=>e.floatingElement,floatingId:e=>e.floatingId},Wt=class extends Vt{constructor(t){let{syncOnly:o,nested:n,onOpenChange:r,triggerElements:i,...s}=t;super({...s,positionReference:s.referenceElement,domReferenceElement:s.referenceElement},{onOpenChange:r,dataRef:{current:{}},events:hc(),nested:n,triggerElements:i},Tg),this.syncOnly=o}syncOpenEvent=(t,o)=>{(!t||!this.state.open||o!=null&&ec(o))&&(this.context.dataRef.current.openEvent=t?o:void 0)};dispatchOpenChange=(t,o)=>{this.syncOpenEvent(t,o.event);let n={open:t,reason:o.reason,nativeEvent:o.event,nested:this.context.nested,triggerElement:o.trigger};this.context.events.emit("openchange",n)};setOpen=(t,o)=>{if(this.syncOnly){this.context.onOpenChange?.(t,o);return}this.dispatchOpenChange(t,o),this.context.onOpenChange?.(t,o)}};function il(e){let{popupStore:t,treatPopupAsFloatingElement:o=!1,floatingRootContext:n,floatingId:r,nested:i,onOpenChange:s}=e,a=t.useState("open"),l=t.useState("activeTriggerElement"),c=t.useState(o?"popupElement":"positionerElement"),d=t.context.triggerElements,m=s,u=rl.useRef(null);n===void 0&&u.current===null&&(u.current=new Wt({open:a,transitionStatus:void 0,referenceElement:l,floatingElement:c,triggerElements:d,onOpenChange:m,floatingId:r,syncOnly:!0,nested:i}));let f=n??u.current;return t.useSyncedValue("floatingId",r),F(()=>{let p={open:a,floatingId:r,referenceElement:l,floatingElement:c};U(l)&&(p.domReferenceElement=l),f.state.positionReference===f.state.referenceElement&&(p.positionReference=l),f.update(p)},[a,r,l,c,f]),f.context.onOpenChange=m,f.context.nested=i,f}var al={tabIndex:-1,[$r]:""};function cl(e,t=!1){let o=mo(),n=Dn()!=null,r=ke(()=>e(o,n)).current;return il({popupStore:r,treatPopupAsFloatingElement:t,floatingRootContext:r.state.floatingRootContext,floatingId:o,nested:n,onOpenChange:r.setOpen}),r}function ll({handle:e,store:t}){return F(()=>e.attachStore(t),[e,t]),null}function kg(e,t){let o=ro.useRef(null),n=ro.useRef(null);return ro.useCallback(r=>{if(e===void 0)return;let i=!1;if(o.current!==null){let s=o.current,a=n.current,l=t.context.triggerElements.getById(s);a&&l===a&&(t.context.triggerElements.delete(s),i=!0),o.current=null,n.current=null}if(r!==null&&(o.current=e,n.current=r,t.context.triggerElements.add(e,r),i=!0),i){let s=t.context.triggerElements.size;t.select("open")&&t.state.triggerCount!==s&&t.set("triggerCount",s)}},[t,e])}function Pg(e,t,o,n=!1){t?e.preventUnmountingOnClose=!1:n&&(e.preventUnmountingOnClose=!0);let r=o?.id??null;(r||t)&&(e.activeTriggerId=r,e.activeTriggerElement=o??null)}function Cg(e){let t=!1;return e.preventUnmountOnClose=()=>{t=!0},()=>t}function dl(e,t,o,n={}){let r=o.reason,i=r===G.triggerHover,s=t&&r===G.triggerFocus,a=!t&&(r===G.triggerPress||r===G.escapeKey),l=Cg(o);if(e.context.onOpenChange?.(t,o),o.isCanceled)return;n.onBeforeDispatch?.(),e.state.floatingRootContext.dispatchOpenChange(t,o);let c=()=>{let d={...n.extraState,open:t};s?d.instantType="focus":a?d.instantType="dismiss":i&&(d.instantType=void 0),Pg(d,t,o.trigger,l()),e.update(d)};i?sl.flushSync(c):c()}function ul(e,t,o,n){let r=o.useState("isMountedByTrigger",e),i=kg(e,o),s=Y(l=>{let c=o.select("open"),d=o.select("activeTriggerId");if(d===e){o.update({activeTriggerElement:l,...c?n:null});return}d==null&&c&&o.update({activeTriggerId:e,activeTriggerElement:l,...n})}),a=ro.useCallback(l=>{i(l),l&&s(l)},[i,s]);return F(()=>{r&&o.update({activeTriggerElement:t.current,...n})},[r,o,t,...Object.values(n)]),{registerTrigger:a,isMountedByThisTrigger:r}}function fl(e,t={}){let{closeOnActiveTriggerUnmount:o=!1}=t,n=ro.useRef(null),r=e.useState("open"),i=e.useState("triggerCount"),s=e.useState("activeTriggerId"),a=e.useState("activeTriggerElement");F(()=>{if(!r){n.current=null,e.state.triggerCount!==0&&e.set("triggerCount",0);return}let l=e.context.triggerElements.size,c={};e.state.triggerCount!==l&&(c.triggerCount=l);let d=e.select("activeTriggerId"),m=null;if(d){let u=e.context.triggerElements.getById(d);if(u)n.current=d,u!==e.state.activeTriggerElement&&(c.activeTriggerElement=u);else{for(let[f,p]of e.context.triggerElements.entries())if(p===e.state.activeTriggerElement){c.activeTriggerId=f,c.activeTriggerElement=p,n.current=f;break}c.activeTriggerId===void 0&&(n.current===d?m=d:n.current=null)}}else n.current=null;if(!m&&!d&&l===1){let u=e.context.triggerElements.entries().next();if(!u.done){let[f,p]=u.value;c.activeTriggerId=f,c.activeTriggerElement=p,n.current=f}}(c.triggerCount!==void 0||c.activeTriggerId!==void 0||c.activeTriggerElement!==void 0)&&e.update(c),m&&o&&queueMicrotask(()=>{if(e.select("open")&&e.select("activeTriggerId")===m&&!e.context.triggerElements.getById(m)){let u=ee(G.none);e.setOpen(!1,u),u.isCanceled||e.update({activeTriggerId:null,activeTriggerElement:null})}})},[r,e,i,s,a,o])}function pl(e,t,o){let{mounted:n,setMounted:r,transitionStatus:i}=Ba(e),s=t.useState("preventUnmountingOnClose"),a=e?!1:s;t.useSyncedValues({mounted:n,transitionStatus:i,preventUnmountingOnClose:a});let l=Y(()=>{r(!1),t.update({activeTriggerId:null,activeTriggerElement:null,mounted:!1,preventUnmountingOnClose:!1}),o?.(),t.context.onOpenChangeComplete?.(!1)});return On({enabled:n&&!e&&!a,open:e,ref:t.context.popupRef,onComplete(){e||l()}}),{forceUnmount:l,transitionStatus:i}}function ml(e,t){e.useSyncedValues(t),F(()=>()=>{e.update({activeTriggerProps:me,inactiveTriggerProps:me,popupProps:me})},[e])}var io=class{constructor(){this.idMap=new Map}add(t,o){this.idMap.set(t,o)}delete(t){this.idMap.delete(t)}hasElement(t){for(let o of this.idMap.values())if(o===t)return!0;return!1}hasMatchingElement(t){for(let o of this.idMap.values())if(t(o))return!0;return!1}getById(t){return this.idMap.get(t)}entries(){return this.idMap.entries()}elements(){return this.idMap.values()}get size(){return this.idMap.size}};function gl(){return new Wt({open:!1,transitionStatus:void 0,floatingElement:null,referenceElement:null,triggerElements:new io,floatingId:void 0,syncOnly:!1,nested:!1,onOpenChange:void 0})}function hl(){return{open:!1,openProp:void 0,mounted:!1,transitionStatus:void 0,floatingRootContext:gl(),floatingId:void 0,triggerCount:0,preventUnmountingOnClose:!1,payload:void 0,activeTriggerId:null,activeTriggerElement:null,triggerIdProp:void 0,popupElement:null,positionerElement:null,activeTriggerProps:me,inactiveTriggerProps:me,popupProps:me}}function wl(e,t,o=!1){return new Wt({open:!1,transitionStatus:void 0,floatingElement:null,referenceElement:null,triggerElements:e,floatingId:t,syncOnly:!0,nested:o,onOpenChange:void 0})}var Zo=e=>e.triggerIdProp??e.activeTriggerId,yi=e=>e.openProp??e.open,bl=e=>(e.popupElement?.id??e.floatingId)||void 0;function vl(e,t){return t!==void 0&&yi(e)&&Zo(e)===t}function Ag(e,t){return vl(e,t)?!0:t!==void 0&&yi(e)&&Zo(e)==null&&e.triggerCount===1}var _l={open:yi,mounted:e=>e.mounted,transitionStatus:e=>e.transitionStatus,floatingRootContext:e=>e.floatingRootContext,triggerCount:e=>e.triggerCount,preventUnmountingOnClose:e=>e.preventUnmountingOnClose,payload:e=>e.payload,activeTriggerId:Zo,activeTriggerElement:e=>e.mounted?e.activeTriggerElement:null,popupId:bl,isTriggerActive:(e,t)=>t!==void 0&&Zo(e)===t,isOpenedByTrigger:(e,t)=>vl(e,t),isMountedByTrigger:(e,t)=>t!==void 0&&Zo(e)===t&&e.mounted,triggerProps:(e,t)=>t?e.activeTriggerProps:e.inactiveTriggerProps,triggerPopupId:(e,t)=>Ag(e,t)?bl(e):void 0,popupProps:e=>e.popupProps,popupElement:e=>e.popupElement,positionerElement:e=>e.positionerElement};var xi=b(z(),1),yl=b(Un(),1);function xl(e){let t=xi.useCallback(n=>e===void 0?Ge:e.subscribeStore(n),[e]),o=xi.useCallback(()=>e===void 0?void 0:e.store,[e]);return(0,yl.useSyncExternalStore)(t,o,()=>e?.serverStore)}function Sl(e){return Og(e,e.rootContext)}function Og(e,t){let{nodeId:o,externalTree:n}=e,r=t.useState("referenceElement"),i=t.useState("floatingElement"),s=t.useState("domReferenceElement"),a=t.useState("open"),l=t.useState("floatingId"),[c,d]=Ie.useState(null),[m,u]=Ie.useState(void 0),[f,p]=Ie.useState(void 0),g=Ie.useRef(null),h=Ft(n),y=Ie.useMemo(()=>({reference:r,floating:i,domReference:s}),[r,i,s]),_=Yc({...e,elements:{...y,...c&&{reference:c}}}),v=U(m)?m:null,w=f===void 0?t.state.floatingElement:f;t.useSyncedValue("referenceElement",m??null),t.useSyncedValue("domReferenceElement",m===void 0?s:v),t.useSyncedValue("floatingElement",w);let R=Ie.useCallback(N=>{let H=U(N)?{getBoundingClientRect:()=>N.getBoundingClientRect(),getClientRects:()=>N.getClientRects(),contextElement:N}:N;d(H),_.refs.setReference(H)},[_.refs]),x=Ie.useCallback(N=>{(U(N)||N===null)&&(g.current=N,u(N)),(U(_.refs.reference.current)||_.refs.reference.current===null||N!==null&&!U(N))&&_.refs.setReference(N)},[_.refs,u]),S=Ie.useCallback(N=>{p(N),_.refs.setFloating(N)},[_.refs]),E=Ie.useMemo(()=>({..._.refs,setReference:x,setFloating:S,setPositionReference:R,domReference:g}),[_.refs,x,S,R]),T=Ie.useMemo(()=>({..._.elements,domReference:s}),[_.elements,s]),P=Ie.useMemo(()=>({..._,dataRef:t.context.dataRef,open:a,onOpenChange:t.setOpen,events:t.context.events,floatingId:l,refs:E,elements:T,nodeId:o,rootStore:t}),[_,E,T,o,t,a,l]);return F(()=>{s&&(g.current=s)},[s]),F(()=>{t.context.dataRef.current.floatingContext=P;let N=h?.nodesRef.current.find(H=>H.id===o);N&&(N.context=P)}),Ie.useMemo(()=>({..._,context:P,refs:E,elements:T,rootStore:t}),[_,E,T,P,t])}var yt=b(z(),1);var Si=kt.os.mac&&kt.engine.webkit;function Ri(e,t={}){let{enabled:o=!0,delay:n}=t,r="rootStore"in e?e.rootStore:e,{events:i,dataRef:s}=r.context,a=yt.useRef(!1),l=yt.useRef(null),c=yt.useRef(!0),d=at();yt.useEffect(()=>{let u=r.select("domReferenceElement");if(!o)return;let f=fe(u);function p(){let y=r.select("domReferenceElement");!r.select("open")&&he(y)&&y===Nn(Pe(y))&&(a.current=!0)}function g(){c.current=!0}function h(){c.current=!1}return ct(oe(f,"blur",p),Si&&oe(f,"keydown",g,!0),Si&&oe(f,"pointerdown",h,!0))},[r,o]),yt.useEffect(()=>{if(!o)return;function u(f){if(f.reason===G.triggerPress||f.reason===G.escapeKey){let p=r.select("domReferenceElement");U(p)&&(l.current=p,a.current=!0)}}return i.on("openchange",u),()=>{i.off("openchange",u)}},[i,o,r]);let m=yt.useMemo(()=>{function u(){a.current=!1,l.current=null}return{onMouseLeave(){u()},onFocus(f){let p=f.currentTarget;if(a.current){if(l.current===p)return;u()}let g=Me(f.nativeEvent);if(U(g)){if(Si&&!f.relatedTarget){if(!c.current&&!oc(g))return}else if(!nc(g))return}let h=zt(f.relatedTarget,r.context.triggerElements),{nativeEvent:y,currentTarget:_}=f,v=typeof n=="function"?n():n;if(r.select("open")&&h||v===0||v===void 0){r.setOpen(!0,ee(G.triggerFocus,y,_));return}d.start(v,()=>{a.current||r.setOpen(!0,ee(G.triggerFocus,y,_))})},onBlur(f){u();let p=f.relatedTarget,g=f.nativeEvent,h=U(p)&&p.hasAttribute(_o("focus-guard"))&&p.getAttribute("data-type")==="outside";d.start(0,()=>{let y=r.select("domReferenceElement"),_=Nn(Pe(y));!p&&_===y||re(s.current.floatingContext?.refs.floating.current,_)||re(y,_)||h||zt(p??_,r.context.triggerElements)||r.setOpen(!1,ee(G.triggerFocus,g))})}}},[s,n,r,d]);return yt.useMemo(()=>o?{reference:m,trigger:m}:{},[o,m])}var Ti=b(z(),1);var Ei=class e{constructor(){this.pointerType=void 0,this.interactedInside=!1,this.handler=void 0,this.blockMouseMove=!0,this.performedPointerEventsMutation=!1,this.pointerEventsScopeElement=null,this.pointerEventsReferenceElement=null,this.pointerEventsFloatingElement=null,this.restTimeoutPending=!1,this.openChangeTimeout=new Ke,this.restTimeout=new Ke,this.handleCloseOptions=void 0}static create(){return new e}dispose=()=>{this.openChangeTimeout.clear(),this.restTimeout.clear()};disposeEffect=()=>this.dispose},qn=new WeakMap;function So(e){if(!e.performedPointerEventsMutation)return;let t=e.pointerEventsScopeElement;t&&qn.get(t)===e&&(e.pointerEventsScopeElement?.style.removeProperty("pointer-events"),e.pointerEventsReferenceElement?.style.removeProperty("pointer-events"),e.pointerEventsFloatingElement?.style.removeProperty("pointer-events"),qn.delete(t)),e.performedPointerEventsMutation=!1,e.pointerEventsScopeElement=null,e.pointerEventsReferenceElement=null,e.pointerEventsFloatingElement=null}function Zn(e,t){let{scopeElement:o,referenceElement:n,floatingElement:r}=t,i=qn.get(o);i&&i!==e&&So(i),So(e),e.performedPointerEventsMutation=!0,e.pointerEventsScopeElement=o,e.pointerEventsReferenceElement=n,e.pointerEventsFloatingElement=r,qn.set(o,e),o.style.pointerEvents="none",n.style.pointerEvents="auto",r.style.pointerEvents="auto"}function Ro(e){let t=e.context.dataRef.current,o=ke(()=>t.hoverInteractionState??Ei.create()).current;return t.hoverInteractionState||(t.hoverInteractionState=o),go(t.hoverInteractionState.disposeEffect),t.hoverInteractionState}function ki(e,t={}){let{enabled:o=!0,closeDelay:n=0,nodeId:r}=t,i="rootStore"in e?e.rootStore:e,s=i.useState("open"),a=i.useState("floatingElement"),l=i.useState("domReferenceElement"),{dataRef:c}=i.context,d=Ft(),m=Dn(),u=Ro(i),f=at(),p=Y(()=>Ln(c.current.openEvent?.type,u.interactedInside)),g=Y(()=>rc(c.current.openEvent?.type)),h=Y(()=>{So(u)});F(()=>{s||(u.pointerType=void 0,u.restTimeoutPending=!1,u.interactedInside=!1,h())},[s,u,h]),Ti.useEffect(()=>h,[h]),F(()=>{if(o&&s&&u.handleCloseOptions?.blockPointerEvents&&g()&&U(l)&&a){let y=l,_=a,v=Pe(a),w=d?.nodesRef.current.find(E=>E.id===m)?.context?.elements.floating;w&&(w.style.pointerEvents="");let R=u.pointerEventsScopeElement!==_?u.pointerEventsScopeElement:null,x=w!==_?w:null,S=u.handleCloseOptions?.getScope?.()??R??x??y.closest("[data-rootownerid]")??v.body;return Zn(u,{scopeElement:S,referenceElement:y,floatingElement:_}),()=>{h()}}},[o,s,l,a,u,g,d,m,h]),Ti.useEffect(()=>{if(!o)return;function y(){return!!(d&&m&&Ct(d.nodesRef.current,m).length>0)}function _(E){let T=$e(n,"close",u.pointerType),P=()=>{i.setOpen(!1,ee(G.triggerHover,E)),d?.events.emit("floating.closed",E)};T?u.openChangeTimeout.start(T,P):(u.openChangeTimeout.clear(),P())}function v(E){let T=Me(E);if(!ti(T)){u.interactedInside=!1;return}u.interactedInside=T?.closest("[aria-haspopup]")!=null}function w(){u.openChangeTimeout.clear(),f.clear(),d?.events.off("floating.closed",x),h()}function R(E){if(y()&&d){d.events.on("floating.closed",x);return}if(zt(E.relatedTarget,i.context.triggerElements))return;let T=c.current.floatingContext?.nodeId??r,P=E.relatedTarget;if(!(d&&T&&U(P)&&Ct(d.nodesRef.current,T,!1).some(H=>re(H.context?.elements.floating,P)))){if(u.handler){u.handler(E);return}h(),g()&&!p()&&_(E)}}function x(E){!d||!m||y()||f.start(0,()=>{d.events.off("floating.closed",x),i.setOpen(!1,ee(G.triggerHover,E)),d.events.emit("floating.closed",E)})}let S=a;return ct(S&&oe(S,"mouseenter",w),S&&oe(S,"mouseleave",R),S&&oe(S,"pointerdown",v,!0),()=>{d?.events.off("floating.closed",x)})},[o,a,i,c,n,r,g,p,h,u,d,m,f])}var Yt=b(z(),1),Rl=b(Ht(),1);var Ng={current:null};function Pi(e,t={}){let{enabled:o=!0,delay:n=0,handleClose:r=null,mouseOnly:i=!1,restMs:s=0,move:a=!0,triggerElementRef:l=Ng,externalTree:c,isActiveTrigger:d=!0,getHandleCloseContext:m,isClosing:u,shouldOpen:f,guardStaleOpen:p=!1}=t,g="rootStore"in e?e.rootStore:e,{dataRef:h,events:y}=g.context,_=Ft(c),v=Ro(g),w=Yt.useRef(!1),R=je(r),x=je(n),S=je(s),E=je(o),T=je(f),P=je(u),N=Y(()=>Ln(h.current.openEvent?.type,v.interactedInside)),H=Y(()=>T.current?.()!==!1),j=Y((I,C,A)=>{let M=g.context.triggerElements;if(M.hasElement(C))return!I||!re(I,C);if(!U(A))return!1;let X=A;return M.hasMatchingElement(de=>re(de,X))&&(!I||!re(I,X))}),L=Y(()=>{if(!v.handler)return;Pe(g.select("domReferenceElement")).removeEventListener("mousemove",v.handler),v.handler=void 0}),k=Y(()=>{So(v)});return d&&(v.handleCloseOptions=R.current?.__options),Yt.useEffect(()=>L,[L]),Yt.useEffect(()=>{if(!o)return;function I(C){C.open?w.current=!1:(w.current=C.reason===G.triggerHover,L(),v.openChangeTimeout.clear(),v.restTimeout.clear(),v.blockMouseMove=!0,v.restTimeoutPending=!1)}return y.on("openchange",I),()=>{y.off("openchange",I)}},[o,y,v,L]),Yt.useEffect(()=>{if(!o)return;function I(O,V=!0){let Z=$e(x.current,"close",v.pointerType);Z?v.openChangeTimeout.start(Z,()=>{g.setOpen(!1,ee(G.triggerHover,O)),_?.events.emit("floating.closed",O)}):V&&(v.openChangeTimeout.clear(),g.setOpen(!1,ee(G.triggerHover,O)),_?.events.emit("floating.closed",O))}let C=l.current??(d?g.select("domReferenceElement"):null);if(!U(C))return;function A(O){if(v.openChangeTimeout.clear(),v.blockMouseMove=!1,i&&!Pt(v.pointerType))return;let V=oi(S.current),Z=$e(x.current,"open",v.pointerType),ie=Me(O),K=O.currentTarget??null,Q=g.select("domReferenceElement"),q=K;if(U(ie)&&!g.context.triggerElements.hasElement(ie)){for(let ye of g.context.triggerElements.elements())if(re(ye,ie)){q=ye;break}}U(K)&&U(Q)&&!g.context.triggerElements.hasElement(K)&&re(K,Q)&&(q=Q);let $=q==null?!1:j(Q,q,ie),ne=g.select("open"),se=P.current?.()??g.select("transitionStatus")==="ending",ze=!ne&&se&&w.current,ae=!$&&U(q)&&U(Q)&&re(Q,q)&&ze,ge=V>0&&!Z,be=$&&(ne||ze)||ae,Ee=!ne||$;if(be){H()&&g.setOpen(!0,ee(G.triggerHover,O,q));return}ge||(Z?v.openChangeTimeout.start(Z,()=>{Ee&&H()&&g.setOpen(!0,ee(G.triggerHover,O,q))}):Ee&&H()&&g.setOpen(!0,ee(G.triggerHover,O,q)))}function M(O){if(N()){k();return}L();let V=g.select("domReferenceElement"),Z=Pe(V);v.restTimeout.clear(),v.restTimeoutPending=!1;let ie=h.current.floatingContext??m?.();if(zt(O.relatedTarget,g.context.triggerElements))return;if(R.current&&ie){g.select("open")||v.openChangeTimeout.clear();let Q=l.current;v.handler=R.current({...ie,tree:_,x:O.clientX,y:O.clientY,onClose(){k(),L(),E.current&&!N()&&Q===g.select("domReferenceElement")&&I(O,!0)}}),Z.addEventListener("mousemove",v.handler),v.handler(O);return}(v.pointerType!=="touch"||!re(g.select("floatingElement"),O.relatedTarget))&&I(O)}function X(O){re(C,O.relatedTarget)||(v.openChangeTimeout.clear(),v.restTimeout.clear(),v.restTimeoutPending=!1)}let de=p?oe(C,"mouseout",X):void 0;return a?ct(oe(C,"mousemove",A,{once:!0}),oe(C,"mouseenter",A),oe(C,"mouseleave",M),de):ct(oe(C,"mouseenter",A),oe(C,"mouseleave",M),de)},[L,k,h,x,g,o,R,v,d,j,N,i,a,S,l,_,E,m,P,H,p]),Yt.useMemo(()=>{if(!o)return;function I(C){v.pointerType=C.pointerType}return{onPointerDown:I,onPointerEnter:I,onMouseMove(C){let{nativeEvent:A}=C,M=C.currentTarget,X=g.select("domReferenceElement"),de=g.select("open"),O=j(X,M,C.target);if(i&&!Pt(v.pointerType))return;if(de&&O&&v.handleCloseOptions?.blockPointerEvents){let ie=g.select("floatingElement");if(ie){let K=v.handleCloseOptions?.getScope?.()??M.ownerDocument.body;Zn(v,{scopeElement:K,referenceElement:M,floatingElement:ie})}}let V=oi(S.current);if(de&&!O||V===0||!O&&v.restTimeoutPending&&C.movementX**2+C.movementY**2<2)return;v.restTimeout.clear();function Z(){if(v.restTimeoutPending=!1,N())return;let ie=g.select("open");!v.blockMouseMove&&(!ie||O)&&H()&&g.setOpen(!0,ee(G.triggerHover,A,M))}v.pointerType==="touch"?Rl.flushSync(()=>{Z()}):O&&de?Z():(v.restTimeoutPending=!0,v.restTimeout.start(V,Z))}}},[o,v,N,j,i,g,S,H])}var El=.1,Ig=El*El,le=.5;function Qn(e,t,o,n,r,i){return n>=t!=i>=t&&e<=(r-o)*(t-n)/(i-n)+o}function Jn(e,t,o,n,r,i,s,a,l,c){let d=!1;return Qn(e,t,o,n,r,i)&&(d=!d),Qn(e,t,r,i,s,a)&&(d=!d),Qn(e,t,s,a,l,c)&&(d=!d),Qn(e,t,l,c,o,n)&&(d=!d),d}function Lg(e,t,o){return e>=o.x&&e<=o.x+o.width&&t>=o.y&&t<=o.y+o.height}function $n(e,t,o,n,r,i){let s=Math.min(o,r),a=Math.max(o,r),l=Math.min(n,i),c=Math.max(n,i);return e>=s&&e<=a&&t>=l&&t<=c}function Ci(e={}){let{blockPointerEvents:t=!1}=e,o=new Ke,n=({x:r,y:i,placement:s,elements:a,onClose:l,nodeId:c,tree:d})=>{let m=s?.split("-")[0],u=!1,f=null,p=null,g=typeof performance<"u"?performance.now():0;function h(_,v){let w=performance.now(),R=w-g;if(f===null||p===null||R===0)return f=_,p=v,g=w,!1;let x=_-f,S=v-p,E=x*x+S*S,T=R*R*Ig;return f=_,p=v,g=w,E0)}function j(){H()||y()}if(H())return;let L=w.getBoundingClientRect(),k=R.getBoundingClientRect(),I=r>k.right-k.width/2,C=i>k.bottom-k.height/2,A=k.width>L.width,M=k.height>L.height,X=(A?L:k).left,de=(A?L:k).right,O=(M?L:k).top,V=(M?L:k).bottom;if(m==="top"&&i>=L.bottom-1||m==="bottom"&&i<=L.top+1||m==="left"&&r>=L.right-1||m==="right"&&r<=L.left+1){j();return}let Z=!1;switch(m){case"top":Z=$n(x,S,X,L.top+1,de,k.bottom-1);break;case"bottom":Z=$n(x,S,X,k.top+1,de,L.bottom-1);break;case"left":Z=$n(x,S,k.right-1,V,L.left+1,O);break;case"right":Z=$n(x,S,L.right-1,V,k.left+1,O);break;default:}if(Z)return;if(u&&!Lg(x,S,L)){j();return}if(!T&&h(x,S)){j();return}let ie=!1;switch(m){case"top":{let K=A?le/2:le*4,Q=A||I?r+K:r-K,q=A?r-K:I?r+K:r-K,$=i+le+1,ne=I||A?k.bottom-le:k.top,se=I?A?k.bottom-le:k.top:k.bottom-le;ie=Jn(x,S,Q,$,q,$,k.left,ne,k.right,se);break}case"bottom":{let K=A?le/2:le*4,Q=A||I?r+K:r-K,q=A?r-K:I?r+K:r-K,$=i-le,ne=I||A?k.top+le:k.bottom,se=I?A?k.top+le:k.bottom:k.top+le;ie=Jn(x,S,Q,$,q,$,k.left,ne,k.right,se);break}case"left":{let K=M?le/2:le*4,Q=M||C?i+K:i-K,q=M?i-K:C?i+K:i-K,$=r+le+1,ne=C||M?k.right-le:k.left,se=C?M?k.right-le:k.left:k.right-le;ie=Jn(x,S,ne,k.top,se,k.bottom,$,Q,$,q);break}case"right":{let K=M?le/2:le*4,Q=M||C?i+K:i-K,q=M?i-K:C?i+K:i-K,$=r-le,ne=C||M?k.left+le:k.right,se=C?M?k.left+le:k.right:k.left+le;ie=Jn(x,S,$,Q,$,q,ne,k.top,se,k.bottom);break}default:}ie?u||o.start(40,j):j()}};return n.__options={...e,blockPointerEvents:t},n}var er=class extends Vt{setState(t){}update(t){}set(t,o){}notifyAll(){}};var hy=(function(e){return e.open="data-open",e.closed="data-closed",e[e.startingStyle=Wr.startingStyle]="startingStyle",e[e.endingStyle=Wr.endingStyle]="endingStyle",e.anchorHidden="data-anchor-hidden",e.side="data-side",e.align="data-align",e})({});var Mg={"data-popup-open":""};var Bg={"data-open":""},Hg={"data-closed":""},zg={"data-anchor-hidden":""},Tl={open(e){return e?Mg:null}};var Qo={open(e){return e?Bg:Hg},anchorHidden(e){return e?zg:null}},kl={...Qo,...Ha};function Pl(e){return po(19)?e:e?"true":void 0}var tr=b(z(),1),Ai=tr.createContext(void 0);function Eo(){return tr.useContext(Ai)?.direction??"ltr"}var qe=b(z(),1);var Dg=e=>({name:"arrow",options:e,async fn(t){let{x:o,y:n,placement:r,rects:i,platform:s,elements:a,middlewareData:l}=t,{element:c,padding:d=0,offsetParent:m="real"}=_t(e,t)||{};if(c==null)return{};let u=zn(d),f={x:o,y:n},p=Xo(r),g=Ko(p),h=await s.getDimensions(c),y=p==="y",_=y?"top":"left",v=y?"bottom":"right",w=y?"clientHeight":"clientWidth",R=i.reference[g]+i.reference[p]-f[p]-i.floating[g],x=f[p]-i.reference[p],S=m==="real"?await s.getOffsetParent?.(c):a.floating,E=a.floating[w]||i.floating[g];(!E||!await s.isElement?.(S))&&(E=a.floating[w]||i.floating[g]);let T=R/2-x/2,P=E/2-h[g]/2-1,N=Math.min(u[_],P),H=Math.min(u[v],P),j=N,L=E-h[g]-H,k=E/2-h[g]/2+T,I=Bn(j,k,L),C=!l.arrow&&dt(r)!=null&&k!==I&&i.reference[g]/2-(k({...Dg(e),options:[e,t]});var Al={name:"hide",async fn(e){let{width:t,height:o,x:n,y:r}=e.rects.reference,i=t===0&&o===0&&n===0&&r===0,s=await e.platform.detectOverflow(e,{elementContext:"reference"});return{data:{referenceHidden:s.top-o>=0||s.right-t>=0||s.bottom-o>=0||s.left-t>=0||i}}}};var To={sideX:"left",sideY:"top"};var Ol="--available-width",Nl="--available-height";function Ml(e,t,o){let n=e==="inline-start"||e==="inline-end";return{top:"top",right:n?o?"inline-start":"inline-end":"right",bottom:"bottom",left:n?o?"inline-end":"inline-start":"left"}[t]}function Il(e,t,o){let{rects:n,placement:r}=e;return{side:Ml(t,Ne(r),o),align:dt(r)||"center",anchor:{width:n.reference.width,height:n.reference.height},positioner:{width:n.floating.width,height:n.floating.height}}}function Bl(e){return jg(e,Sl)}function jg(e,t){let{anchor:o,positionMethod:n="absolute",side:r="bottom",sideOffset:i=0,align:s="center",alignOffset:a=0,collisionBoundary:l,collisionPadding:c=5,sticky:d=!1,arrowPadding:m=5,disableAnchorTracking:u=!1,inline:f,keepMounted:p=!1,floatingRootContext:g,mounted:h,collisionAvoidance:y,shift:_,nodeId:v,adaptiveOrigin:w,lazyFlip:R=!1,externalTree:x}=e,[S,E]=qe.useState(null);!h&&S!==null&&E(null);let T=y.side||"flip",P=y.align||"flip",N=y.fallbackAxisSide||"end",H=_?.crossAxis??!1,j=_?.rootBoundary,L=typeof o=="function"?o:void 0,k=Y(L),I=L?k:o,C=je(o),A=je(h),X=Eo()==="rtl",de=S||{top:"top",right:"right",bottom:"bottom",left:"left","inline-end":X?"left":"right","inline-start":X?"right":"left"}[r],O=s==="center"?de:`${de}-${s}`,V=c;typeof V=="number"?V={top:V,right:V,bottom:V,left:V}:V&&(V={top:V.top||0,right:V.right||0,bottom:V.bottom||0,left:V.left||0});let Z=1,ie=r==="bottom"?Z:0,K=r==="top"?Z:0,Q=r==="right"?Z:0,q=r==="left"?Z:0,$={boundary:l==="clipping-ancestors"?"clippingAncestors":l,padding:V},ne=qe.useRef(null),se=je(i),ze=je(a),ae=typeof i!="function"?i:0,ge=typeof a!="function"?a:0,be=[];f&&be.push(f),be.push(ui(te=>{let Je=Il(te,r,X),pt=typeof se.current=="function"?se.current(Je):se.current,Ue=typeof ze.current=="function"?ze.current(Je):ze.current;return{mainAxis:pt,crossAxis:Ue,alignmentAxis:Ue}},[ae,ge,X,r]));let Ee=P==="none"&&T!=="shift",ye=!Ee&&(d||H||T==="shift"),Kt=T==="none"?null:mi({...$,padding:{top:V.top+Z+ie,right:V.right+Z+q,bottom:V.bottom+Z+K,left:V.left+Z+Q},mainAxis:!H&&T==="flip",crossAxis:P==="flip"?"alignment":!1,fallbackAxisSideDirection:N}),rt=Ee?null:fi({...$,rootBoundary:j,mainAxis:P!=="none",crossAxis:ye,limiter:d||H?void 0:pi(te=>{if(!ne.current)return{};let{width:Je,height:pt}=ne.current.getBoundingClientRect(),Ue=Fe(Ne(te.placement)),Tt=Ue==="y"?Je:pt,mt=Ue==="y"?V.left+V.right:V.top+V.bottom;return{offset:Tt/2+mt/2}})},[$,d,H,j,V,P]);T==="shift"||P==="shift"||s==="center"?be.push(rt,Kt):be.push(Kt,rt),be.push(gi({...$,apply({elements:{floating:te},availableWidth:Je,availableHeight:pt,rects:Ue}){if(!A.current)return;let Tt=te.style;Tt.setProperty(Ol,`${Je}px`),Tt.setProperty(Nl,`${pt}px`);let mt=fe(te).devicePixelRatio||1,{x:Mo,y:wn,width:vn,height:Cr}=Ue.reference,Ar=(Math.round((Mo+vn)*mt)-Math.round(Mo*mt))/mt,Or=(Math.round((wn+Cr)*mt)-Math.round(wn*mt))/mt;Tt.setProperty("--anchor-width",`${Ar}px`),Tt.setProperty("--anchor-height",`${Or}px`)}}),Cl(te=>({element:ne.current||Pe(te.elements.floating).createElement("div"),padding:m,offsetParent:"floating"}),[m]),{name:"transformOrigin",fn(te){let{elements:Je,middlewareData:pt,placement:Ue,rects:Tt,y:mt}=te,Mo=Ne(Ue),wn=Fe(Mo),vn=ne.current,Cr=pt.arrow?.x||0,Ar=pt.arrow?.y||0,Or=vn?.clientWidth||0,Yf=vn?.clientHeight||0,Nr=Cr+Or/2,la=Ar+Yf/2,Uf=Math.abs(pt.shift?.y||0),Gf=Tt.reference.height/2,Bo=typeof i=="function"?i(Il(te,r,X)):i,Kf=Uf>Bo,Xf={top:`${Nr}px calc(100% + ${Bo}px)`,bottom:`${Nr}px ${-Bo}px`,left:`calc(100% + ${Bo}px) ${la}px`,right:`${-Bo}px ${la}px`}[Mo],qf=`${Nr}px ${Tt.reference.y+Gf-mt}px`;return Je.floating.style.setProperty("--transform-origin",ye&&wn==="y"&&Kf?qf:Xf),{}}},Al,w),F(()=>{!h&&g&&g.update({referenceElement:null,floatingElement:null,domReferenceElement:null,positionReference:null})},[h,g]);let ft=qe.useMemo(()=>({elementResize:!u&&typeof ResizeObserver<"u",layoutShift:!u&&typeof IntersectionObserver<"u"}),[u]),{refs:Ot,elements:xe,x:fn,y:B,middlewareData:D,update:Se,placement:Ae,context:Nt,isPositioned:it,floatingStyles:It}=t({rootContext:g,open:p?h:void 0,placement:O,middleware:be,strategy:n,whileElementsMounted:p?void 0:(...te)=>qo(...te,ft),nodeId:v,externalTree:x}),{sideX:Ye,sideY:uo}=D.adaptiveOrigin||To,Xt=it?n:"fixed",pn=qe.useMemo(()=>{let te;return it?w?te={position:Xt,[Ye]:fn,[uo]:B}:te={...It,position:Xt}:te={position:Xt,top:0,left:0},te[Ol]="100vw",te[Nl]="100vh",it||(te.opacity=0),te},[w,Xt,Ye,fn,uo,B,It,it]),fo=qe.useRef(null);F(()=>{if(!h)return;let te=C.current,Je=typeof te=="function"?te():te,Ue=(Ll(Je)?Je.current:Je)||null||null;Ue!==fo.current&&(Ot.setPositionReference(Ue),fo.current=Ue)},[h,Ot,I,C]),qe.useEffect(()=>{if(!h)return;let te=C.current;typeof te!="function"&&Ll(te)&&te.current!==fo.current&&(Ot.setPositionReference(te.current),fo.current=te.current)},[h,Ot,I,C]),qe.useEffect(()=>{if(p&&h&&xe.reference&&xe.floating)return qo(xe.reference,xe.floating,Se,ft)},[p,h,xe,Se,ft]);let Lt=Ne(Ae),mn=Ml(r,Lt,X),gn=dt(Ae)||"center",bn=!!D.hide?.referenceHidden;F(()=>{R&&h&&it&&Lt!==de&&E(Lt)},[R,h,it,Lt,de]);let hn=qe.useMemo(()=>({position:"absolute",top:D.arrow?.y,left:D.arrow?.x}),[D.arrow]),ca=D.arrow?.centerOffset!==0;return qe.useMemo(()=>({positionerStyles:pn,arrowStyles:hn,arrowRef:ne,arrowUncentered:ca,side:mn,align:gn,physicalSide:Lt,anchorHidden:bn,refs:Ot,context:Nt,isPositioned:it,update:Se}),[pn,hn,ne,ca,mn,gn,Lt,bn,Ot,Nt,it,Se])}function Ll(e){return e!=null&&"current"in e}function or(e){return e==="starting"?fc:me}function Hl(e,t,{styles:o,transitionStatus:n,props:r,refs:i,hidden:s,inert:a=!1}){let l={...o};return a&&(l.pointerEvents="none"),Oe("div",e,{state:t,ref:i,props:[{role:"presentation",hidden:s,style:l},or(n),r],stateAttributesMapping:Qo})}var zl=b(z(),1);var Oi=zl.forwardRef(function(t,o){let{render:n,className:r,disabled:i=!1,focusableWhenDisabled:s=!1,nativeButton:a=!0,style:l,...c}=t,{getButtonProps:d,buttonRef:m}=Ya({disabled:i,focusableWhenDisabled:s,native:a});return Oe("button",t,{state:{disabled:i},ref:[o,m],props:[c,d]})});var Ce=b(z(),1),Kl=b(Ht(),1);var Dl=b(z(),1);function jl(e){let[t,o]=Dl.useState({current:e,previous:null});return Object.is(e,t.current)||o({current:e,previous:t.current}),t.previous}var ko=b(z(),1);function Ni(e){let t=Le(e),o=parseFloat(t.width)||0,n=parseFloat(t.height)||0,r=he(e),i=r?e.offsetWidth:o,s=r?e.offsetHeight:n;return(jt(o)!==i||jt(n)!==s)&&(o=i,n=s),{width:o,height:n}}function Vl(e){let{popupElement:t,positionerElement:o,content:n,mounted:r,onMeasureLayout:i,onMeasureLayoutComplete:s,side:a,direction:l}=e,c=vo(t,!0),d=bo(),m=ko.useRef(null),u=ko.useRef(!0),f=ko.useRef(Ge),p=Y(i),g=Y(s),h=ko.useMemo(()=>Fg(a,l),[a,l]);F(()=>{if(!r){f.current=Ge,u.current=!0,m.current=null;return}if(!t||!o)return;f.current=Fl(t,h),Ii(t,"auto");let y=rr(t,"position","static"),_=rr(t,"transform","none"),v=rr(t,"scale","1"),w=Fl(o,{"--available-width":"max-content","--available-height":"max-content"});function R(){y(),_(),w()}function x(){R(),v()}if(p?.(),u.current||m.current===null){nr(o,"max-content");let P=Ni(t);return m.current=P,nr(o,P),x(),g?.(null,P),u.current=!1,()=>{f.current(),f.current=Ge}}nr(o,"max-content");let S=m.current,E=Ni(t);m.current=E,Ii(t,S),x(),g?.(S,E),nr(o,E);let T=new AbortController;return d.request(()=>{Ii(t,E),c(()=>{t.style.setProperty("--popup-width","auto"),t.style.setProperty("--popup-height","auto")},T.signal)}),()=>{T.abort(),d.cancel(),f.current(),f.current=Ge}},[n,t,o,c,d,r,p,g,h])}function Fg(e,t){let o=e==="top",n=e==="left"||e===(t==="rtl"?"inline-end":"inline-start");return!o&&!n?me:{position:"absolute",[o?"bottom":"top"]:"0",[n?"right":"left"]:"0"}}function rr(e,t,o){let n=e.style.getPropertyValue(t);return e.style.setProperty(t,o),()=>{e.style.setProperty(t,n)}}function Fl(e,t){let o=[];for(let[n,r]of Object.entries(t))o.push(rr(e,n,r));return o.length?()=>{o.forEach(n=>n())}:Ge}function Ii(e,t){let o=t==="auto"?"auto":`${t.width}px`,n=t==="auto"?"auto":`${t.height}px`;e.style.setProperty("--popup-width",o),e.style.setProperty("--popup-height",n)}function nr(e,t){let o=t==="max-content"?"max-content":`${t.width}px`,n=t==="max-content"?"max-content":`${t.height}px`;e.style.setProperty("--positioner-width",o),e.style.setProperty("--positioner-height",n)}var Wl=b(z(),1);var Yl=b(W(),1),ir=function(t){let{direction:o="ltr"}=t,n=Wl.useMemo(()=>({direction:o}),[o]);return(0,Yl.jsx)(Ai.Provider,{value:n,children:t.children})};var Ul={name:"adaptiveOrigin",async fn(e){let{x:t,y:o,rects:{floating:n},elements:{floating:r},platform:i,strategy:s,placement:a}=e,l=fe(r),c=l.getComputedStyle(r);if(!(c.transitionDuration!=="0s"&&c.transitionDuration!==""))return{x:t,y:o,data:To};let m=await i.getOffsetParent?.(r),u={width:0,height:0};if(s==="fixed"&&l?.visualViewport)u={width:l.visualViewport.width,height:l.visualViewport.height};else if(m===l){let _=Pe(r);u={width:_.documentElement.clientWidth,height:_.documentElement.clientHeight}}else await i.isElement?.(m)&&(u=await i.getDimensions(m));let f=Ne(a),p=t,g=o;f==="left"&&(p=u.width-(t+n.width)),f==="top"&&(g=u.height-(o+n.height));let h=f==="left"?"right":To.sideX,y=f==="top"?"bottom":To.sideY;return{x:p,y:g,data:{sideX:h,sideY:y}}}};var Po=b(W(),1),Xl={activationDirection:e=>e?{"data-activation-direction":e}:null};function ql(e){let{store:t,side:o,children:n}=e,r=Eo(),i=t.useState("activeTriggerElement"),s=t.useState("activeTriggerId"),a=t.useState("open"),l=t.useState("payload"),c=t.useState("mounted"),d=t.useState("popupElement"),m=t.useState("positionerElement"),u=jl(a?i:null),f=Yg(s,l),p=Ce.useRef(null),[g,h]=Ce.useState(null),[y,_]=Ce.useState(null),v=Ce.useRef(null),w=Ce.useRef(null),R=vo(v,!0),x=bo(),S=Ce.useRef(null),[E,T]=Ce.useState(null),[P,N]=Ce.useState(!1);F(()=>(t.set("adaptiveOrigin",Ul),()=>{t.set("adaptiveOrigin",void 0)}),[t]);let H=Y(()=>{v.current?.style.setProperty("animation","none"),v.current?.style.setProperty("transition","none"),w.current?.style.setProperty("display","none")}),j=Y(M=>{v.current?.style.removeProperty("animation"),v.current?.style.removeProperty("transition"),w.current?.style.removeProperty("display"),M&&T(M)}),L=Y(()=>{S.current?.abort();let M=new AbortController;S.current=M,R(()=>{h(null),T(null),p.current=null},M.signal)}),k=Ce.useRef(null);F(()=>{(!a||!c)&&(k.current=null)},[a,c]),F(()=>{if(i&&u&&i!==u&&k.current!==i&&p.current){h(p.current),N(!0);let M=Wg(u,i);_(M),k.current=i}},[i,u]),F(()=>{g!=null&&(S.current?.abort(),N(!0),x.request(()=>{Kl.flushSync(()=>{N(!1)}),L()}))},[f,g,L,x]),F(()=>{let M=v.current;if(!M)return;let X=Pe(M).createElement("div");for(let de of Array.from(M.childNodes))X.appendChild(de.cloneNode(!0));p.current=X});let I=g!=null,C;I?C=(0,Po.jsxs)(Ce.Fragment,{children:[(0,Po.jsx)("div",{"data-previous":!0,inert:Pl(!0),ref:w,style:{...E?{"--popup-width":`${E.width}px`,"--popup-height":`${E.height}px`}:null,position:"absolute"},"data-ending-style":P?void 0:""},"previous"),(0,Po.jsx)("div",{"data-current":!0,ref:v,"data-starting-style":P?"":void 0,children:n},f)]}):C=(0,Po.jsx)("div",{"data-current":!0,ref:v,children:n},f),F(()=>{let M=w.current;!M||!g||M.replaceChildren(...Array.from(g.childNodes))},[g]),Vl({popupElement:d,positionerElement:m,mounted:c,content:l,onMeasureLayout:H,onMeasureLayoutComplete:j,side:o,direction:r});let A={activationDirection:Vg(y),transitioning:I};return{children:C,state:A}}function Vg(e){if(e)return`${Gl(e.horizontal,5,"right","left")} ${Gl(e.vertical,5,"down","up")}`}function Gl(e,t,o,n){return e>t?o:e<-t?n:""}function Wg(e,t){let o=e.getBoundingClientRect(),n=t.getBoundingClientRect(),r={x:o.left+o.width/2,y:o.top+o.height/2},i={x:n.left+n.width/2,y:n.top+n.height/2};return{horizontal:i.x-r.x,vertical:i.y-r.y}}function Yg(e,t){let[o,n]=Ce.useState(0),r=Ce.useRef(e),i=Ce.useRef(t),s=Ce.useRef(!1);return F(()=>{let a=r.current,l=i.current,c=e!==a,d=t!==l;c?(n(m=>m+1),s.current=!d):s.current&&d&&(n(m=>m+1),s.current=!1),r.current=e,i.current=t},[e,t]),`${e??"current"}-${o}`}var sr=b(z(),1),Zl=b(Ht(),1);var Ql=b(W(),1),Jl=sr.forwardRef(function(t,o){let{children:n,container:r,className:i,render:s,style:a,...l}=t,{node:c,subtree:d}=bc({container:r,ref:o,componentProps:t,elementProps:l});return!d&&!c?null:(0,Ql.jsxs)(sr.Fragment,{children:[d,c&&Zl.createPortal(n,c)]})});var tt={};Mt(tt,{Arrow:()=>hd,Handle:()=>$o,Popup:()=>gd,Portal:()=>ud,Positioner:()=>pd,Provider:()=>vd,Root:()=>rd,Trigger:()=>cd,Viewport:()=>yd,createHandle:()=>xd});var Co=b(z(),1);var ar=b(z(),1),Li=ar.createContext(void 0);function et(e){let t=ar.useContext(Li);if(t===void 0&&!e)throw new Error(De(72));return t}var $l=b(z(),1);var ed={..._l,disabled:e=>e.disabled,instantType:e=>e.instantType,isInstantPhase:e=>e.isInstantPhase,trackCursorAxis:e=>e.trackCursorAxis,disableHoverablePopup:e=>e.disableHoverablePopup,lastOpenChangeReason:e=>e.openChangeReason,closeOnClick:e=>e.closeOnClick,closeDelay:e=>e.closeDelay,adaptiveOrigin:e=>e.adaptiveOrigin},cr=class extends Vt{constructor(t,o,n){let r=new io;super(od(t,r,o,n),nd(r),ed)}setOpen=(t,o)=>{dl(this,t,o,{extraState:{openChangeReason:o.reason}})};cancelPendingOpen(t){this.state.floatingRootContext.dispatchOpenChange(!1,ee(G.triggerPress,t))}};function td(){let e=new io,t=new er(Object.freeze(od(void 0,e)),Object.freeze(nd(e)),ed);return Object.assign(t,{setOpen:Ge,cancelPendingOpen:Ge})}function od(e,t,o,n=!1){let r={...hl(),disabled:!1,instantType:void 0,isInstantPhase:!1,trackCursorAxis:"none",disableHoverablePopup:!1,openChangeReason:null,closeOnClick:!0,closeDelay:0,adaptiveOrigin:void 0,...e};return r.floatingRootContext=wl(t,o,n),r}function nd(e){return{popupRef:$l.createRef(),onOpenChange:void 0,onOpenChangeComplete:void 0,triggerElements:e}}var Jo=b(W(),1),rd=vi(function(t){let{disabled:o=!1,defaultOpen:n=!1,open:r,disableHoverablePopup:i=!1,trackCursorAxis:s="none",actionsRef:a,onOpenChange:l,onOpenChangeComplete:c,handle:d,triggerId:m,defaultTriggerId:u=null,children:f}=t,p=cl((N,H)=>new cr({open:n,openProp:r,activeTriggerId:u,triggerIdProp:m},N,H));p.useControlledProp("openProp",r),p.useControlledProp("triggerIdProp",m),p.useContextCallback("onOpenChange",l),p.useContextCallback("onOpenChangeComplete",c);let g=p.useState("open"),h=!o&&g,y=p.useState("activeTriggerId"),_=p.useState("mounted"),v=p.useState("payload");p.useSyncedValues({trackCursorAxis:s,disableHoverablePopup:i,disabled:o}),fl(p,{closeOnActiveTriggerUnmount:!0});let{forceUnmount:w,transitionStatus:R}=pl(h,p),x=p.useState("isInstantPhase"),S=p.useState("instantType"),E=p.useState("lastOpenChangeReason"),T=Co.useRef(null);F(()=>{g&&o&&p.setOpen(!1,ee(G.disabled))},[g,o,p]),F(()=>{R==="ending"&&E===G.none||R!=="ending"&&x?(S!=="delay"&&(T.current=S),p.set("instantType","delay")):T.current!==null&&(p.set("instantType",T.current),T.current=null)},[R,x,E,S,p]),F(()=>{h&&y==null&&p.set("payload",void 0)},[p,y,h]),Co.useImperativeHandle(a,()=>({unmount:w,close:()=>p.setOpen(!1,ee(G.imperativeAction))}),[w,p]);let P=h||_||!o&&s!=="none";return(0,Jo.jsxs)(Li.Provider,{value:p,children:[d&&(0,Jo.jsx)(ll,{handle:d,store:p}),P&&(0,Jo.jsx)(Ug,{store:p,disabled:o,trackCursorAxis:s}),typeof f=="function"?f({payload:v}):f]})});function Ug({store:e,disabled:t,trackCursorAxis:o}){let n=e.useState("floatingRootContext"),r=si(n,{enabled:!t,referencePress:()=>e.select("closeOnClick")}),i=ii(n,{enabled:!t&&o!=="none",axis:o==="none"?void 0:o}),s=Co.useMemo(()=>ve(i.reference,r.reference),[i.reference,r.reference]);return ml(e,{activeTriggerProps:s,inactiveTriggerProps:s,popupProps:r.floating??me}),null}var dr=b(z(),1);var lr=b(z(),1),Mi=lr.createContext(void 0);function id(){return lr.useContext(Mi)}var ad="data-base-ui-tooltip-trigger";function sd(e){if("composedPath"in e){let o=e.composedPath();for(let n=0;nh.select("transitionStatus")==="ending",shouldOpen(){return!X.current}}),Q=Ri(w,{enabled:!I}).reference,q=ae=>{let ge=X.current,be=sd(ae),Ee=ie(be),ye=R.current,Kt=ye&&be&&re(ye,be);if(Ee&&h.select("open")&&h.select("lastOpenChangeReason")===G.triggerHover){h.setOpen(!1,ee(G.triggerHover,ae));return}if(ge&&!Ee&&Kt&&!C.current&&!h.select("open")&&ye&&Pt(O.current)){let rt=()=>{!X.current&&!C.current&&!h.select("open")&&h.setOpen(!0,ee(G.triggerHover,ae,ye))},ft=V();ft===0?(de.clear(),rt()):de.start(ft,rt)}},$=h.useState("triggerProps",T);return Oe("button",t,{state:{open:v},ref:[o,E,R],props:[K,Q,T||A!=="none"?$:void 0,{onMouseOver(ae){q(ae.nativeEvent)},onFocus(ae){Z(sd(ae.nativeEvent))&&ae.preventBaseUIHandler()},onMouseLeave(){X.current=!1,de.clear(),O.current=void 0},onPointerEnter(ae){O.current=ae.pointerType},onPointerDown(ae){O.current=ae.pointerType,h.set("closeOnClick",d),d&&!h.select("open")&&h.cancelPendingOpen(ae.nativeEvent)},onClick(ae){d&&!h.select("open")&&h.cancelPendingOpen(ae.nativeEvent)},id:y,"data-trigger-disabled":I?"":void 0,[ad]:I?void 0:""},f],stateAttributesMapping:Tl})});var dd=b(z(),1);var ur=b(z(),1),Bi=ur.createContext(void 0);function ld(){let e=ur.useContext(Bi);if(e===void 0)throw new Error(De(70));return e}var Hi=b(W(),1),ud=dd.forwardRef(function(t,o){let{keepMounted:n=!1,...r}=t;return et().useState("mounted")||n?(0,Hi.jsx)(Bi.Provider,{value:n,children:(0,Hi.jsx)(Jl,{ref:o,...r})}):null});var pr=b(z(),1);var fr=b(z(),1),zi=fr.createContext(void 0);function Ao(){let e=fr.useContext(zi);if(e===void 0)throw new Error(De(71));return e}var fd=b(W(),1),pd=pr.forwardRef(function(t,o){let{render:n,className:r,anchor:i,positionMethod:s="absolute",side:a="top",align:l="center",sideOffset:c=0,alignOffset:d=0,collisionBoundary:m="clipping-ancestors",collisionPadding:u=5,arrowPadding:f=5,sticky:p=!1,disableAnchorTracking:g=!1,collisionAvoidance:h=pc,style:y,..._}=t,v=et(),w=ld(),R=v.useState("open"),x=v.useState("mounted"),S=v.useState("trackCursorAxis"),E=v.useState("disableHoverablePopup"),T=v.useState("floatingRootContext"),P=v.useState("instantType"),N=v.useState("transitionStatus"),H=v.useState("adaptiveOrigin"),j=Bl({anchor:i,positionMethod:s,floatingRootContext:T,mounted:x,side:a,sideOffset:c,align:l,alignOffset:d,collisionBoundary:m,collisionPadding:u,sticky:p,arrowPadding:f,disableAnchorTracking:g,keepMounted:w,collisionAvoidance:h,adaptiveOrigin:H}),L=pr.useMemo(()=>({open:R,side:j.side,align:j.align,anchorHidden:j.anchorHidden,instant:S!=="none"?"tracking-cursor":P}),[R,j.side,j.align,j.anchorHidden,S,P]),k=Hl(t,L,{styles:j.positionerStyles,transitionStatus:N,props:_,refs:[o,v.useStateSetter("positionerElement")],hidden:!x,inert:!R||S==="both"||E});return(0,fd.jsx)(zi.Provider,{value:j,children:k})});var md=b(z(),1);var gd=md.forwardRef(function(t,o){let{render:n,className:r,style:i,...s}=t,a=et(),{side:l,align:c}=Ao(),d=a.useState("open"),m=a.useState("instantType"),u=a.useState("transitionStatus"),f=a.useState("popupProps"),p=a.useState("floatingRootContext"),g=a.useState("disabled"),h=a.useState("closeDelay");On({open:d,ref:a.context.popupRef,onComplete(){d&&a.context.onOpenChangeComplete?.(!0)}}),ki(p,{enabled:!g,closeDelay:h});let y=a.useStateSetter("popupElement");return Oe("div",t,{state:{open:d,side:l,align:c,instant:m,transitionStatus:u},ref:[o,a.context.popupRef,y],props:[al,f,or(u),s],stateAttributesMapping:kl})});var bd=b(z(),1);var hd=bd.forwardRef(function(t,o){let{render:n,className:r,style:i,...s}=t,a=et(),{arrowRef:l,side:c,align:d,arrowUncentered:m,arrowStyles:u}=Ao(),f=a.useState("open"),p=a.useState("instantType");return Oe("div",t,{state:{open:f,side:c,align:d,uncentered:m,instant:p},ref:[o,l],props:[{style:u,"aria-hidden":!0},s],stateAttributesMapping:Qo})});var wd=b(z(),1);var Di=b(W(),1),vd=function(t){let{delay:o,closeDelay:n,timeout:r=400}=t,i=wd.useMemo(()=>({open:o,close:n}),[o,n]);return(0,Di.jsx)(Mi.Provider,{value:o,children:(0,Di.jsx)(ni,{delay:i,timeoutMs:r,children:t.children})})};var _d=b(z(),1);var yd=_d.forwardRef(function(t,o){let{render:n,className:r,style:i,children:s,...a}=t,l=et(),c=Ao(),d=l.useState("instantType"),{children:m,state:u}=ql({store:l,side:c.side,children:s}),f={activationDirection:u.activationDirection,transitioning:u.transitioning,instant:d};return Oe("div",t,{state:f,ref:o,props:[a,{children:m}],stateAttributesMapping:Xl})});var $o=class extends Yn{constructor(){super(td(),"Tooltip")}open(t){this.openByTrigger(t)}close(){this.closePopup()}get isOpen(){return this.attachedStore?.select("open")??!1}};function xd(){return new $o}function ot(e){return Oe(e.defaultTagName??"div",e,e)}var Ed=b(ce(),1),ji="data-wp-hash";function Fi(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&qg(document)),e.__wpStyleRuntime}function Xg(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${ji}]`))if(o.getAttribute(ji)===t)return!0;return!1}function Td(e,t,o){if(!e.head)return;let n=Fi(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Xg(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(ji,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function qg(e){let t=Fi();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Td(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function kd(e,t){let o=Fi();o.styles.set(e,t);for(let n of o.documents.keys())Td(n,e,t)}typeof process>"u",kd("a495f9d138",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._83ed8a8da5dd50ea__text{margin:0}._14437cfb77831647__heading-2xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-2xl,32px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-2xl,32px);--_gcd-p-line-height:var(--wpds-typography-line-height-2xl,40px);font-size:var(--wpds-typography-font-size-2xl,32px);line-height:var(--wpds-typography-line-height-2xl,40px)}._14437cfb77831647__heading-2xl,._3c78b7fa9b4072dd__heading-xl{font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-emphasis,600)}._3c78b7fa9b4072dd__heading-xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-p-line-height:var(--wpds-typography-line-height-md,24px);font-size:var(--wpds-typography-font-size-xl,20px);line-height:var(--wpds-typography-line-height-md,24px)}.aa58f227716bcde2__heading-lg{--_gcd-heading-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-lg,15px)}.aa58f227716bcde2__heading-lg,.fc4da56d8dfe52c4__heading-md{font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:var(--wpds-typography-line-height-sm,20px)}.fc4da56d8dfe52c4__heading-md{--_gcd-heading-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-md,13px)}.a9b78c7c82e8dff7__heading-sm{--_gcd-heading-font-size:var(--wpds-typography-font-size-xs,11px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-xs,11px);--_gcd-p-line-height:var(--wpds-typography-line-height-xs,16px);font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-xs,11px);font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:var(--wpds-typography-line-height-xs,16px);text-transform:uppercase}._305ff559e52180d5__body-xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-p-line-height:var(--wpds-typography-line-height-xl,32px);font-size:var(--wpds-typography-font-size-xl,20px);line-height:var(--wpds-typography-line-height-xl,32px)}._305ff559e52180d5__body-xl,.ca1aa3fc2029e958__body-lg{font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-default,400)}.ca1aa3fc2029e958__body-lg{--_gcd-heading-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-p-line-height:var(--wpds-typography-line-height-md,24px);font-size:var(--wpds-typography-font-size-lg,15px);line-height:var(--wpds-typography-line-height-md,24px)}._131101940be12424__body-md{--_gcd-heading-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-md,13px);line-height:var(--wpds-typography-line-height-sm,20px)}._0e8d87a42c1f75fa__body-sm,._131101940be12424__body-md{font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-default,400)}._0e8d87a42c1f75fa__body-sm{--_gcd-heading-font-size:var(--wpds-typography-font-size-sm,12px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-sm,12px);--_gcd-p-line-height:var(--wpds-typography-line-height-xs,16px);font-size:var(--wpds-typography-font-size-sm,12px);line-height:var(--wpds-typography-line-height-xs,16px)}}}');var Sd={text:"_83ed8a8da5dd50ea__text","heading-2xl":"_14437cfb77831647__heading-2xl","heading-xl":"_3c78b7fa9b4072dd__heading-xl","heading-lg":"aa58f227716bcde2__heading-lg","heading-md":"fc4da56d8dfe52c4__heading-md","heading-sm":"a9b78c7c82e8dff7__heading-sm","body-xl":"_305ff559e52180d5__body-xl","body-lg":"ca1aa3fc2029e958__body-lg","body-md":"_131101940be12424__body-md","body-sm":"_0e8d87a42c1f75fa__body-sm"};typeof process>"u",kd("af6d9984a6","._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}");var Rd={button:"_6defc79820e382c6__button",input:"d2cff2e5dea83bd1__input",textarea:"_547d86373d02e108__textarea",div:"_8c15fd0ed9f28ba4__div",p:"_43cec3e1eec1066d__p",heading:"e97669c6d9a38497__heading",a:"_2c0831b0499dbd6e__a"},We=(0,Ed.forwardRef)(function({variant:t="body-md",render:o,className:n,...r},i){return ot({render:o,defaultTagName:"span",ref:i,props:ve(r,{className:J(Sd.text,Rd.heading,Rd.p,Sd[t],n)})})});var Od=b(W(),1),Vi="data-wp-hash";function Wi(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Qg(document)),e.__wpStyleRuntime}function Zg(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Vi}]`))if(o.getAttribute(Vi)===t)return!0;return!1}function Ad(e,t,o){if(!e.head)return;let n=Wi(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Zg(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Vi,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Qg(e){let t=Wi();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Ad(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Jg(e,t){let o=Wi();o.styles.set(e,t);for(let n of o.documents.keys())Ad(n,e,t)}typeof process>"u",Jg("9db2873e7f","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._96e6251aad1a6136__badge{border-radius:var(--wpds-border-radius-lg,8px);padding-block:var(--wpds-dimension-padding-xs,4px);padding-inline:var(--wpds-dimension-padding-sm,8px)}._99f7158cb520f750__is-high-intent{background-color:var(--wpds-color-background-surface-error,#f6e6e3);color:var(--wpds-color-foreground-content-error,#470000)}.c20ebef2365bc8b7__is-medium-intent{background-color:var(--wpds-color-background-surface-warning,#fde6be);color:var(--wpds-color-foreground-content-warning,#2e1900)}._365e1626c6202e52__is-low-intent{background-color:var(--wpds-color-background-surface-caution,#fee995);color:var(--wpds-color-foreground-content-caution,#281d00)}._33f8198127ddf4ef__is-stable-intent{background-color:var(--wpds-color-background-surface-success,#c6f7cd);color:var(--wpds-color-foreground-content-success,#002900)}._04c1aca8fc449412__is-informational-intent{background-color:var(--wpds-color-background-surface-info,#deebfa);color:var(--wpds-color-foreground-content-info,#001b4f)}._90726e69d495ec19__is-draft-intent{background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);color:var(--wpds-color-foreground-content-neutral,#1e1e1e)}._898f4a544993bd39__is-none-intent{background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);padding-block:calc(var(--wpds-dimension-padding-xs, 4px) - var(--wpds-border-width-xs, 1px));padding-inline:calc(var(--wpds-dimension-padding-sm, 8px) - var(--wpds-border-width-xs, 1px))}}}");var Pd={badge:"_96e6251aad1a6136__badge","is-high-intent":"_99f7158cb520f750__is-high-intent","is-medium-intent":"c20ebef2365bc8b7__is-medium-intent","is-low-intent":"_365e1626c6202e52__is-low-intent","is-stable-intent":"_33f8198127ddf4ef__is-stable-intent","is-informational-intent":"_04c1aca8fc449412__is-informational-intent","is-draft-intent":"_90726e69d495ec19__is-draft-intent","is-none-intent":"_898f4a544993bd39__is-none-intent"},Yi=(0,Cd.forwardRef)(function({intent:t="none",className:o,...n},r){return(0,Od.jsx)(We,{ref:r,className:J(Pd.badge,Pd[`is-${t}-intent`],o),...n,variant:"body-sm"})});var mr=b(ce(),1),Nd=b(st(),1),Ld=b(W(),1);import{speak as $g}from"@wordpress/a11y";var Ui="data-wp-hash";function Gi(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&tb(document)),e.__wpStyleRuntime}function eb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Ui}]`))if(o.getAttribute(Ui)===t)return!0;return!1}function Id(e,t,o){if(!e.head)return;let n=Gi(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(eb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Ui,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function tb(e){let t=Gi();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Id(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function gr(e,t){let o=Gi();o.styles.set(e,t);for(let n of o.documents.keys())Id(n,e,t)}typeof process>"u",gr("effc4e3032",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._97b0fc33c028be1a__button,.abbb272e2ce49bd6__is-unstyled{appearance:none;padding:0}._97b0fc33c028be1a__button{--wp-ui-button-font-weight:var(--wpds-typography-font-weight-emphasis,600);--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-strong,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-strong-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 93%,#000));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand-strong,#fff);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-strong-active,#fff);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-strong-disabled,#8d8d8d);--wp-ui-button-padding-block:var(--wpds-dimension-padding-xs,4px);--wp-ui-button-padding-inline:var(--wpds-dimension-padding-md,12px);--wp-ui-button-height:var(--wpds-dimension-size-lg,40px);--wp-ui-button-aspect-ratio:auto;--wp-ui-button-font-size:var(--wpds-typography-font-size-md,13px);--wp-ui-button-min-width:calc(4ch + var(--wp-ui-button-padding-inline)*2);--wp-ui-button-icon-margin:calc((var(--wpds-dimension-size-2xs, 16px) - var(--wpds-dimension-size-sm, 24px))/2);--wp-ui-button-border-color:var(--wp-ui-button-background-color);--wp-ui-button-border-color-active:var(--wp-ui-button-background-color-active);--wp-ui-button-border-color-disabled:var(--wp-ui-button-background-color-disabled);--_gcd-button-font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);--_gcd-button-font-size:var(--wp-ui-button-font-size);--_gcd-button-font-weight:var(--wp-ui-button-font-weight);align-items:center;aspect-ratio:var(--wp-ui-button-aspect-ratio);background-clip:border-box;background-color:var(--wp-ui-button-background-color);border-color:var(--wp-ui-button-border-color);border-radius:var(--wpds-border-radius-sm,2px);border-style:solid;border-width:1px;color:var(--wp-ui-button-foreground-color);display:inline-flex;font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wp-ui-button-font-size);font-weight:var(--wp-ui-button-font-weight);gap:var(--wpds-dimension-gap-sm,8px);justify-content:center;line-height:var(--wpds-typography-line-height-sm,20px);max-width:100%;min-height:var(--wp-ui-button-height);min-width:var(--wp-ui-button-min-width);overflow-wrap:anywhere;padding-block:var(--wp-ui-button-padding-block);padding-inline:var(--wp-ui-button-padding-inline);position:relative;text-align:center;text-decoration:none;&:not([data-disabled]){cursor:var(--wpds-cursor-control,pointer)}@media not (prefers-reduced-motion){transition:color .1s ease-out;*{transition:opacity .1s ease-out}}&[href]{cursor:pointer}[href]{color:inherit;text-decoration:inherit}&:not([data-disabled]):is(:hover,:active,:focus){background-color:var(--wp-ui-button-background-color-active);border-color:var(--wp-ui-button-border-color-active);color:var(--wp-ui-button-foreground-color-active)}&[data-disabled]:not(._914b42f315c0e580__is-loading){background-color:var(--wp-ui-button-background-color-disabled);border-color:var(--wp-ui-button-border-color-disabled);color:var(--wp-ui-button-foreground-color-disabled);@media (forced-colors:active){border-bottom-color:GrayText;border-left-color:GrayText;border-right-color:GrayText;border-top-color:GrayText;color:GrayText}}&:before{aspect-ratio:1;border:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid;border-block-end-color:transparent;border-block-start-color:var(--wp-ui-button-foreground-color);border-inline-end-color:var(--wp-ui-button-foreground-color);border-inline-start-color:transparent;border-radius:50%;box-sizing:border-box;content:"";display:block;height:var(--wp-ui-button-font-size);left:50%;opacity:0;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);@media not (prefers-reduced-motion){transition:opacity .1s ease-out}@media (forced-colors:active){border-block-end-style:none;border-bottom-color:ButtonText;border-inline-start-style:none;border-left-color:ButtonText;border-right-color:ButtonText;border-top-color:ButtonText}}}._908205475f9f2a92__is-small{--wp-ui-button-padding-block:0px;--wp-ui-button-padding-inline:var(--wpds-dimension-padding-sm,8px);--wp-ui-button-height:var(--wpds-dimension-size-sm,24px)}._9f6fc6553aeb36fe__icon{margin:var(--wp-ui-button-icon-margin)}.dd460c965226cc77__is-brand{&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 85%,#000));--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-brand-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000)}}.e722a8f96726aa99__is-neutral{&.ad0619a3217c6a5b__is-minimal[aria-pressed=true],&.b50b3358c5fb4d0b__is-solid{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-strong,#2d2d2d);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-strong-active,#1e1e1e);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral-strong,#f0f0f0);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-strong-active,#f0f0f0);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-strong-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d);--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-neutral-active,#6e6e6e);--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-neutral-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000)}}.abbb272e2ce49bd6__is-unstyled{background:none;border:none;min-width:unset}.cf59cf1b69629838__is-compact{--wp-ui-button-height:var(--wpds-dimension-size-md,32px)}._914b42f315c0e580__is-loading:not(.abbb272e2ce49bd6__is-unstyled){color:transparent;&:not([data-disabled]):is(:hover,:active,:focus){color:transparent}@media (forced-colors:active){color:ButtonFace}*{opacity:0}&:before{opacity:1;transition-delay:.05s;@media not (prefers-reduced-motion){animation:_5a1d53da6f830c8d__loading-animation 1s linear infinite}}}}@keyframes _5a1d53da6f830c8d__loading-animation{0%{transform:translate(-50%,-50%) rotate(0deg)}to{transform:translate(-50%,-50%) rotate(1turn)}}}');var en={button:"_97b0fc33c028be1a__button","is-unstyled":"abbb272e2ce49bd6__is-unstyled","is-loading":"_914b42f315c0e580__is-loading","is-small":"_908205475f9f2a92__is-small",icon:"_9f6fc6553aeb36fe__icon","is-brand":"dd460c965226cc77__is-brand","is-outline":"_62d5a778b7b258ee__is-outline","is-minimal":"ad0619a3217c6a5b__is-minimal","is-neutral":"e722a8f96726aa99__is-neutral","is-solid":"b50b3358c5fb4d0b__is-solid","is-compact":"cf59cf1b69629838__is-compact","loading-animation":"_5a1d53da6f830c8d__loading-animation"};typeof process>"u",gr("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var ob={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",gr("96553466c8","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._64de9947bf305b7a__outset-ring--focus-within-visible:focus-within:has(:focus-visible),.af79fb116edb0dd7__outset-ring--focus:focus,.dfcfdc28396e5d98__outset-ring--focus-visible:focus-visible,.e5cd9ee879f6403a__outset-ring--focus-within:focus-within,:focus-visible ._81935a08e952f267__outset-ring--focus-parent-visible{--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within,.abc777e9713fa711__outset-ring--focus-except-active:focus{outline:none}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within:not(:has(:active)),.abc777e9713fa711__outset-ring--focus-except-active:focus:not(:active){--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}}}");var nb={"outset-ring--focus":"af79fb116edb0dd7__outset-ring--focus","outset-ring--focus-visible":"dfcfdc28396e5d98__outset-ring--focus-visible","outset-ring--focus-within":"e5cd9ee879f6403a__outset-ring--focus-within","outset-ring--focus-within-visible":"_64de9947bf305b7a__outset-ring--focus-within-visible","outset-ring--focus-parent-visible":"_81935a08e952f267__outset-ring--focus-parent-visible","outset-ring--focus-except-active":"abc777e9713fa711__outset-ring--focus-except-active","outset-ring--focus-within-except-active":"_3c9f5ee9fc9c136d__outset-ring--focus-within-except-active"};typeof process>"u",gr("af6d9984a6","._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}");var rb={button:"_6defc79820e382c6__button",input:"d2cff2e5dea83bd1__input",textarea:"_547d86373d02e108__textarea",div:"_8c15fd0ed9f28ba4__div",p:"_43cec3e1eec1066d__p",heading:"e97669c6d9a38497__heading",a:"_2c0831b0499dbd6e__a"},Md=(0,mr.forwardRef)(function({tone:t="brand",variant:o="solid",size:n="default",className:r,focusableWhenDisabled:i=!0,disabled:s,loading:a,loadingAnnouncement:l=(0,Nd.__)("Loading"),children:c,...d},m){let u=J(rb.button,ob["box-sizing"],nb["outset-ring--focus-except-active"],o!=="unstyled"&&en.button,en[`is-${t}`],en[`is-${o}`],en[`is-${n}`],a&&en["is-loading"],r);return(0,mr.useEffect)(()=>{a&&l&&$g(l)},[a,l]),(0,Ld.jsx)(Oi,{ref:m,className:u,focusableWhenDisabled:i,disabled:s??a,...d,children:c})});var jd=b(ce(),1);var Hd=b(ce(),1),zd=b(so(),1),Dd=b(W(),1),ao=(0,Hd.forwardRef)(function({icon:t,size:o=24,...n},r){return(0,Dd.jsx)(zd.SVG,{ref:r,...t.props,...n,width:o,height:o})});var Vd=b(W(),1),Ki="data-wp-hash";function Xi(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&sb(document)),e.__wpStyleRuntime}function ib(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Ki}]`))if(o.getAttribute(Ki)===t)return!0;return!1}function Fd(e,t,o){if(!e.head)return;let n=Xi(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(ib(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Ki,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function sb(e){let t=Xi();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Fd(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function ab(e,t){let o=Xi();o.styles.set(e,t);for(let n of o.documents.keys())Fd(n,e,t)}typeof process>"u",ab("effc4e3032",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._97b0fc33c028be1a__button,.abbb272e2ce49bd6__is-unstyled{appearance:none;padding:0}._97b0fc33c028be1a__button{--wp-ui-button-font-weight:var(--wpds-typography-font-weight-emphasis,600);--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-strong,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-strong-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 93%,#000));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand-strong,#fff);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-strong-active,#fff);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-strong-disabled,#8d8d8d);--wp-ui-button-padding-block:var(--wpds-dimension-padding-xs,4px);--wp-ui-button-padding-inline:var(--wpds-dimension-padding-md,12px);--wp-ui-button-height:var(--wpds-dimension-size-lg,40px);--wp-ui-button-aspect-ratio:auto;--wp-ui-button-font-size:var(--wpds-typography-font-size-md,13px);--wp-ui-button-min-width:calc(4ch + var(--wp-ui-button-padding-inline)*2);--wp-ui-button-icon-margin:calc((var(--wpds-dimension-size-2xs, 16px) - var(--wpds-dimension-size-sm, 24px))/2);--wp-ui-button-border-color:var(--wp-ui-button-background-color);--wp-ui-button-border-color-active:var(--wp-ui-button-background-color-active);--wp-ui-button-border-color-disabled:var(--wp-ui-button-background-color-disabled);--_gcd-button-font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);--_gcd-button-font-size:var(--wp-ui-button-font-size);--_gcd-button-font-weight:var(--wp-ui-button-font-weight);align-items:center;aspect-ratio:var(--wp-ui-button-aspect-ratio);background-clip:border-box;background-color:var(--wp-ui-button-background-color);border-color:var(--wp-ui-button-border-color);border-radius:var(--wpds-border-radius-sm,2px);border-style:solid;border-width:1px;color:var(--wp-ui-button-foreground-color);display:inline-flex;font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wp-ui-button-font-size);font-weight:var(--wp-ui-button-font-weight);gap:var(--wpds-dimension-gap-sm,8px);justify-content:center;line-height:var(--wpds-typography-line-height-sm,20px);max-width:100%;min-height:var(--wp-ui-button-height);min-width:var(--wp-ui-button-min-width);overflow-wrap:anywhere;padding-block:var(--wp-ui-button-padding-block);padding-inline:var(--wp-ui-button-padding-inline);position:relative;text-align:center;text-decoration:none;&:not([data-disabled]){cursor:var(--wpds-cursor-control,pointer)}@media not (prefers-reduced-motion){transition:color .1s ease-out;*{transition:opacity .1s ease-out}}&[href]{cursor:pointer}[href]{color:inherit;text-decoration:inherit}&:not([data-disabled]):is(:hover,:active,:focus){background-color:var(--wp-ui-button-background-color-active);border-color:var(--wp-ui-button-border-color-active);color:var(--wp-ui-button-foreground-color-active)}&[data-disabled]:not(._914b42f315c0e580__is-loading){background-color:var(--wp-ui-button-background-color-disabled);border-color:var(--wp-ui-button-border-color-disabled);color:var(--wp-ui-button-foreground-color-disabled);@media (forced-colors:active){border-bottom-color:GrayText;border-left-color:GrayText;border-right-color:GrayText;border-top-color:GrayText;color:GrayText}}&:before{aspect-ratio:1;border:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid;border-block-end-color:transparent;border-block-start-color:var(--wp-ui-button-foreground-color);border-inline-end-color:var(--wp-ui-button-foreground-color);border-inline-start-color:transparent;border-radius:50%;box-sizing:border-box;content:"";display:block;height:var(--wp-ui-button-font-size);left:50%;opacity:0;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);@media not (prefers-reduced-motion){transition:opacity .1s ease-out}@media (forced-colors:active){border-block-end-style:none;border-bottom-color:ButtonText;border-inline-start-style:none;border-left-color:ButtonText;border-right-color:ButtonText;border-top-color:ButtonText}}}._908205475f9f2a92__is-small{--wp-ui-button-padding-block:0px;--wp-ui-button-padding-inline:var(--wpds-dimension-padding-sm,8px);--wp-ui-button-height:var(--wpds-dimension-size-sm,24px)}._9f6fc6553aeb36fe__icon{margin:var(--wp-ui-button-icon-margin)}.dd460c965226cc77__is-brand{&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 85%,#000));--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-brand-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000)}}.e722a8f96726aa99__is-neutral{&.ad0619a3217c6a5b__is-minimal[aria-pressed=true],&.b50b3358c5fb4d0b__is-solid{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-strong,#2d2d2d);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-strong-active,#1e1e1e);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral-strong,#f0f0f0);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-strong-active,#f0f0f0);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-strong-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d);--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-neutral-active,#6e6e6e);--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-neutral-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000)}}.abbb272e2ce49bd6__is-unstyled{background:none;border:none;min-width:unset}.cf59cf1b69629838__is-compact{--wp-ui-button-height:var(--wpds-dimension-size-md,32px)}._914b42f315c0e580__is-loading:not(.abbb272e2ce49bd6__is-unstyled){color:transparent;&:not([data-disabled]):is(:hover,:active,:focus){color:transparent}@media (forced-colors:active){color:ButtonFace}*{opacity:0}&:before{opacity:1;transition-delay:.05s;@media not (prefers-reduced-motion){animation:_5a1d53da6f830c8d__loading-animation 1s linear infinite}}}}@keyframes _5a1d53da6f830c8d__loading-animation{0%{transform:translate(-50%,-50%) rotate(0deg)}to{transform:translate(-50%,-50%) rotate(1turn)}}}');var cb={button:"_97b0fc33c028be1a__button","is-unstyled":"abbb272e2ce49bd6__is-unstyled","is-loading":"_914b42f315c0e580__is-loading","is-small":"_908205475f9f2a92__is-small",icon:"_9f6fc6553aeb36fe__icon","is-brand":"dd460c965226cc77__is-brand","is-outline":"_62d5a778b7b258ee__is-outline","is-minimal":"ad0619a3217c6a5b__is-minimal","is-neutral":"e722a8f96726aa99__is-neutral","is-solid":"b50b3358c5fb4d0b__is-solid","is-compact":"cf59cf1b69629838__is-compact","loading-animation":"_5a1d53da6f830c8d__loading-animation"},qi=(0,jd.forwardRef)(function({className:t,icon:o,...n},r){return(0,Vd.jsx)(ao,{ref:r,icon:o,className:J(cb.icon,t),size:24,...n})});qi.displayName="Button.Icon";var br=Object.assign(Md,{Icon:qi});var hr=b(so(),1),Zi=b(W(),1),Qi=(0,Zi.jsx)(hr.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,Zi.jsx)(hr.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M5.5 12a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0ZM12 4a8 8 0 1 0 0 16 8 8 0 0 0 0-16Zm-.75 12v-1.5h1.5V16h-1.5Zm0-8v5h1.5V8h-1.5Z"})});var wr=b(so(),1),Ji=b(W(),1),$i=(0,Ji.jsx)(wr.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,Ji.jsx)(wr.Path,{d:"M12 13.06l3.712 3.713 1.061-1.06L13.061 12l3.712-3.712-1.06-1.06L12 10.938 8.288 7.227l-1.061 1.06L10.939 12l-3.712 3.712 1.06 1.061L12 13.061z"})});var vr=b(so(),1),es=b(W(),1),ts=(0,es.jsx)(vr.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,es.jsx)(vr.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M12.218 5.377a.25.25 0 0 0-.436 0l-7.29 12.96a.25.25 0 0 0 .218.373h14.58a.25.25 0 0 0 .218-.372l-7.29-12.96Zm-1.743-.735c.669-1.19 2.381-1.19 3.05 0l7.29 12.96a1.75 1.75 0 0 1-1.525 2.608H4.71a1.75 1.75 0 0 1-1.525-2.608l7.29-12.96ZM12.75 17.46h-1.5v-1.5h1.5v1.5Zm-1.5-3h1.5v-5h-1.5v5Z"})});var _r=b(so(),1),os=b(W(),1),ns=(0,os.jsx)(_r.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,os.jsx)(_r.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M5.5 12a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0ZM12 4a8 8 0 1 0 0 16 8 8 0 0 0 0-16Zm.75 4v1.5h-1.5V8h1.5Zm0 8v-5h-1.5v5h1.5Z"})});var yr=b(so(),1),rs=b(W(),1),is=(0,rs.jsx)(yr.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,rs.jsx)(yr.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M12 18.5a6.5 6.5 0 1 1 0-13 6.5 6.5 0 0 1 0 13ZM4 12a8 8 0 1 1 16 0 8 8 0 0 1-16 0Zm11.53-1.47-1.06-1.06L11 12.94l-1.47-1.47-1.06 1.06L11 15.06l4.53-4.53Z"})});var yu=b(ce(),1);var cu=b(ce(),1);var Kd=b(ce(),1);var as="data-wp-hash";function cs(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&db(document)),e.__wpStyleRuntime}function lb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${as}]`))if(o.getAttribute(as)===t)return!0;return!1}function Yd(e,t,o){if(!e.head)return;let n=cs(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(lb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(as,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function db(e){let t=cs();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Yd(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function ub(e,t){let o=cs();o.styles.set(e,t);for(let n of o.documents.keys())Yd(n,e,t)}typeof process>"u",ub("be37f31c1e","._11fc52b637ff8a7e__slot{inset:0;isolation:isolate;pointer-events:none;position:fixed;z-index:1000000003}@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._11fc52b637ff8a7e__slot>*{pointer-events:auto}}}");var Wd={slot:"_11fc52b637ff8a7e__slot"},Ud="data-wp-compat-overlay-slot";function fb(){return typeof document>"u"?null:document}function pb(){let e;try{e=window.top?.wp}catch{}let t=e??window.wp;return typeof t?.components=="object"&&t.components!==null}var xt=null;function ss(e){return e.setAttribute("aria-hidden","false"),e}function mb(e){let t=e.createElement("div");return t.setAttribute(Ud,""),Wd.slot&&t.classList.add(Wd.slot),e.body.appendChild(t),t}function Gd(){if(typeof window>"u"||!pb()&&window.__wpUiCompatOverlaySlotEnabled!==!0)return;let e=fb();if(!e||!e.body)return;if(xt&&xt.ownerDocument===e&&xt.isConnected)return ss(xt);let t=e.querySelector(`[${Ud}]`);return t instanceof HTMLDivElement?(xt=ss(t),xt):(xt?.isConnected&&xt.remove(),xt=ss(mb(e)),xt)}var Xd=b(W(),1),qd=(0,Kd.forwardRef)(function({container:t,...o},n){return(0,Xd.jsx)(tt.Portal,{container:t??Gd(),...o,ref:n})});var Zd=b(ce(),1),$d=b(W(),1),ls="data-wp-hash";function ds(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&bb(document)),e.__wpStyleRuntime}function gb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${ls}]`))if(o.getAttribute(ls)===t)return!0;return!1}function Qd(e,t,o){if(!e.head)return;let n=ds(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(gb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(ls,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function bb(e){let t=ds();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Qd(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Jd(e,t){let o=ds();o.styles.set(e,t);for(let n of o.documents.keys())Qd(n,e,t)}typeof process>"u",Jd("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var hb={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",Jd("19fcc06039",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}');var wb={positioner:"_480b748dd3510e64__positioner",popup:"_50096b232db7709d__popup"},eu=(0,Zd.forwardRef)(function({align:t="center",className:o,side:n="top",sideOffset:r=4,...i},s){return(0,$d.jsx)(tt.Positioner,{ref:s,align:t,side:n,sideOffset:r,...i,className:J(hb["box-sizing"],wb.positioner,o)})});var tu=b(ce(),1);function us(e,t,o){return(0,tu.cloneElement)(e??t,{children:o})}var vb=b(nu(),1);var iu=b(fs(),1),{lock:s3,unlock:su}=(0,iu.__dangerousOptInToUnstableAPIsOnlyForCoreModules)("I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.","@wordpress/ui");function _b(){let e=vb;if(e.ThemeProvider)return e.ThemeProvider;if(!e.privateApis)throw new Error("@wordpress/ui: @wordpress/theme must expose `ThemeProvider` or `privateApis.ThemeProvider`.");return su(e.privateApis).ThemeProvider}var au=_b();var tn=b(W(),1),ps="data-wp-hash";function ms(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&xb(document)),e.__wpStyleRuntime}function yb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${ps}]`))if(o.getAttribute(ps)===t)return!0;return!1}function lu(e,t,o){if(!e.head)return;let n=ms(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(yb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(ps,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function xb(e){let t=ms();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)lu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Sb(e,t){let o=ms();o.styles.set(e,t);for(let n of o.documents.keys())lu(n,e,t)}typeof process>"u",Sb("19fcc06039",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}');var Rb={positioner:"_480b748dd3510e64__positioner",popup:"_50096b232db7709d__popup"},Eb={background:"#1e1e1e"},gs=(0,cu.forwardRef)(function({portal:t,positioner:o,children:n,className:r,...i},s){let a=(0,tn.jsx)(au,{color:Eb,children:(0,tn.jsx)(tt.Popup,{ref:s,className:J(Rb.popup,r),...i,children:n})}),l=us(o,(0,tn.jsx)(eu,{}),a);return us(t,(0,tn.jsx)(qd,{}),l)});var du=b(ce(),1),uu=b(W(),1),bs=(0,du.forwardRef)(function(t,o){return(0,uu.jsx)(tt.Trigger,{ref:o,...t})});var fu=b(st(),1),pu=b(W(),1);function mu({children:e}){return(0,pu.jsx)(ir,{direction:(0,fu.isRTL)()?"rtl":"ltr",children:e})}var hs=b(W(),1);function ws(e){return(0,hs.jsx)(mu,{children:(0,hs.jsx)(tt.Root,{...e})})}var on=b(ce(),1),Sr=b(st(),1);var gu=b(ce(),1),vs="data-wp-hash";function _s(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Pb(document)),e.__wpStyleRuntime}function kb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${vs}]`))if(o.getAttribute(vs)===t)return!0;return!1}function bu(e,t,o){if(!e.head)return;let n=_s(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(kb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(vs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Pb(e){let t=_s();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)bu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Cb(e,t){let o=_s();o.styles.set(e,t);for(let n of o.documents.keys())bu(n,e,t)}typeof process>"u",Cb("fa606a57ae","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.f37b9e2e191ebd66__visually-hidden{word-wrap:normal;border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-break:normal}}}");var Ab={"visually-hidden":"f37b9e2e191ebd66__visually-hidden"},ys=(0,gu.forwardRef)(function({render:t,...o},n){return ot({render:t,ref:n,props:ve({className:Ab["visually-hidden"]},o,{"data-visually-hidden":""})})});var xr=b(W(),1);function hu({"aria-describedby":e,"aria-keyshortcuts":t,shortcut:o}){let n=(0,on.useId)(),r=o?n:void 0,i=[e,r].filter(Boolean).join(" ");return{descriptionId:r,targetProps:{"aria-describedby":i||void 0,"aria-keyshortcuts":o?.ariaKeyShortcut??t}}}var wu=(0,on.forwardRef)(function({descriptionId:t,shortcut:o},n){return(0,xr.jsx)(ys,{id:t,"aria-hidden":"true",render:(0,xr.jsx)("span",{ref:n}),children:(0,Sr.sprintf)((0,Sr.__)("Keyboard shortcut: %s"),o.label??o.ariaKeyShortcut)})}),vu=(0,on.forwardRef)(function({className:t,shortcut:o},n){return(0,xr.jsx)("span",{ref:n,"aria-hidden":"true",className:t,dir:"ltr",children:o.displayShortcut})});var nt=b(W(),1),xs="data-wp-hash";function Ss(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Nb(document)),e.__wpStyleRuntime}function Ob(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${xs}]`))if(o.getAttribute(xs)===t)return!0;return!1}function xu(e,t,o){if(!e.head)return;let n=Ss(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Ob(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(xs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Nb(e){let t=Ss();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)xu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Ib(e,t){let o=Ss();o.styles.set(e,t);for(let n of o.documents.keys())xu(n,e,t)}typeof process>"u",Ib("c5cdafb1bc","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer compositions{._28cfdc260e755391__icon-button{--wp-ui-button-aspect-ratio:1;--wp-ui-button-padding-inline:0px;--wp-ui-button-min-width:unset}.f1c70d719989a85a__icon{margin:-1px}}}");var _u={"icon-button":"_28cfdc260e755391__icon-button",icon:"f1c70d719989a85a__icon"},Rs=(0,yu.forwardRef)(function({label:t,className:o,children:n,disabled:r,focusableWhenDisabled:i=!0,icon:s,size:a,shortcut:l,positioner:c,"aria-describedby":d,"aria-keyshortcuts":m,...u},f){let p=J(_u["icon-button"],o),{descriptionId:g,targetProps:h}=hu({"aria-describedby":d,"aria-keyshortcuts":m,shortcut:l});return(0,nt.jsxs)(ws,{children:[(0,nt.jsxs)(bs,{ref:f,...h,disabled:r&&!i,render:(0,nt.jsx)(br,{...u,size:a,"aria-label":t,disabled:r,focusableWhenDisabled:i}),className:p,children:[(0,nt.jsx)(ao,{icon:s,size:24,className:_u.icon}),l&&g&&(0,nt.jsx)(wu,{descriptionId:g,shortcut:l})]}),(0,nt.jsxs)(gs,{positioner:c,children:[t,l&&(0,nt.jsxs)(nt.Fragment,{children:[" ",(0,nt.jsx)(vu,{shortcut:l})]})]})]})});var Su=b(ce(),1),Es="data-wp-hash";function Ts(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Mb(document)),e.__wpStyleRuntime}function Lb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Es}]`))if(o.getAttribute(Es)===t)return!0;return!1}function Ru(e,t,o){if(!e.head)return;let n=Ts(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Lb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Es,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Mb(e){let t=Ts();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Ru(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Bb(e,t){let o=Ts();o.styles.set(e,t);for(let n of o.documents.keys())Ru(n,e,t)}typeof process>"u",Bb("32aba35fe1","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._19ce0419607e1896__stack{display:flex}}}");var Hb={stack:"_19ce0419607e1896__stack"},zb={xs:"var(--wpds-dimension-gap-xs, 4px)",sm:"var(--wpds-dimension-gap-sm, 8px)",md:"var(--wpds-dimension-gap-md, 12px)",lg:"var(--wpds-dimension-gap-lg, 16px)",xl:"var(--wpds-dimension-gap-xl, 24px)","2xl":"var(--wpds-dimension-gap-2xl, 32px)","3xl":"var(--wpds-dimension-gap-3xl, 40px)"},Ut=(0,Su.forwardRef)(function({direction:t,gap:o,align:n,justify:r,wrap:i,render:s,...a},l){let c={gap:o&&zb[o],alignItems:n,justifyContent:r,flexDirection:t,flexWrap:i};return ot({render:s,ref:l,props:ve(a,{style:c,className:Hb.stack})})});var Eu=b(ce(),1),Tu=b(st(),1),Oo=b(W(),1),ks="data-wp-hash";function Ps(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&jb(document)),e.__wpStyleRuntime}function Db(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${ks}]`))if(o.getAttribute(ks)===t)return!0;return!1}function ku(e,t,o){if(!e.head)return;let n=Ps(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Db(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(ks,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function jb(e){let t=Ps();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)ku(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Er(e,t){let o=Ps();o.styles.set(e,t);for(let n of o.documents.keys())ku(n,e,t)}typeof process>"u",Er("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var Fb={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",Er("96553466c8","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._64de9947bf305b7a__outset-ring--focus-within-visible:focus-within:has(:focus-visible),.af79fb116edb0dd7__outset-ring--focus:focus,.dfcfdc28396e5d98__outset-ring--focus-visible:focus-visible,.e5cd9ee879f6403a__outset-ring--focus-within:focus-within,:focus-visible ._81935a08e952f267__outset-ring--focus-parent-visible{--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within,.abc777e9713fa711__outset-ring--focus-except-active:focus{outline:none}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within:not(:has(:active)),.abc777e9713fa711__outset-ring--focus-except-active:focus:not(:active){--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}}}");var Vb={"outset-ring--focus":"af79fb116edb0dd7__outset-ring--focus","outset-ring--focus-visible":"dfcfdc28396e5d98__outset-ring--focus-visible","outset-ring--focus-within":"e5cd9ee879f6403a__outset-ring--focus-within","outset-ring--focus-within-visible":"_64de9947bf305b7a__outset-ring--focus-within-visible","outset-ring--focus-parent-visible":"_81935a08e952f267__outset-ring--focus-parent-visible","outset-ring--focus-except-active":"abc777e9713fa711__outset-ring--focus-except-active","outset-ring--focus-within-except-active":"_3c9f5ee9fc9c136d__outset-ring--focus-within-except-active"};typeof process>"u",Er("e8e6a9be37",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.d4250949359b05ce__link{text-decoration-thickness:from-font;text-underline-offset:.2em}.c6055659b8e2cd2c__is-brand,.c6055659b8e2cd2c__is-brand:visited{--_gcd-a-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9))}.c6055659b8e2cd2c__is-brand:active,.c6055659b8e2cd2c__is-brand:hover{--_gcd-a-color:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));color:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000))}._92e0dfcaeee15b88__is-neutral,._92e0dfcaeee15b88__is-neutral:visited{--_gcd-a-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);text-decoration-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d)}._92e0dfcaeee15b88__is-neutral:active,._92e0dfcaeee15b88__is-neutral:hover{--_gcd-a-color:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);color:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e)}.cf122a9bf1035d42__is-unstyled{--_gcd-a-color:inherit;color:inherit;text-decoration:none}._0cb411afac4c86c7__link-icon{display:inline-block;font-weight:var(--wpds-typography-font-weight-default,400);line-height:1;margin-inline-start:var(--wpds-dimension-padding-xs,4px);text-decoration:none}._0cb411afac4c86c7__link-icon:after{content:"\\2197"}._0cb411afac4c86c7__link-icon:dir(rtl):after{content:"\\2196"}}}');var Rr={link:"d4250949359b05ce__link","is-brand":"c6055659b8e2cd2c__is-brand","is-neutral":"_92e0dfcaeee15b88__is-neutral","is-unstyled":"cf122a9bf1035d42__is-unstyled","link-icon":"_0cb411afac4c86c7__link-icon"};typeof process>"u",Er("af6d9984a6","._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}");var Wb={button:"_6defc79820e382c6__button",input:"d2cff2e5dea83bd1__input",textarea:"_547d86373d02e108__textarea",div:"_8c15fd0ed9f28ba4__div",p:"_43cec3e1eec1066d__p",heading:"e97669c6d9a38497__heading",a:"_2c0831b0499dbd6e__a"},co=(0,Eu.forwardRef)(function({children:t,variant:o="default",tone:n="brand",openInNewTab:r=!1,render:i,className:s,...a},l){return ot({render:i,defaultTagName:"a",ref:l,props:ve(a,{className:J(Wb.a,Fb["box-sizing"],Vb["outset-ring--focus-except-active"],o!=="unstyled"&&Rr.link,o!=="unstyled"&&Rr[`is-${n}`],o==="unstyled"&&Rr["is-unstyled"],s),target:r?"_blank":void 0,children:(0,Oo.jsxs)(Oo.Fragment,{children:[t,r&&(0,Oo.jsx)("span",{className:Rr["link-icon"],role:"img","aria-label":(0,Tu.__)("(opens in a new tab)")})]})})})});var nn={};Mt(nn,{ActionButton:()=>Qu,ActionLink:()=>ef,Actions:()=>Fu,CloseIcon:()=>Gu,Description:()=>zu,Root:()=>Au,Title:()=>Lu});var No=b(ce(),1);import{speak as Yb}from"@wordpress/a11y";var Io=b(W(),1),As="data-wp-hash";function Os(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Gb(document)),e.__wpStyleRuntime}function Ub(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${As}]`))if(o.getAttribute(As)===t)return!0;return!1}function Pu(e,t,o){if(!e.head)return;let n=Os(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Ub(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(As,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Gb(e){let t=Os();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Pu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Cu(e,t){let o=Os();o.styles.set(e,t);for(let n of o.documents.keys())Pu(n,e,t)}typeof process>"u",Cu("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var Kb={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",Cu("726c480820","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var Cs={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},Xb={neutral:null,info:ns,warning:Qi,success:is,error:ts};function qb(e){return e==="error"?"assertive":"polite"}function Zb(e){if(e){if(typeof e=="string")return e;try{return(0,No.renderToString)(e)}catch{return}}}function Qb(e,t){let o=Zb(e);(0,No.useEffect)(()=>{o&&Yb(o,t)},[o,t])}var Au=(0,No.forwardRef)(function({intent:t="neutral",children:o,icon:n,spokenMessage:r=o,politeness:i=qb(t),render:s,...a},l){Qb(r,i);let c=n===null?null:n??Xb[t],d=J(Cs.notice,Cs[`is-${t}`],Kb["box-sizing"]);return ot({defaultTagName:"div",render:s,ref:l,props:ve({className:d,children:(0,Io.jsxs)(Io.Fragment,{children:[o,c&&(0,Io.jsx)(ao,{className:Cs.icon,icon:c})]})},a)})});var Ou=b(ce(),1);var Iu=b(W(),1),Ns="data-wp-hash";function Is(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&$b(document)),e.__wpStyleRuntime}function Jb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Ns}]`))if(o.getAttribute(Ns)===t)return!0;return!1}function Nu(e,t,o){if(!e.head)return;let n=Is(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Jb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Ns,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function $b(e){let t=Is();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Nu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function eh(e,t){let o=Is();o.styles.set(e,t);for(let n of o.documents.keys())Nu(n,e,t)}typeof process>"u",eh("726c480820","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var th={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},Lu=(0,Ou.forwardRef)(function({className:t,...o},n){return(0,Iu.jsx)(We,{ref:n,variant:"heading-md",className:J(th.title,t),...o})});var Mu=b(ce(),1);var Hu=b(W(),1),Ls="data-wp-hash";function Ms(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&nh(document)),e.__wpStyleRuntime}function oh(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Ls}]`))if(o.getAttribute(Ls)===t)return!0;return!1}function Bu(e,t,o){if(!e.head)return;let n=Ms(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(oh(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Ls,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function nh(e){let t=Ms();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Bu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function rh(e,t){let o=Ms();o.styles.set(e,t);for(let n of o.documents.keys())Bu(n,e,t)}typeof process>"u",rh("726c480820","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var ih={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},zu=(0,Mu.forwardRef)(function({className:t,...o},n){return(0,Hu.jsx)(We,{ref:n,variant:"body-md",className:J(ih.description,t),...o})});var Du=b(ce(),1);var Bs="data-wp-hash";function Hs(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&ah(document)),e.__wpStyleRuntime}function sh(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Bs}]`))if(o.getAttribute(Bs)===t)return!0;return!1}function ju(e,t,o){if(!e.head)return;let n=Hs(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(sh(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Bs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function ah(e){let t=Hs();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)ju(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function ch(e,t){let o=Hs();o.styles.set(e,t);for(let n of o.documents.keys())ju(n,e,t)}typeof process>"u",ch("726c480820","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var lh={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},Fu=(0,Du.forwardRef)(function({render:t,...o},n){return ot({defaultTagName:"div",render:t,ref:n,props:ve({className:lh.actions},o)})});var Vu=b(ce(),1),Wu=b(st(),1);var Uu=b(W(),1),zs="data-wp-hash";function Ds(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&uh(document)),e.__wpStyleRuntime}function dh(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${zs}]`))if(o.getAttribute(zs)===t)return!0;return!1}function Yu(e,t,o){if(!e.head)return;let n=Ds(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(dh(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(zs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function uh(e){let t=Ds();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Yu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function fh(e,t){let o=Ds();o.styles.set(e,t);for(let n of o.documents.keys())Yu(n,e,t)}typeof process>"u",fh("726c480820","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var ph={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},Gu=(0,Vu.forwardRef)(function({className:t,icon:o=$i,label:n=(0,Wu.__)("Dismiss"),...r},i){return(0,Uu.jsx)(Rs,{...r,ref:i,className:J(ph["close-icon"],t),variant:"minimal",size:"small",tone:"neutral",icon:o,label:n})});var Xu=b(ce(),1);var Zu=b(W(),1),js="data-wp-hash";function Fs(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&gh(document)),e.__wpStyleRuntime}function mh(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${js}]`))if(o.getAttribute(js)===t)return!0;return!1}function qu(e,t,o){if(!e.head)return;let n=Fs(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(mh(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(js,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function gh(e){let t=Fs();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)qu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function bh(e,t){let o=Fs();o.styles.set(e,t);for(let n of o.documents.keys())qu(n,e,t)}typeof process>"u",bh("726c480820","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var Ku={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},Qu=(0,Xu.forwardRef)(function({className:t,loading:o,loadingAnnouncement:n,variant:r,...i},s){return(0,Zu.jsx)(br,{...i,...o!==void 0?{loading:o,loadingAnnouncement:n??""}:{},ref:s,size:"compact",tone:"neutral",variant:r,className:J(Ku["action-button"],Ku[`is-action-button-${r}`],t)})});var Ju=b(ce(),1);var Ws=b(W(),1),Vs="data-wp-hash";function Ys(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&wh(document)),e.__wpStyleRuntime}function hh(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Vs}]`))if(o.getAttribute(Vs)===t)return!0;return!1}function $u(e,t,o){if(!e.head)return;let n=Ys(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(hh(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Vs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function wh(e){let t=Ys();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)$u(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function vh(e,t){let o=Ys();o.styles.set(e,t);for(let n of o.documents.keys())$u(n,e,t)}typeof process>"u",vh("726c480820","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var _h={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},ef=(0,Ju.forwardRef)(function({className:t,render:o,...n},r){return(0,Ws.jsx)(We,{ref:r,className:J(_h["action-link"],t),...n,variant:"body-md",render:(0,Ws.jsx)(co,{tone:"neutral",variant:"default",render:o})})});var tf=b(ce(),1),of=b(W(),1),nf=(0,tf.forwardRef)(({children:e,className:t,ariaLabel:o,as:n="div",...r},i)=>(0,of.jsx)(n,{ref:i,className:J("admin-ui-navigable-region",t),"aria-label":o,role:"region",tabIndex:"-1",...r,children:e}));nf.displayName="NavigableRegion";var rf=nf;var sf=b(st(),1);var Gt=b(W(),1),Gs="data-wp-hash";function Ks(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&xh(document)),e.__wpStyleRuntime}function yh(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Gs}]`))if(o.getAttribute(Gs)===t)return!0;return!1}function af(e,t,o){if(!e.head)return;let n=Ks(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(yh(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Gs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function xh(e){let t=Ks();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)af(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Sh(e,t){let o=Ks();o.styles.set(e,t);for(let n of o.documents.keys())af(n,e,t)}typeof process>"u",Sh("72ef022400",".bfb5a2dd8cceebd3__list{--focus-ring-size:calc(var(--wpds-border-width-focus, var(--wp-admin-border-width-focus, 2px))*2);list-style:none;margin:calc(var(--focus-ring-size)*-1);overflow-x:auto;padding:var(--focus-ring-size);scroll-padding:var(--focus-ring-size)}.a4759b4cb2c8bd92__li{flex-shrink:0}._07da506d3f2d9afe__item{align-items:center;color:var(--wpds-color-foreground-interactive-neutral-weak,#707070);display:flex;font-weight:var(--wpds-typography-font-weight-default,400);min-block-size:44px;min-inline-size:44px;text-decoration:none}._07da506d3f2d9afe__item:hover,._07da506d3f2d9afe__item[aria-current=page]{color:var(--wpds-color-foreground-interactive-neutral-weak-active,#1e1e1e)}._07da506d3f2d9afe__item[aria-current=page]{font-weight:var(--wpds-typography-font-weight-emphasis,600)}");var Us={list:"bfb5a2dd8cceebd3__list",li:"a4759b4cb2c8bd92__li",item:"_07da506d3f2d9afe__item"},Rh=({items:e,currentHref:t,ariaLabel:o=(0,sf.__)("Sections"),linkComponent:n,className:r})=>{if(!e.length)return null;let i=n??"a";return(0,Gt.jsx)("nav",{"aria-label":o,className:r,children:(0,Gt.jsx)(Ut,{render:(0,Gt.jsx)("ul",{role:"list"}),direction:"row",align:"center",gap:"md",className:Us.list,children:e.map(s=>(0,Gt.jsx)("li",{className:Us.li,children:(0,Gt.jsx)(We,{variant:"body-md",className:Us.item,render:(0,Gt.jsx)(co,{variant:"unstyled","aria-current":s.href===t?"page":void 0,render:(0,Gt.jsx)(i,{href:s.href})}),children:s.label})},s.href))})})},cf=Rh;var df=b(rn(),1),{Fill:uf,Slot:ff}=(0,df.createSlotFill)("SidebarToggle");var Ze=b(W(),1),Xs="data-wp-hash";function qs(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Th(document)),e.__wpStyleRuntime}function Eh(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Xs}]`))if(o.getAttribute(Xs)===t)return!0;return!1}function pf(e,t,o){if(!e.head)return;let n=qs(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Eh(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Xs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Th(e){let t=qs();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)pf(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function kh(e,t){let o=qs();o.styles.set(e,t);for(let n of o.documents.keys())pf(n,e,t)}typeof process>"u",kh("1f3750277d","._956b6df0898efed0__page{text-wrap:pretty;background-color:var(--wpds-color-background-surface-neutral,#fcfcfc);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);display:flex;flex-flow:column;height:100%;position:relative;z-index:1}._0625b55e82a0d93d__header{background:var(--wpds-color-background-surface-neutral-strong,#fff);border-block-end:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral-weak,#f0f0f0);inset-block-start:0;padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px);position:sticky;z-index:1}.a43c44d5ae28b2e8__header-content{min-height:var(--wpds-dimension-size-md,32px)}.b7cb5b9daf3a3b25__header-actions{flex-shrink:0}._8bcd33103b451f30__header-lockup{min-width:0}._8113be94e7caf73c__header-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._9a776c7f70996f61__header-visual{display:grid;flex-shrink:0;grid-template-columns:1fr;grid-template-rows:1fr;height:var(--wpds-dimension-size-sm,24px);width:var(--wpds-dimension-size-sm,24px);>*{grid-column:1/-1;grid-row:1/-1;max-height:100%;max-width:100%}}.d5e0920cd15d35bc__sidebar-toggle-slot:empty{display:none}._60fea2f6bf5319cd__header-subtitle{color:var(--wpds-color-foreground-content-neutral-weak,#707070);padding-block-end:var(--wpds-dimension-padding-xs,4px)}._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation,._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation ._60fea2f6bf5319cd__header-subtitle{padding-block-end:0}._673c99dcbfb58211__header-navigation{margin-block-start:var(--wpds-dimension-gap-md,12px)}.be5e57d029ec4036__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;&._128806d0b26e3a50__has-padding{padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px)}}");var St={page:"_956b6df0898efed0__page",header:"_0625b55e82a0d93d__header","header-content":"a43c44d5ae28b2e8__header-content","header-actions":"b7cb5b9daf3a3b25__header-actions","header-lockup":"_8bcd33103b451f30__header-lockup","header-title":"_8113be94e7caf73c__header-title","header-visual":"_9a776c7f70996f61__header-visual","sidebar-toggle-slot":"d5e0920cd15d35bc__sidebar-toggle-slot","header-subtitle":"_60fea2f6bf5319cd__header-subtitle","has-navigation":"_4b0f17e503d11619__has-navigation","header-navigation":"_673c99dcbfb58211__header-navigation",content:"be5e57d029ec4036__content","has-padding":"_128806d0b26e3a50__has-padding"};function mf({headingLevel:e=1,breadcrumbs:t,badges:o,visual:n,title:r,subTitle:i,actions:s,navigation:a,components:l,showSidebarToggle:c=!0}){let d=`h${e}`,m=!!a?.items?.length;return(0,Ze.jsxs)(Ut,{direction:"column",className:J(St.header,m&&St["has-navigation"]),children:[(0,Ze.jsxs)(Ut,{className:St["header-content"],direction:"row",gap:"sm",justify:"space-between",children:[(0,Ze.jsxs)(Ut,{direction:"row",gap:"sm",align:"center",justify:"start",className:St["header-lockup"],children:[c&&(0,Ze.jsx)(ff,{bubblesVirtually:!0,className:St["sidebar-toggle-slot"]}),n&&(0,Ze.jsx)("div",{className:St["header-visual"],"aria-hidden":"true",children:n}),r&&(0,Ze.jsx)(We,{className:St["header-title"],render:(0,Ze.jsx)(d,{}),variant:"heading-lg",children:r}),t,o]}),s&&(0,Ze.jsx)(Ut,{align:"center",className:St["header-actions"],direction:"row",gap:"sm",children:s})]}),i&&(0,Ze.jsx)(We,{render:(0,Ze.jsx)("p",{}),variant:"body-md",className:St["header-subtitle"],children:i}),m&&(0,Ze.jsx)(cf,{...a,linkComponent:l?.link,className:St["header-navigation"]})]})}var sn=b(W(),1),Qs="data-wp-hash";function Js(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Ch(document)),e.__wpStyleRuntime}function Ph(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Qs}]`))if(o.getAttribute(Qs)===t)return!0;return!1}function gf(e,t,o){if(!e.head)return;let n=Js(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Ph(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Qs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Ch(e){let t=Js();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)gf(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Ah(e,t){let o=Js();o.styles.set(e,t);for(let n of o.documents.keys())gf(n,e,t)}typeof process>"u",Ah("1f3750277d","._956b6df0898efed0__page{text-wrap:pretty;background-color:var(--wpds-color-background-surface-neutral,#fcfcfc);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);display:flex;flex-flow:column;height:100%;position:relative;z-index:1}._0625b55e82a0d93d__header{background:var(--wpds-color-background-surface-neutral-strong,#fff);border-block-end:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral-weak,#f0f0f0);inset-block-start:0;padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px);position:sticky;z-index:1}.a43c44d5ae28b2e8__header-content{min-height:var(--wpds-dimension-size-md,32px)}.b7cb5b9daf3a3b25__header-actions{flex-shrink:0}._8bcd33103b451f30__header-lockup{min-width:0}._8113be94e7caf73c__header-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._9a776c7f70996f61__header-visual{display:grid;flex-shrink:0;grid-template-columns:1fr;grid-template-rows:1fr;height:var(--wpds-dimension-size-sm,24px);width:var(--wpds-dimension-size-sm,24px);>*{grid-column:1/-1;grid-row:1/-1;max-height:100%;max-width:100%}}.d5e0920cd15d35bc__sidebar-toggle-slot:empty{display:none}._60fea2f6bf5319cd__header-subtitle{color:var(--wpds-color-foreground-content-neutral-weak,#707070);padding-block-end:var(--wpds-dimension-padding-xs,4px)}._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation,._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation ._60fea2f6bf5319cd__header-subtitle{padding-block-end:0}._673c99dcbfb58211__header-navigation{margin-block-start:var(--wpds-dimension-gap-md,12px)}.be5e57d029ec4036__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;&._128806d0b26e3a50__has-padding{padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px)}}");var Zs={page:"_956b6df0898efed0__page",header:"_0625b55e82a0d93d__header","header-content":"a43c44d5ae28b2e8__header-content","header-actions":"b7cb5b9daf3a3b25__header-actions","header-lockup":"_8bcd33103b451f30__header-lockup","header-title":"_8113be94e7caf73c__header-title","header-visual":"_9a776c7f70996f61__header-visual","sidebar-toggle-slot":"d5e0920cd15d35bc__sidebar-toggle-slot","header-subtitle":"_60fea2f6bf5319cd__header-subtitle","has-navigation":"_4b0f17e503d11619__has-navigation","header-navigation":"_673c99dcbfb58211__header-navigation",content:"be5e57d029ec4036__content","has-padding":"_128806d0b26e3a50__has-padding"};function bf({headingLevel:e,breadcrumbs:t,badges:o,visual:n,title:r,subTitle:i,children:s,className:a,actions:l,navigation:c,components:d,ariaLabel:m,hasPadding:u=!1,showSidebarToggle:f=!0}){let p=J(Zs.page,a);return(0,sn.jsxs)(rf,{className:p,ariaLabel:m??(typeof r=="string"?r:""),children:[(r||t||o||l||n||!!c?.items?.length)&&(0,sn.jsx)(mf,{headingLevel:e,breadcrumbs:t,badges:o,visual:n,title:r,subTitle:i,actions:l,navigation:c,components:d,showSidebarToggle:f}),u?(0,sn.jsx)("div",{className:J(Zs.content,Zs["has-padding"]),children:s}):s]})}bf.SidebarToggleFill=uf;var $s=bf;var ut=b(rn()),Ff=b(an()),Vf=b(ce()),At=b(st()),Wf=b(Tr());import{privateApis as Kh}from"@wordpress/connectors";var vf=b(fs()),{lock:a8,unlock:Lo}=(0,vf.__dangerousOptInToUnstableAPIsOnlyForCoreModules)("I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.","@wordpress/routes");if(typeof document<"u"&&!document.head.querySelector("style[data-wp-hash='09e9b056ea']")){let e=document.createElement("style");e.setAttribute("data-wp-hash","09e9b056ea"),e.appendChild(document.createTextNode(".connectors-page{box-sizing:border-box;margin:0 auto;max-width:680px;padding:24px;width:100%}.connectors-page .components-item{background:#fff;border:1px solid #ddd;border-radius:8px;overflow:hidden;padding:20px;scroll-margin-top:120px}.connectors-page .connector-settings__error{color:#cc1818}.connectors-page .connector-settings .components-text-control__input{font-family:monospace;scroll-margin-top:120px}.connectors-page__file-mods-notice{margin-bottom:16px}.connectors-page--empty{align-items:center;display:flex;flex-direction:column;flex-grow:1;gap:32px;justify-content:center;text-align:center}.connectors-page .ai-plugin-callout{background-color:#e7d4e4;background-image:radial-gradient(ellipse 70% 120% at 18% 115%,rgba(202,158,198,.75) 0,rgba(202,158,198,0) 60%),radial-gradient(ellipse 55% 110% at 92% -15%,rgba(208,175,217,.7) 0,rgba(208,175,217,0) 65%),radial-gradient(ellipse 40% 85% at 58% -10%,rgba(170,130,184,.45) 0,rgba(170,130,184,0) 70%);border-radius:8px;overflow:hidden;padding:24px;padding-inline-end:150px;position:relative}[dir=rtl] .connectors-page .ai-plugin-callout{background-image:radial-gradient(ellipse 70% 120% at 82% 115%,rgba(202,158,198,.75) 0,rgba(202,158,198,0) 60%),radial-gradient(ellipse 55% 110% at 8% -15%,rgba(208,175,217,.7) 0,rgba(208,175,217,0) 65%),radial-gradient(ellipse 40% 85% at 42% -10%,rgba(170,130,184,.45) 0,rgba(170,130,184,0) 70%)}.connectors-page .ai-plugin-callout__content{align-items:flex-start;display:flex;flex-direction:column;gap:12px;padding-top:2px}.connectors-page .ai-plugin-callout__content p{font-size:13px;line-height:20px;margin:0}.connectors-page .ai-plugin-callout__decoration{height:110px;inset-inline-end:16px;position:absolute;top:12px;width:110px}.connectors-page>p{color:#949494}@media (max-width:680px){.connectors-page .ai-plugin-callout{padding:12px;padding-inline-end:100px}.connectors-page .ai-plugin-callout__decoration{height:75px;inset-inline-end:8px;top:8px;width:75px}}@media (max-width:480px){.connectors-page{padding:8px}.connectors-page .ai-plugin-callout{padding-inline-end:130px}.connectors-page .components-item{padding:12px}.connectors-page .components-item>.components-v-stack>.components-h-stack:first-child svg{height:32px;width:32px}.connectors-page .components-item>.components-v-stack>.components-h-stack:first-child>.components-h-stack:last-child{align-items:flex-end;flex-direction:column}}")),document.head.appendChild(e)}var dn=b(rn()),sa=b(Tr()),un=b(an()),Et=b(ce()),Qe=b(st()),Hf=b(ea()),zf=b(xf());var kr=b(rn()),na=b(ce()),Af=b(an()),lo=b(st());import{__experimentalRegisterConnector as Oh,__experimentalConnectorItem as Cf,__experimentalDefaultConnectorSettings as Nh,__experimentalApplicationPasswordConnectorSettings as Ih,privateApis as Lh}from"@wordpress/connectors";var ta=b(Tr()),ln=b(an()),cn=b(ce()),pe=b(st()),Sf=b(ea());function oa({file:e,settingName:t,connectorName:o,isInstalled:n,isActivated:r,keySource:i="none",initialIsConnected:s=!1}){let[a,l]=(0,cn.useState)(!1),[c,d]=(0,cn.useState)(!1),[m,u]=(0,cn.useState)(s),[f,p]=(0,cn.useState)(null),g=e?.replace(/\.php$/,""),h=g?.includes("/")?g.split("/")[0]:g,{derivedPluginStatus:y,canManagePlugins:_,currentApiKey:v,currentUsername:w,hasStoredCredentials:R,hasResolvedSettings:x,canInstallPlugins:S}=(0,ln.useSelect)(Q=>{let q=Q(ta.store),ne=q.getEntityRecord("root","site")?.[t],se=typeof ne=="string"?ne:"",ze=typeof ne=="object"&&ne!==null?ne:void 0,ae=ze!==void 0?!!ze.username&&!!ze.password:!!se,ge=q.hasFinishedResolution("getEntityRecord",["root","site"]),be=!!q.canUser("create",{kind:"root",name:"plugin"}),Ee={currentApiKey:se,currentUsername:ze?.username??"",hasStoredCredentials:ae,hasResolvedSettings:ge,canInstallPlugins:be};if(!e)return{...Ee,derivedPluginStatus:ge?"active":"checking",canManagePlugins:void 0};let ye=q.getEntityRecord("root","plugin",g);if(!q.hasFinishedResolution("getEntityRecord",["root","plugin",g]))return{...Ee,derivedPluginStatus:"checking",canManagePlugins:void 0};if(ye){let ft=ye.status==="active"||ye.status==="network-active";return{...Ee,derivedPluginStatus:ft?"active":"inactive",canManagePlugins:!0}}let rt="not-installed";return r?rt="active":n&&(rt="inactive"),{...Ee,derivedPluginStatus:rt,canManagePlugins:!1}},[e,g,t,n,r]),E=f??y,T=_,P=E==="active"&&m||f==="active"&&R,{saveEntityRecord:N,invalidateResolution:H}=(0,ln.useDispatch)(ta.store),{createSuccessNotice:j,createErrorNotice:L}=(0,ln.useDispatch)(Sf.store),k=Q=>N("root","site",{[t]:Q},{throwOnError:!0}),I=()=>{j((0,pe.sprintf)((0,pe.__)("%s connected successfully."),o),{id:"connector-connect-success",type:"snackbar"})},C=()=>{j((0,pe.sprintf)((0,pe.__)("%s disconnected."),o),{id:"connector-disconnect-success",type:"snackbar"})},A=()=>{L((0,pe.sprintf)((0,pe.__)("Failed to disconnect %s."),o),{id:"connector-disconnect-error",type:"snackbar"})},M=async()=>{if(h){d(!0);try{await N("root","plugin",{slug:h,status:"active"},{throwOnError:!0}),p("active"),H("getEntityRecord",["root","site"]),l(!0),j((0,pe.sprintf)((0,pe.__)("Plugin for %s installed and activated successfully."),o),{id:"connector-plugin-install-success",type:"snackbar"})}catch{L((0,pe.sprintf)((0,pe.__)("Failed to install plugin for %s."),o),{id:"connector-plugin-install-error",type:"snackbar"})}finally{d(!1)}}},X=async()=>{if(e){d(!0);try{await N("root","plugin",{plugin:g,status:"active"},{throwOnError:!0}),p("active"),H("getEntityRecord",["root","site"]),l(!0),j((0,pe.sprintf)((0,pe.__)("Plugin for %s activated successfully."),o),{id:"connector-plugin-activate-success",type:"snackbar"})}catch{L((0,pe.sprintf)((0,pe.__)("Failed to activate plugin for %s."),o),{id:"connector-plugin-activate-error",type:"snackbar"})}finally{d(!1)}}};return{pluginStatus:E,canInstallPlugins:S,canActivatePlugins:T,isExpanded:a,setIsExpanded:l,isBusy:c,isConnected:P,currentApiKey:v,currentUsername:w,hasResolvedSettings:x,keySource:i,handleButtonClick:()=>{if(E==="not-installed"){if(S===!1)return;M()}else if(E==="inactive"){if(T===!1)return;X()}else l(!a)},getButtonLabel:()=>{if(c)return E==="not-installed"?(0,pe.__)("Installing\u2026"):(0,pe.__)("Activating\u2026");if(a)return(0,pe.__)("Cancel");if(P)return(0,pe.__)("Edit");switch(E){case"checking":return(0,pe.__)("Checking\u2026");case"not-installed":return(0,pe.__)("Install");case"inactive":return(0,pe.__)("Activate");case"active":return(0,pe.__)("Set up")}},saveApiKey:async Q=>{let q=v;try{let se=(await k(Q))?.[t];if(Q&&(se===q||!se))throw new Error("It was not possible to connect to the provider using this key.");u(!0),I()}catch($){throw console.error("Failed to save API key:",$),$}},removeApiKey:async()=>{try{await k(""),u(!1),C()}catch(Q){console.error("Failed to remove API key:",Q),A()}},saveCredentials:async({username:Q,applicationPassword:q})=>{try{let se=(await k({username:Q,password:q}))?.[t];if(!se?.username||!se?.password)throw new Error((0,pe.__)("It was not possible to save these credentials."));u(!0),I()}catch($){throw console.error("Failed to save credentials:",$),$}},removeCredentials:async()=>{try{await k({username:"",password:""}),u(!1),C()}catch(Q){console.error("Failed to remove credentials:",Q),A()}}}}var ue=b(W()),Rf=()=>(0,ue.jsx)("svg",{width:"40",height:"40",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:(0,ue.jsx)("path",{d:"M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364l2.0201-1.1685a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.4043-.6813zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z",fill:"currentColor"})}),Ef=()=>(0,ue.jsx)("svg",{width:"40",height:"40",viewBox:"0 0 32 32",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:(0,ue.jsx)("path",{d:"M6.2 21.024L12.416 17.536L12.52 17.232L12.416 17.064H12.112L11.072 17L7.52 16.904L4.44 16.776L1.456 16.616L0.704 16.456L0 15.528L0.072 15.064L0.704 14.64L1.608 14.72L3.608 14.856L6.608 15.064L8.784 15.192L12.008 15.528H12.52L12.592 15.32L12.416 15.192L12.28 15.064L9.176 12.96L5.816 10.736L4.056 9.456L3.104 8.808L2.624 8.2L2.416 6.872L3.28 5.92L4.44 6L4.736 6.08L5.912 6.984L8.424 8.928L11.704 11.344L12.184 11.744L12.376 11.608L12.4 11.512L12.184 11.152L10.4 7.928L8.496 4.648L7.648 3.288L7.424 2.472C7.344 2.136 7.288 1.856 7.288 1.512L8.272 0.176L8.816 0L10.128 0.176L10.68 0.656L11.496 2.52L12.816 5.456L14.864 9.448L15.464 10.632L15.784 11.728L15.904 12.064H16.112V11.872L16.28 9.624L16.592 6.864L16.896 3.312L17 2.312L17.496 1.112L18.48 0.464L19.248 0.832L19.88 1.736L19.792 2.32L19.416 4.76L18.68 8.584L18.2 11.144H18.48L18.8 10.824L20.096 9.104L22.272 6.384L23.232 5.304L24.352 4.112L25.072 3.544H26.432L27.432 5.032L26.984 6.568L25.584 8.344L24.424 9.848L22.76 12.088L21.72 13.88L21.816 14.024L22.064 14L25.824 13.2L27.856 12.832L30.28 12.416L31.376 12.928L31.496 13.448L31.064 14.512L28.472 15.152L25.432 15.76L20.904 16.832L20.848 16.872L20.912 16.952L22.952 17.144L23.824 17.192H25.96L29.936 17.488L30.976 18.176L31.6 19.016L31.496 19.656L29.896 20.472L27.736 19.96L22.696 18.76L20.968 18.328H20.728V18.472L22.168 19.88L24.808 22.264L28.112 25.336L28.28 26.096L27.856 26.696L27.408 26.632L24.504 24.448L23.384 23.464L20.848 21.328H20.68V21.552L21.264 22.408L24.352 27.048L24.512 28.472L24.288 28.936L23.488 29.216L22.608 29.056L20.8 26.52L18.936 23.664L17.432 21.104L17.248 21.208L16.36 30.768L15.944 31.256L14.984 31.624L14.184 31.016L13.76 30.032L14.184 28.088L14.696 25.552L15.112 23.536L15.488 21.032L15.712 20.2L15.696 20.144L15.512 20.168L13.624 22.76L10.752 26.64L8.48 29.072L7.936 29.288L6.992 28.8L7.08 27.928L7.608 27.152L10.752 23.152L12.648 20.672L13.872 19.24L13.864 19.032H13.792L5.44 24.456L3.952 24.648L3.312 24.048L3.392 23.064L3.696 22.744L6.208 21.016L6.2 21.024Z",fill:"#D97757"})}),Tf=()=>(0,ue.jsxs)("svg",{width:"40",height:"40",viewBox:"0 0 32 32",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[(0,ue.jsx)("path",{d:"M0 4C0 1.79086 1.79086 0 4 0H28C30.2091 0 32 1.79086 32 4V28C32 30.2091 30.2091 32 28 32H4C1.79086 32 0 30.2091 0 28V4Z",fill:"#F0F0F0"}),(0,ue.jsx)("path",{d:"M14.5 8V12H17.5V8H19V12H20.5C20.7652 12 21.0196 12.1054 21.2071 12.2929C21.3946 12.4804 21.5 12.7348 21.5 13V17L18.5 21V23C18.5 23.2652 18.3946 23.5196 18.2071 23.7071C18.0196 23.8946 17.7652 24 17.5 24H14.5C14.2348 24 13.9804 23.8946 13.7929 23.7071C13.6054 23.5196 13.5 23.2652 13.5 23V21L10.5 17V13C10.5 12.7348 10.6054 12.4804 10.7929 12.2929C10.9804 12.1054 11.2348 12 11.5 12H13V8H14.5ZM15 20.5V22.5H17V20.5L20 16.5V13.5H12V16.5L15 20.5Z",fill:"#949494"})]}),kf=()=>(0,ue.jsxs)("svg",{width:"40",height:"40",viewBox:"0 0 44 44",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[(0,ue.jsx)("rect",{width:"44",height:"44",fill:"#357B49",rx:"6"}),(0,ue.jsx)("path",{fill:"#fff",fillRule:"evenodd",d:"m29.746 28.31-6.392-16.797c-.152-.397-.305-.672-.789-.675-.673 0-1.408.611-1.746 1.316l-7.378 16.154c-.072.16-.143.311-.214.454-.5.995-1.045 1.546-2.357 1.626a.399.399 0 0 0-.16.033l-.01.004a.399.399 0 0 0-.23.392v.01c0 .054.01.106.03.155l.004.01a.416.416 0 0 0 .394.252h6.212a.417.417 0 0 0 .307-.12.416.416 0 0 0 .124-.305.398.398 0 0 0-.105-.302.399.399 0 0 0-.294-.127c-.757 0-2.197-.062-2.197-1.164.02-.318.103-.63.245-.916l1.399-3.152c.52-1.163 1.654-1.163 2.572-1.163h5.843c.023 0 .044 0 .062.003.13.014.16.081.214.242l1.534 4.07a2.857 2.857 0 0 1 .216 1.04c0 .054-.003.104-.01.153-.09.726-.831.887-1.49.887a.4.4 0 0 0-.294.127l-.007.008-.007.008a.401.401 0 0 0-.092.286v.01c0 .054.01.106.03.155l.005.01a.42.42 0 0 0 .395.252h7.011a.413.413 0 0 0 .279-.13.412.412 0 0 0 .11-.297.387.387 0 0 0-.09-.294.388.388 0 0 0-.277-.135c-1.448-.122-2.295-.643-2.847-2.08Zm-11.985-5.844 2.847-6.304c.361-.728.659-1.486.889-2.265 0-.06.03-.092.06-.092s.061.032.061.091c.02.122.045.247.073.374.197.888.584 1.878.914 2.723l.176.453 1.684 4.529a.927.927 0 0 1 .092.4.473.473 0 0 1-.009.094c-.041.202-.228.272-.602.272h-6.063c-.122 0-.184-.03-.184-.092a.36.36 0 0 1 .062-.183Zm17.107-.721c0 .786-.446 1.231-1.25 1.231-.806 0-1.125-.409-1.125-1.034 0-.786.465-1.231 1.25-1.231.785 0 1.125.427 1.125 1.034ZM9.629 23.002c.803 0 1.25-.447 1.25-1.231 0-.607-.343-1.036-1.128-1.036-.785 0-1.25.447-1.25 1.231 0 .625.325 1.036 1.128 1.036Z",clipRule:"evenodd"})]}),Pf=()=>(0,ue.jsxs)("svg",{width:"40",height:"40",style:{flex:"none",lineHeight:1},viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[(0,ue.jsx)("path",{d:"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z",fill:"#3186FF"}),(0,ue.jsx)("path",{d:"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z",fill:"url(#lobe-icons-gemini-fill-0)"}),(0,ue.jsx)("path",{d:"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z",fill:"url(#lobe-icons-gemini-fill-1)"}),(0,ue.jsx)("path",{d:"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z",fill:"url(#lobe-icons-gemini-fill-2)"}),(0,ue.jsxs)("defs",{children:[(0,ue.jsxs)("linearGradient",{gradientUnits:"userSpaceOnUse",id:"lobe-icons-gemini-fill-0",x1:"7",x2:"11",y1:"15.5",y2:"12",children:[(0,ue.jsx)("stop",{stopColor:"#08B962"}),(0,ue.jsx)("stop",{offset:"1",stopColor:"#08B962",stopOpacity:"0"})]}),(0,ue.jsxs)("linearGradient",{gradientUnits:"userSpaceOnUse",id:"lobe-icons-gemini-fill-1",x1:"8",x2:"11.5",y1:"5.5",y2:"11",children:[(0,ue.jsx)("stop",{stopColor:"#F94543"}),(0,ue.jsx)("stop",{offset:"1",stopColor:"#F94543",stopOpacity:"0"})]}),(0,ue.jsxs)("linearGradient",{gradientUnits:"userSpaceOnUse",id:"lobe-icons-gemini-fill-2",x1:"3.5",x2:"17.5",y1:"13.5",y2:"12",children:[(0,ue.jsx)("stop",{stopColor:"#FABC12"}),(0,ue.jsx)("stop",{offset:".46",stopColor:"#FABC12",stopOpacity:"0"})]})]})]});var _e=b(W()),{store:Mh}=Lo(Lh);function Of(){try{return JSON.parse(document.getElementById("wp-script-module-data-options-connectors-wp-admin")?.textContent??"{}")}catch{return{}}}function ra(){return Of().connectors??{}}function Nf(){return!!Of().isFileModDisabled}var Bh={google:Pf,openai:Rf,anthropic:Ef,akismet:kf};function Hh(e,t){if(t)return(0,_e.jsx)("img",{src:t,alt:"",width:40,height:40});let o=Bh[e];return o?(0,_e.jsx)(o,{}):(0,_e.jsx)(Tf,{})}var zh=()=>(0,_e.jsx)("span",{style:{color:"#345b37",backgroundColor:"#eff8f0",padding:"4px 12px",borderRadius:"2px",fontSize:"13px",fontWeight:"var(--wpds-typography-font-weight-emphasis)",whiteSpace:"nowrap"},children:(0,lo.__)("Connected")}),Dh=({slug:e})=>(0,_e.jsx)(co,{href:(0,lo.sprintf)((0,lo.__)("https://wordpress.org/plugins/%s/"),e),openInNewTab:!0,children:(0,lo.__)("Learn more")}),jh=()=>(0,_e.jsx)(Yi,{children:(0,lo.__)("Not available")});function If({isConnected:e,showUnavailableBadge:t,pluginSlug:o,isExpanded:n,isBusy:r,pluginStatus:i,actionButtonRef:s,handleButtonClick:a,getButtonLabel:l}){return(0,_e.jsxs)(kr.__experimentalHStack,{spacing:3,expanded:!1,children:[e&&(0,_e.jsx)(zh,{}),t&&(o?(0,_e.jsx)(Dh,{slug:o}):(0,_e.jsx)(jh,{})),!t&&(0,_e.jsx)(kr.Button,{ref:s,variant:n||e?"tertiary":"secondary",size:"compact",onClick:a,disabled:i==="checking"||r,isBusy:r,accessibleWhenDisabled:!0,children:l()})]})}function Lf(e){let t=e?.replace(/\.php$/,"");return t?.includes("/")?t.split("/")[0]:t}function Fh({name:e,description:t,logo:o,authentication:n,plugin:r}){let i=n?.method==="api_key"?n:void 0,s=i?.settingName??"",a=i?.credentialsUrl??void 0,l=Lf(r?.file),{pluginStatus:c,canInstallPlugins:d,canActivatePlugins:m,isExpanded:u,setIsExpanded:f,isBusy:p,isConnected:g,currentApiKey:h,hasResolvedSettings:y,keySource:_,handleButtonClick:v,getButtonLabel:w,saveApiKey:R,removeApiKey:x}=oa({file:r?.file,settingName:s,connectorName:e,isInstalled:r?.isInstalled,isActivated:r?.isActivated,keySource:i?.keySource,initialIsConnected:i?.isConnected}),S=_==="env"||_==="constant",E=c==="not-installed"&&d===!1||c==="inactive"&&m===!1,T=(0,na.useRef)(null);return(0,_e.jsx)(Cf,{className:l?`connector-item--${l}`:void 0,logo:o,name:e,description:t,actionArea:(0,_e.jsx)(If,{isConnected:g,showUnavailableBadge:E,pluginSlug:l,isExpanded:u,isBusy:p,pluginStatus:c,actionButtonRef:T,handleButtonClick:v,getButtonLabel:w}),children:u&&c==="active"&&y&&(0,_e.jsx)(Nh,{initialValue:S?"\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022":h,helpUrl:a,readOnly:g||S,keySource:_,onRemove:S?void 0:async()=>{await x(),T.current?.focus()},onSave:async P=>{await R(P),f(!1),T.current?.focus()}},g?"connected":"setup")})}function Vh({name:e,description:t,logo:o,authentication:n,plugin:r}){let i=n?.method==="application_password"?n:void 0,s=i?.settingName??"",a=i?.credentialsUrl??void 0,l=Lf(r?.file),{pluginStatus:c,canInstallPlugins:d,canActivatePlugins:m,isExpanded:u,setIsExpanded:f,isBusy:p,isConnected:g,currentUsername:h,hasResolvedSettings:y,keySource:_,handleButtonClick:v,getButtonLabel:w,saveCredentials:R,removeCredentials:x}=oa({file:r?.file,settingName:s,connectorName:e,isInstalled:r?.isInstalled,isActivated:r?.isActivated,keySource:i?.keySource,initialIsConnected:i?.isConnected}),S=_==="env"||_==="constant",E=(0,na.useRef)(null),T=c==="not-installed"&&d===!1||c==="inactive"&&m===!1;return(0,_e.jsx)(Cf,{className:l?`connector-item--${l}`:void 0,logo:o,name:e,description:t,actionArea:(0,_e.jsx)(If,{isConnected:g,showUnavailableBadge:T,pluginSlug:l,isExpanded:u,isBusy:p,pluginStatus:c,actionButtonRef:E,handleButtonClick:v,getButtonLabel:w}),children:u&&c==="active"&&y&&(0,_e.jsx)(Ih,{initialUsername:S?"\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022":h,helpUrl:a,readOnly:g||S,keySource:_,onRemove:S?void 0:async()=>{await x(),E.current?.focus()},onSave:async P=>{await R(P),f(!1),E.current?.focus()}},g?"connected":"setup")})}function Mf(){let e=ra(),t=o=>o.replace(/[^a-z0-9-_]/gi,"-");for(let[o,n]of Object.entries(e)){if(o==="akismet"&&!n.plugin?.isInstalled)continue;let{authentication:r}=n,i=t(o),s={name:n.name,description:n.description,type:n.type,logo:Hh(o,n.logoUrl),authentication:r,plugin:n.plugin},a=Lo((0,Af.select)(Mh)).getConnector(i);r.method==="api_key"&&!a?.render?s.render=Fh:r.method==="application_password"&&!a?.render&&(s.render=Vh),Oh(i,s)}}var Pr=b(W());function Bf(){return(0,Pr.jsx)("div",{className:"ai-plugin-callout__decoration","aria-hidden":"true",children:(0,Pr.jsx)("svg",{viewBox:"0 0 248 248",xmlns:"http://www.w3.org/2000/svg",xmlnsXlink:"http://www.w3.org/1999/xlink",focusable:"false",style:{width:"100%",height:"100%"},children:(0,Pr.jsx)("image",{href:"data:image/png;base64,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",width:"248",height:"248",style:{mixBlendMode:"multiply"}})})})}var Rt=b(W()),Wh="ai",Yh="ai-wp-admin",ia="ai/ai",Uh="https://wordpress.org/plugins/ai/",aa=Object.values(ra()),Gh=aa.some(e=>e.type==="ai_provider"),Df=[];for(let e of aa)e.type==="ai_provider"&&e.authentication.method==="api_key"&&Df.push(e.authentication.settingName);function jf(){let[e,t]=(0,Et.useState)(!1),[o,n]=(0,Et.useState)(!1),r=(0,Et.useRef)(null);(0,Et.useEffect)(()=>{o&&r.current?.focus()},[o]);let i=(0,Et.useRef)(aa.some(R=>R.type==="ai_provider"&&R.authentication.method==="api_key"&&R.authentication.isConnected)).current,{pluginStatus:s,canInstallPlugins:a,canManagePlugins:l,hasConnectedProvider:c}=(0,un.useSelect)(R=>{let x=R(sa.store),S=!!x.canUser("create",{kind:"root",name:"plugin"}),E=x.getEntityRecord("root","site"),T=i||Df.some(H=>!!E?.[H]),P=x.getEntityRecord("root","plugin",ia);return x.hasFinishedResolution("getEntityRecord",["root","plugin",ia])?P?{pluginStatus:P.status==="active"?"active":"inactive",canInstallPlugins:S,canManagePlugins:!0,hasConnectedProvider:T}:{pluginStatus:"not-installed",canInstallPlugins:S,canManagePlugins:S,hasConnectedProvider:T}:{pluginStatus:"checking",canInstallPlugins:S,canManagePlugins:void 0,hasConnectedProvider:T}},[]),{saveEntityRecord:d}=(0,un.useDispatch)(sa.store),{createSuccessNotice:m,createErrorNotice:u}=(0,un.useDispatch)(Hf.store),f=async()=>{t(!0);try{await d("root","plugin",{slug:Wh,status:"active"},{throwOnError:!0}),n(!0),m((0,Qe.__)("AI plugin installed and activated successfully."),{id:"ai-plugin-install-success",type:"snackbar"})}catch{u((0,Qe.__)("Failed to install the AI plugin."),{id:"ai-plugin-install-error",type:"snackbar"})}finally{t(!1)}},p=async()=>{t(!0);try{await d("root","plugin",{plugin:ia,status:"active"},{throwOnError:!0}),n(!0),m((0,Qe.__)("AI plugin activated successfully."),{id:"ai-plugin-activate-success",type:"snackbar"})}catch{u((0,Qe.__)("Failed to activate the AI plugin."),{id:"ai-plugin-activate-error",type:"snackbar"})}finally{t(!1)}};if(!Gh||s==="checking"||s==="active"&&i&&!o||s==="inactive"&&l===!1)return null;let g=s==="active"&&!c,h=s==="active"&&c&&(!i||o),y=s==="not-installed"||s==="inactive",_=s==="not-installed"&&a===!1,v=()=>h?(0,Qe.__)("The AI plugin is ready to use. You can use it to generate featured images, alt text, titles, excerpts and more. Learn more"):g?(0,Qe.__)("The AI plugin is installed. Connect an AI provider below to generate featured images, alt text, titles, excerpts, and more. Learn more"):(0,Qe.__)("The AI plugin can use your AI connectors to generate featured images, alt text, titles, excerpts and more. Learn more"),w=()=>s==="not-installed"?{label:e?(0,Qe.__)("Installing\u2026"):(0,Qe.__)("Install the AI plugin"),disabled:e,onClick:e?void 0:f}:{label:e?(0,Qe.__)("Activating\u2026"):(0,Qe.__)("Activate the AI plugin"),disabled:e,onClick:e?void 0:p};return(0,Rt.jsxs)("div",{className:"ai-plugin-callout",children:[(0,Rt.jsxs)("div",{className:"ai-plugin-callout__content",children:[(0,Rt.jsx)("p",{children:(0,Et.createInterpolateElement)(v(),{strong:(0,Rt.jsx)("strong",{}),a:(0,Rt.jsx)(dn.ExternalLink,{href:Uh})})}),!_&&(y?(0,Rt.jsx)(dn.Button,{variant:"primary",size:"compact",isBusy:e,disabled:w().disabled,accessibleWhenDisabled:!0,onClick:w().onClick,children:w().label}):(0,Rt.jsx)(dn.Button,{ref:r,variant:"secondary",size:"compact",href:(0,zf.addQueryArgs)("options-general.php",{page:Yh}),children:(0,Qe.__)("Control features in the AI plugin")}))]}),(0,Rt.jsx)(Bf,{})]})}var Re=b(W()),{store:Xh}=Lo(Kh);Mf();function qh(){let e=Nf(),{connectors:t,canInstallPlugins:o,isAiPluginInstalled:n}=(0,Ff.useSelect)(c=>{let d=c(Wf.store),m=d.getEntityRecord("root","plugin","ai/ai");return{connectors:Lo(c(Xh)).getConnectors(),canInstallPlugins:d.canUser("create",{kind:"root",name:"plugin"}),isAiPluginInstalled:!!m}},[]),r=t.filter(c=>c.render),i=Array.from(new Set(t.filter(c=>c.type==="ai_provider").map(c=>c.plugin?.file?.split("/")[0]).filter(c=>!!c))).sort(),s=new Set(t.filter(c=>c.plugin?.isInstalled).map(c=>c.plugin?.file?.split("/")[0]).filter(c=>!!c));n&&s.add("ai");let a=["ai",...i].filter(c=>!s.has(c)),l=r.length===0;return(0,Re.jsx)($s,{title:(0,At.__)("Connectors"),subTitle:(0,At.__)("All of your API keys and credentials are stored here and shared across plugins. Configure once and use everywhere."),children:(0,Re.jsxs)("div",{className:`connectors-page${l?" connectors-page--empty":""}`,children:[a.length>0&&(e||!o)&&(0,Re.jsx)(nn.Root,{intent:"info",className:"connectors-page__file-mods-notice",children:(0,Re.jsx)(nn.Description,{children:e?(0,At.__)("Plugins cannot be installed here due to your site configuration. Install them manually using your normal deployment workflow."):(0,At.__)("You do not have permission to install plugins. Please ask a site administrator to install them for you.")})}),l?(0,Re.jsxs)(ut.__experimentalVStack,{alignment:"center",spacing:3,style:{maxWidth:480},children:[(0,Re.jsxs)(ut.__experimentalVStack,{alignment:"center",spacing:2,children:[(0,Re.jsx)(ut.__experimentalHeading,{level:2,size:15,children:(0,At.__)("No connectors yet")}),(0,Re.jsx)(ut.__experimentalText,{size:12,children:(0,At.__)("Connectors appear here when you install plugins that use external services. Each plugin registers the API keys it needs, and you manage them all in one place.")})]}),(0,Re.jsx)(ut.Button,{variant:"secondary",href:"plugin-install.php",__next40pxDefaultSize:!0,children:(0,At.__)("Learn more")})]}):(0,Re.jsxs)(ut.__experimentalVStack,{spacing:3,children:[(0,Re.jsx)(jf,{}),(0,Re.jsx)(ut.__experimentalVStack,{spacing:3,role:"list",children:t.map(c=>c.render?(0,Re.jsx)(c.render,{slug:c.slug,name:c.name,description:c.description,type:c.type,logo:c.logo,authentication:c.authentication,plugin:c.plugin},c.slug):null)})]}),o&&!e&&(0,Re.jsx)("p",{children:(0,Vf.createInterpolateElement)((0,At.__)("If the connector you need is not listed, search the plugin directory to see if a connector is available."),{a:(0,Re.jsx)("a",{href:"plugin-install.php?s=connector&tab=search&type=tag"})})})]})})}function Zh(){return(0,Re.jsx)(qh,{})}var Qh=Zh;export{Qh as stage}; /*! Bundled license information: use-sync-external-store/cjs/use-sync-external-store-shim.production.js: diff --git a/src/wp-includes/build/routes/font-list/content.js b/src/wp-includes/build/routes/font-list/content.js index 9683f74f08a9b..6f0404e093d80 100644 --- a/src/wp-includes/build/routes/font-list/content.js +++ b/src/wp-includes/build/routes/font-list/content.js @@ -78,7 +78,7 @@ var require_use_sync_external_store_shim_development = __commonJS({ return x2 === y2 && (0 !== x2 || 1 / x2 === 1 / y2) || x2 !== x2 && y2 !== y2; } function useSyncExternalStore$2(subscribe, getSnapshot) { - didWarnOld18Alpha || void 0 === React49.startTransition || (didWarnOld18Alpha = true, console.error( + didWarnOld18Alpha || void 0 === React48.startTransition || (didWarnOld18Alpha = true, console.error( "You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release." )); var value = getSnapshot(); @@ -126,8 +126,8 @@ var require_use_sync_external_store_shim_development = __commonJS({ return getSnapshot(); } "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error()); - var React49 = require_react(), objectIs = "function" === typeof Object.is ? Object.is : is, useState28 = React49.useState, useEffect20 = React49.useEffect, useLayoutEffect4 = React49.useLayoutEffect, useDebugValue2 = React49.useDebugValue, didWarnOld18Alpha = false, didWarnUncachedGetSnapshot = false, shim = "undefined" === typeof window || "undefined" === typeof window.document || "undefined" === typeof window.document.createElement ? useSyncExternalStore$1 : useSyncExternalStore$2; - exports.useSyncExternalStore = void 0 !== React49.useSyncExternalStore ? React49.useSyncExternalStore : shim; + var React48 = require_react(), objectIs = "function" === typeof Object.is ? Object.is : is, useState28 = React48.useState, useEffect20 = React48.useEffect, useLayoutEffect4 = React48.useLayoutEffect, useDebugValue2 = React48.useDebugValue, didWarnOld18Alpha = false, didWarnUncachedGetSnapshot = false, shim = "undefined" === typeof window || "undefined" === typeof window.document || "undefined" === typeof window.document.createElement ? useSyncExternalStore$1 : useSyncExternalStore$2; + exports.useSyncExternalStore = void 0 !== React48.useSyncExternalStore ? React48.useSyncExternalStore : shim; "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error()); })(); } @@ -154,14 +154,14 @@ var require_with_selector_development = __commonJS({ return x2 === y2 && (0 !== x2 || 1 / x2 === 1 / y2) || x2 !== x2 && y2 !== y2; } "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error()); - var React49 = require_react(), shim = require_shim(), objectIs = "function" === typeof Object.is ? Object.is : is, useSyncExternalStore2 = shim.useSyncExternalStore, useRef23 = React49.useRef, useEffect20 = React49.useEffect, useMemo30 = React49.useMemo, useDebugValue2 = React49.useDebugValue; + var React48 = require_react(), shim = require_shim(), objectIs = "function" === typeof Object.is ? Object.is : is, useSyncExternalStore3 = shim.useSyncExternalStore, useRef22 = React48.useRef, useEffect20 = React48.useEffect, useMemo32 = React48.useMemo, useDebugValue2 = React48.useDebugValue; exports.useSyncExternalStoreWithSelector = function(subscribe, getSnapshot, getServerSnapshot, selector, isEqual) { - var instRef = useRef23(null); + var instRef = useRef22(null); if (null === instRef.current) { var inst = { hasValue: false, value: null }; instRef.current = inst; } else inst = instRef.current; - instRef = useMemo30( + instRef = useMemo32( function() { function memoizedSelector(nextSnapshot) { if (!hasMemo) { @@ -196,7 +196,7 @@ var require_with_selector_development = __commonJS({ }, [getSnapshot, getServerSnapshot, selector, isEqual] ); - var value = useSyncExternalStore2(subscribe, instRef[0], instRef[1]); + var value = useSyncExternalStore3(subscribe, instRef[0], instRef[1]); useEffect20( function() { inst.hasValue = true; @@ -498,16 +498,16 @@ function clsx() { var clsx_default = clsx; // node_modules/@base-ui/utils/safeReact.mjs -var React2 = __toESM(require_react(), 1); +var React = __toESM(require_react(), 1); var SafeReact = { - ...React2 + ...React }; // node_modules/@base-ui/utils/useRefWithInit.mjs -var React3 = __toESM(require_react(), 1); +var React2 = __toESM(require_react(), 1); var UNINITIALIZED = {}; function useRefWithInit(init, initArg) { - const ref = React3.useRef(UNINITIALIZED); + const ref = React2.useRef(UNINITIALIZED); if (ref.current === UNINITIALIZED) { ref.current = init(initArg); } @@ -547,12 +547,6 @@ function assertNotCalled() { } } -// node_modules/@base-ui/utils/useIsoLayoutEffect.mjs -var React4 = __toESM(require_react(), 1); -var noop = () => { -}; -var useIsoLayoutEffect = typeof document !== "undefined" ? React4.useLayoutEffect : noop; - // node_modules/@base-ui/utils/warn.mjs var set; if (true) { @@ -568,17 +562,14 @@ function warn(...messages) { } } -// node_modules/@base-ui/react/internals/direction-context/DirectionContext.mjs -var React5 = __toESM(require_react(), 1); -var DirectionContext = /* @__PURE__ */ React5.createContext(void 0); -if (true) DirectionContext.displayName = "DirectionContext"; -function useDirection() { - const context = React5.useContext(DirectionContext); - return context?.direction ?? "ltr"; -} +// node_modules/@base-ui/utils/useIsoLayoutEffect.mjs +var React3 = __toESM(require_react(), 1); +var noop = () => { +}; +var useIsoLayoutEffect = typeof document !== "undefined" ? React3.useLayoutEffect : noop; // node_modules/@base-ui/react/internals/useRenderElement.mjs -var React8 = __toESM(require_react(), 1); +var React6 = __toESM(require_react(), 1); // node_modules/@base-ui/utils/useMergedRefs.mjs function useMergedRefs(a2, b2, c2, d2) { @@ -653,7 +644,7 @@ function update(forkRef, refs) { if (typeof cleanupCallback === "function") { cleanupCallback(); } else { - ref(null); + void ref(null); } break; } @@ -670,18 +661,18 @@ function update(forkRef, refs) { } // node_modules/@base-ui/utils/getReactElementRef.mjs -var React7 = __toESM(require_react(), 1); +var React5 = __toESM(require_react(), 1); // node_modules/@base-ui/utils/reactVersion.mjs -var React6 = __toESM(require_react(), 1); -var majorVersion = parseInt(React6.version, 10); +var React4 = __toESM(require_react(), 1); +var majorVersion = parseInt(React4.version, 10); function isReactVersionAtLeast(reactVersionToCheck) { return majorVersion >= reactVersionToCheck; } // node_modules/@base-ui/utils/getReactElementRef.mjs function getReactElementRef(element) { - if (!/* @__PURE__ */ React7.isValidElement(element)) { + if (!/* @__PURE__ */ React5.isValidElement(element)) { return null; } const reactElement = element; @@ -919,17 +910,17 @@ function useRenderElementProps(componentProps, params = {}) { state = EMPTY_OBJECT, ref, props, - stateAttributesMapping: stateAttributesMapping3, + stateAttributesMapping, enabled = true } = params; const className = enabled ? resolveClassName(classNameProp, state) : void 0; const style = enabled ? resolveStyle(styleProp, state) : void 0; - const stateProps = enabled ? getStateAttributesProps(state, stateAttributesMapping3) : EMPTY_OBJECT; + const stateProps = enabled ? getStateAttributesProps(state, stateAttributesMapping) : EMPTY_OBJECT; const resolvedProps = enabled && props ? resolveRenderFunctionProps(props) : void 0; const outProps = enabled ? mergeObjects(stateProps, resolvedProps) ?? {} : EMPTY_OBJECT; if (typeof document !== "undefined") { if (!enabled) { - useMergedRefs(null, null); + void useMergedRefs(null, null); } else if (Array.isArray(ref)) { outProps.ref = useMergedRefsN([outProps.ref, getReactElementRef(renderProp), ...ref]); } else { @@ -968,15 +959,15 @@ function evaluateRenderProp(element, render, props, state) { mergedProps.ref = props.ref; let newElement = render; if (newElement?.$$typeof === REACT_LAZY_TYPE) { - const children = React8.Children.toArray(render); + const children = React6.Children.toArray(render); newElement = children[0]; } if (true) { - if (!/* @__PURE__ */ React8.isValidElement(newElement)) { + if (!/* @__PURE__ */ React6.isValidElement(newElement)) { throw new Error(["Base UI: The `render` prop was provided an invalid React element as `React.isValidElement(render)` is `false`.", "A valid React element must be provided to the `render` prop because it is cloned with props to replace the default element.", "https://base-ui.com/r/invalid-render-prop"].join("\n")); } } - return /* @__PURE__ */ React8.cloneElement(newElement, mergedProps); + return /* @__PURE__ */ React6.cloneElement(newElement, mergedProps); } if (element) { if (typeof element === "string") { @@ -1013,16 +1004,16 @@ function renderTag(Tag, props) { key: props.key }); } - return /* @__PURE__ */ React8.createElement(Tag, props); + return /* @__PURE__ */ React6.createElement(Tag, props); } // node_modules/@base-ui/utils/useId.mjs -var React9 = __toESM(require_react(), 1); +var React7 = __toESM(require_react(), 1); var globalId = 0; function useGlobalId(idOverride, prefix = "mui") { - const [defaultId, setDefaultId] = React9.useState(idOverride); + const [defaultId, setDefaultId] = React7.useState(idOverride); const id = idOverride || defaultId; - React9.useEffect(() => { + React7.useEffect(() => { if (defaultId == null) { globalId += 1; setDefaultId(`${prefix}-${globalId}`); @@ -1146,17 +1137,16 @@ function createChangeEventDetails(reason, event, trigger, customProperties) { } // node_modules/@base-ui/react/internals/useTransitionStatus.mjs -var React11 = __toESM(require_react(), 1); +var React9 = __toESM(require_react(), 1); // node_modules/@base-ui/utils/useOnMount.mjs -var React10 = __toESM(require_react(), 1); -var EMPTY = []; +var React8 = __toESM(require_react(), 1); function useOnMount(fn) { - React10.useEffect(fn, EMPTY); + React8.useEffect(fn, EMPTY_ARRAY); } // node_modules/@base-ui/utils/useAnimationFrame.mjs -var EMPTY2 = null; +var EMPTY = null; var LAST_RAF = globalThis.requestAnimationFrame; var Scheduler = class { /* This implementation uses an array as a backing data-structure for frame callbacks. @@ -1216,21 +1206,21 @@ var AnimationFrame = class _AnimationFrame { static cancel(id) { return scheduler.cancel(id); } - currentId = EMPTY2; + currentId = EMPTY; /** * Executes `fn` after `delay`, clearing any previously scheduled call. */ request(fn) { this.cancel(); this.currentId = scheduler.request(() => { - this.currentId = EMPTY2; + this.currentId = EMPTY; fn(); }); } cancel = () => { - if (this.currentId !== EMPTY2) { + if (this.currentId !== EMPTY) { scheduler.cancel(this.currentId); - this.currentId = EMPTY2; + this.currentId = EMPTY; } }; disposeEffect = () => { @@ -1245,8 +1235,8 @@ function useAnimationFrame() { // node_modules/@base-ui/react/internals/useTransitionStatus.mjs function useTransitionStatus(open, enableIdleState = false, deferEndingState = false) { - const [transitionStatus, setTransitionStatus] = React11.useState(open && enableIdleState ? "idle" : void 0); - const [mounted, setMounted] = React11.useState(open); + const [transitionStatus, setTransitionStatus] = React9.useState(open && enableIdleState ? "idle" : void 0); + const [mounted, setMounted] = React9.useState(open); if (open && !mounted) { setMounted(true); setTransitionStatus("starting"); @@ -1307,10 +1297,10 @@ var TransitionStatusDataAttributes = /* @__PURE__ */ (function(TransitionStatusD return TransitionStatusDataAttributes2; })({}); var STARTING_HOOK = { - [TransitionStatusDataAttributes.startingStyle]: "" + "data-starting-style": "" }; var ENDING_HOOK = { - [TransitionStatusDataAttributes.endingStyle]: "" + "data-ending-style": "" }; var transitionStatusMapping = { transitionStatus(value) { @@ -1480,6 +1470,11 @@ function getFrameElement(win) { return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null; } +// node_modules/@base-ui/utils/owner.mjs +function ownerDocument(node) { + return node?.ownerDocument || document; +} + // node_modules/@base-ui/utils/addEventListener.mjs function addEventListener(target, type, listener, options) { target.addEventListener(type, listener, options); @@ -1506,13 +1501,8 @@ function createLatestRef(value) { return latest; } -// node_modules/@base-ui/utils/owner.mjs -function ownerDocument(node) { - return node?.ownerDocument || document; -} - // node_modules/@base-ui/react/internals/useOpenChangeComplete.mjs -var React12 = __toESM(require_react(), 1); +var React10 = __toESM(require_react(), 1); // node_modules/@base-ui/react/internals/useAnimationsFinished.mjs var ReactDOM = __toESM(require_react_dom(), 1); @@ -1526,7 +1516,7 @@ function resolveRef(maybeRef) { } // node_modules/@base-ui/react/internals/useAnimationsFinished.mjs -function useAnimationsFinished(elementOrRef, waitForStartingStyleRemoved = false, treatAbortedAsFinished = true) { +function useAnimationsFinished(elementOrRef, waitForStartingStyleRemoved = false) { const frame = useAnimationFrame(); return useStableCallback((fnToExecute, signal = null) => { frame.cancel(); @@ -1547,21 +1537,20 @@ function useAnimationsFinished(elementOrRef, waitForStartingStyleRemoved = false if (!signal?.aborted) { done(); } - }).catch(() => { - if (treatAbortedAsFinished) { - if (!signal?.aborted) { - done(); - } + }, () => { + if (signal?.aborted) { return; } const currentAnimations = resolvedElement.getAnimations(); - if (!signal?.aborted && currentAnimations.length > 0 && currentAnimations.some((animation) => animation.pending || animation.playState !== "finished")) { + if (currentAnimations.some((animation) => animation.pending || animation.playState !== "finished")) { exec(); + return; } + done(); }); } if (waitForStartingStyleRemoved) { - const startingStyleAttribute = TransitionStatusDataAttributes.startingStyle; + const startingStyleAttribute = "data-starting-style"; if (!resolvedElement.hasAttribute(startingStyleAttribute)) { frame.request(exec); return; @@ -1594,8 +1583,8 @@ function useOpenChangeComplete(parameters) { onComplete: onCompleteParam } = parameters; const onComplete = useStableCallback(onCompleteParam); - const runOnceAnimationsFinish = useAnimationsFinished(ref, open, false); - React12.useEffect(() => { + const runOnceAnimationsFinish = useAnimationsFinished(ref, open); + React10.useEffect(() => { if (!enabled) { return void 0; } @@ -1607,16 +1596,6 @@ function useOpenChangeComplete(parameters) { }, [enabled, open, onComplete, runOnceAnimationsFinish]); } -// node_modules/@base-ui/utils/useOnFirstRender.mjs -var React13 = __toESM(require_react(), 1); -function useOnFirstRender(fn) { - const ref = React13.useRef(true); - if (ref.current) { - ref.current = false; - fn(); - } -} - // node_modules/@base-ui/utils/platform/parts.mjs var parts_exports = {}; __export(parts_exports, { @@ -1708,29 +1687,29 @@ __export(env_exports, { var jsdom = /jsdom|happydom/.test(lowerUserAgent); // node_modules/@base-ui/utils/useTimeout.mjs -var EMPTY3 = 0; +var EMPTY2 = 0; var Timeout = class _Timeout { static create() { return new _Timeout(); } - currentId = EMPTY3; + currentId = EMPTY2; /** * Executes `fn` after `delay`, clearing any previously scheduled call. */ start(delay, fn) { this.clear(); this.currentId = setTimeout(() => { - this.currentId = EMPTY3; + this.currentId = EMPTY2; fn(); }, delay); } isStarted() { - return this.currentId !== EMPTY3; + return this.currentId !== EMPTY2; } clear = () => { - if (this.currentId !== EMPTY3) { + if (this.currentId !== EMPTY2) { clearTimeout(this.currentId); - this.currentId = EMPTY3; + this.currentId = EMPTY2; } }; disposeEffect = () => { @@ -1744,7 +1723,7 @@ function useTimeout() { } // node_modules/@base-ui/react/floating-ui-react/components/FloatingDelayGroup.mjs -var React14 = __toESM(require_react(), 1); +var React11 = __toESM(require_react(), 1); // node_modules/@base-ui/react/floating-ui-react/utils/event.mjs function isReactEvent(event) { @@ -1878,7 +1857,7 @@ function isHoverOpenEvent(openEventType) { // node_modules/@base-ui/react/floating-ui-react/components/FloatingDelayGroup.mjs var import_jsx_runtime = __toESM(require_jsx_runtime(), 1); -var FloatingDelayGroupContext = /* @__PURE__ */ React14.createContext({ +var FloatingDelayGroupContext = /* @__PURE__ */ React11.createContext({ hasProvider: false, timeoutMs: 0, delayRef: { @@ -1905,10 +1884,10 @@ function FloatingDelayGroup(props) { delay, timeoutMs = 0 } = props; - const delayRef = React14.useRef(delay); - const initialDelayRef = React14.useRef(delay); - const currentIdRef = React14.useRef(null); - const currentContextRef = React14.useRef(null); + const delayRef = React11.useRef(delay); + const initialDelayRef = React11.useRef(delay); + const currentIdRef = React11.useRef(null); + const currentContextRef = React11.useRef(null); const timeout = useTimeout(); useIsoLayoutEffect(() => { initialDelayRef.current = delay; @@ -1922,7 +1901,7 @@ function FloatingDelayGroup(props) { }; }, [delay, currentIdRef, delayRef, initialDelayRef]); return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FloatingDelayGroupContext.Provider, { - value: React14.useMemo(() => ({ + value: React11.useMemo(() => ({ hasProvider: true, delayRef, initialDelayRef, @@ -1942,7 +1921,7 @@ function useDelayGroup(context, options = { } = options; const store = "rootStore" in context ? context.rootStore : context; const floatingId = store.useState("floatingId"); - const groupContext = React14.useContext(FloatingDelayGroupContext); + const groupContext = React11.useContext(FloatingDelayGroupContext); const { currentIdRef, delayRef, @@ -1952,22 +1931,13 @@ function useDelayGroup(context, options = { hasProvider, timeout } = groupContext; - const [isInstantPhase, setIsInstantPhase] = React14.useState(false); - const openRef = React14.useRef(open); - const isUnmountedRef = React14.useRef(false); + const [isInstantPhase, setIsInstantPhase] = React11.useState(false); + const openRef = React11.useRef(open); useIsoLayoutEffect(() => { openRef.current = open; }, [open]); - useIsoLayoutEffect(() => { - return () => { - isUnmountedRef.current = true; - }; - }, []); useIsoLayoutEffect(() => { function unset() { - if (!isUnmountedRef.current) { - setIsInstantPhase(false); - } currentContextRef.current?.setIsInstantPhase(false); currentIdRef.current = null; currentContextRef.current = null; @@ -2035,7 +2005,7 @@ function useDelayGroup(context, options = { } }; }, [currentContextRef, currentIdRef, delayRef, floatingId, initialDelayRef, timeout]); - return React14.useMemo(() => ({ + return React11.useMemo(() => ({ hasProvider, delayRef, isInstantPhase @@ -2055,7 +2025,7 @@ function mergeCleanups(...cleanups) { } // node_modules/@base-ui/react/utils/FocusGuard.mjs -var React15 = __toESM(require_react(), 1); +var React12 = __toESM(require_react(), 1); // node_modules/@base-ui/utils/visuallyHidden.mjs var visuallyHiddenBase = { @@ -2081,8 +2051,8 @@ var visuallyHiddenInput = { // node_modules/@base-ui/react/utils/FocusGuard.mjs var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1); -var FocusGuard = /* @__PURE__ */ React15.forwardRef(function FocusGuard2(props, ref) { - const [role, setRole] = React15.useState(); +var FocusGuard = /* @__PURE__ */ React12.forwardRef(function FocusGuard2(props, ref) { + const [role, setRole] = React12.useState(); useIsoLayoutEffect(() => { if (parts_exports.screenReader.voiceOver && parts_exports.engine.webkit) { setRole("button"); @@ -2105,7 +2075,6 @@ var FocusGuard = /* @__PURE__ */ React15.forwardRef(function FocusGuard2(props, if (true) FocusGuard.displayName = "FocusGuard"; // node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs -var sides = ["top", "right", "bottom", "left"]; var min = Math.min; var max = Math.max; var round = Math.round; @@ -2427,7 +2396,7 @@ function createAttribute(name2) { } // node_modules/@base-ui/react/floating-ui-react/components/FloatingPortal.mjs -var React16 = __toESM(require_react(), 1); +var React13 = __toESM(require_react(), 1); var ReactDOM2 = __toESM(require_react_dom(), 1); // node_modules/@base-ui/react/internals/constants.mjs @@ -2452,9 +2421,9 @@ var ownerVisuallyHidden = { // node_modules/@base-ui/react/floating-ui-react/components/FloatingPortal.mjs var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1); -var PortalContext = /* @__PURE__ */ React16.createContext(null); +var PortalContext = /* @__PURE__ */ React13.createContext(null); if (true) PortalContext.displayName = "PortalContext"; -var usePortalContext = () => React16.useContext(PortalContext); +var usePortalContext = () => React13.useContext(PortalContext); var attr = createAttribute("portal"); function useFloatingPortalNode(props = {}) { const { @@ -2466,14 +2435,14 @@ function useFloatingPortalNode(props = {}) { const uniqueId = useId(); const portalContext = usePortalContext(); const parentPortalNode = portalContext?.portalNode; - const [containerElement, setContainerElement] = React16.useState(null); - const [portalNode, setPortalNode] = React16.useState(null); + const [containerElement, setContainerElement] = React13.useState(null); + const [portalNode, setPortalNode] = React13.useState(null); const setPortalNodeRef = useStableCallback((node) => { if (node !== null) { setPortalNode(node); } }); - const containerRef = React16.useRef(null); + const containerRef = React13.useRef(null); useIsoLayoutEffect(() => { if (containerProp === null) { if (containerRef.current) { @@ -2483,9 +2452,6 @@ function useFloatingPortalNode(props = {}) { } return; } - if (uniqueId == null) { - return; - } const resolvedContainer = (containerProp && (isNode(containerProp) ? containerProp : containerProp.current)) ?? parentPortalNode ?? document.body; if (resolvedContainer == null) { if (containerRef.current) { @@ -2500,7 +2466,7 @@ function useFloatingPortalNode(props = {}) { setPortalNode(null); setContainerElement(resolvedContainer); } - }, [containerProp, parentPortalNode, uniqueId]); + }, [containerProp, parentPortalNode]); const portalElement = useRenderElement("div", componentProps, { ref: [ref, setPortalNodeRef], props: [{ @@ -2510,39 +2476,42 @@ function useFloatingPortalNode(props = {}) { }); const portalSubtree = containerElement && portalElement ? /* @__PURE__ */ ReactDOM2.createPortal(portalElement, containerElement) : null; return { - portalNode, - portalSubtree + node: portalNode, + // `id` and `render` props can override or remove the generated ID. Use the exact + // rendered value so `aria-owns` never points at an ID absent from the DOM. + nodeId: /* @__PURE__ */ React13.isValidElement(portalElement) ? portalElement.props.id : void 0, + subtree: portalSubtree }; } -var FloatingPortal = /* @__PURE__ */ React16.forwardRef(function FloatingPortal2(componentProps, forwardedRef) { +var FloatingPortal = /* @__PURE__ */ React13.forwardRef(function FloatingPortal2(componentProps, forwardedRef) { const { render, className, style, children, container, - renderGuards, ...elementProps } = componentProps; const { - portalNode, - portalSubtree + node: portalNode, + nodeId: portalNodeId, + subtree: portalSubtree } = useFloatingPortalNode({ container, ref: forwardedRef, componentProps, elementProps }); - const beforeOutsideRef = React16.useRef(null); - const afterOutsideRef = React16.useRef(null); - const beforeInsideRef = React16.useRef(null); - const afterInsideRef = React16.useRef(null); - const [focusManagerState, setFocusManagerState] = React16.useState(null); - const focusInsideDisabledRef = React16.useRef(false); + const beforeOutsideRef = React13.useRef(null); + const afterOutsideRef = React13.useRef(null); + const beforeInsideRef = React13.useRef(null); + const afterInsideRef = React13.useRef(null); + const [focusManagerState, setFocusManagerState] = React13.useState(null); + const focusInsideDisabledRef = React13.useRef(false); const modal = focusManagerState?.modal; const open = focusManagerState?.open; - const shouldRenderGuards = typeof renderGuards === "boolean" ? renderGuards : !!focusManagerState && !focusManagerState.modal && focusManagerState.open && !!portalNode; - React16.useEffect(() => { + const shouldRenderGuards = !!focusManagerState && !focusManagerState.modal && focusManagerState.open && !!portalNode; + React13.useEffect(() => { if (!portalNode || modal) { return void 0; } @@ -2568,7 +2537,7 @@ var FloatingPortal = /* @__PURE__ */ React16.forwardRef(function FloatingPortal2 enableFocusInside(portalNode); focusInsideDisabledRef.current = false; }, [open, portalNode]); - const portalContextValue = React16.useMemo(() => ({ + const portalContextValue = React13.useMemo(() => ({ beforeOutsideRef, afterOutsideRef, beforeInsideRef, @@ -2576,7 +2545,7 @@ var FloatingPortal = /* @__PURE__ */ React16.forwardRef(function FloatingPortal2 portalNode, setFocusManagerState }), [portalNode]); - return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(React16.Fragment, { + return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(React13.Fragment, { children: [portalSubtree, /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(PortalContext.Provider, { value: portalContextValue, children: [shouldRenderGuards && portalNode && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(FocusGuard, { @@ -2592,7 +2561,7 @@ var FloatingPortal = /* @__PURE__ */ React16.forwardRef(function FloatingPortal2 } } }), shouldRenderGuards && portalNode && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { - "aria-owns": portalNode.id, + "aria-owns": portalNodeId, style: ownerVisuallyHidden }), portalNode && /* @__PURE__ */ ReactDOM2.createPortal(children, portalNode), shouldRenderGuards && portalNode && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(FocusGuard, { "data-type": "outside", @@ -2616,7 +2585,7 @@ var FloatingPortal = /* @__PURE__ */ React16.forwardRef(function FloatingPortal2 if (true) FloatingPortal.displayName = "FloatingPortal"; // node_modules/@base-ui/react/floating-ui-react/components/FloatingTree.mjs -var React17 = __toESM(require_react(), 1); +var React14 = __toESM(require_react(), 1); // node_modules/@base-ui/react/floating-ui-react/utils/createEventEmitter.mjs function createEventEmitter() { @@ -2639,18 +2608,18 @@ function createEventEmitter() { // node_modules/@base-ui/react/floating-ui-react/components/FloatingTree.mjs var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1); -var FloatingNodeContext = /* @__PURE__ */ React17.createContext(null); +var FloatingNodeContext = /* @__PURE__ */ React14.createContext(null); if (true) FloatingNodeContext.displayName = "FloatingNodeContext"; -var FloatingTreeContext = /* @__PURE__ */ React17.createContext(null); +var FloatingTreeContext = /* @__PURE__ */ React14.createContext(null); if (true) FloatingTreeContext.displayName = "FloatingTreeContext"; -var useFloatingParentNodeId = () => React17.useContext(FloatingNodeContext)?.id || null; +var useFloatingParentNodeId = () => React14.useContext(FloatingNodeContext)?.id || null; var useFloatingTree = (externalTree) => { - const contextTree = React17.useContext(FloatingTreeContext); + const contextTree = React14.useContext(FloatingTreeContext); return externalTree ?? contextTree; }; // node_modules/@base-ui/react/floating-ui-react/hooks/useClientPoint.mjs -var React18 = __toESM(require_react(), 1); +var React15 = __toESM(require_react(), 1); function createVirtualElement(domElement, data) { let offsetX = null; let offsetY = null; @@ -2717,10 +2686,10 @@ function useClientPoint(context, props = {}) { const floating = store.useState("floatingElement"); const domReference = store.useState("domReferenceElement"); const dataRef = store.context.dataRef; - const initialRef = React18.useRef(false); - const cleanupListenerRef = React18.useRef(null); - const [pointerType, setPointerType] = React18.useState(); - const [reactive, setReactive] = React18.useState([]); + const initialRef = React15.useRef(false); + const cleanupListenerRef = React15.useRef(null); + const [pointerType, setPointerType] = React15.useState(); + const [reactive, setReactive] = React15.useState([]); const resetReference = useStableCallback((reference2) => { store.set("positionReference", reference2); }); @@ -2748,7 +2717,7 @@ function useClientPoint(context, props = {}) { } }); const openCheck = isMouseLikePointerType(pointerType) ? floating : open; - React18.useEffect(() => { + React15.useEffect(() => { if (!enabled) { resetReference(domReference); return void 0; @@ -2776,20 +2745,20 @@ function useClientPoint(context, props = {}) { } return cleanupListener; }, [openCheck, enabled, floating, dataRef, domReference, store, setReference, resetReference, reactive]); - React18.useEffect(() => () => { + React15.useEffect(() => () => { store.set("positionReference", null); }, [store]); - React18.useEffect(() => { + React15.useEffect(() => { if (enabled && !floating) { initialRef.current = false; } }, [enabled, floating]); - React18.useEffect(() => { + React15.useEffect(() => { if (!enabled && open) { initialRef.current = true; } }, [enabled, open]); - const reference = React18.useMemo(() => { + const reference = React15.useMemo(() => { function setPointerTypeRef(event) { setPointerType(event.pointerType); } @@ -2800,14 +2769,14 @@ function useClientPoint(context, props = {}) { onMouseEnter: handleReferenceEnterOrMove }; }, [handleReferenceEnterOrMove]); - return React18.useMemo(() => enabled ? { + return React15.useMemo(() => enabled ? { reference, trigger: reference } : {}, [enabled, reference]); } // node_modules/@base-ui/react/floating-ui-react/hooks/useDismiss.mjs -var React19 = __toESM(require_react(), 1); +var React16 = __toESM(require_react(), 1); function alwaysFalse() { return false; } @@ -2842,12 +2811,12 @@ function useDismiss(context, props = {}) { escapeKey: escapeKeyBubbles, outsidePress: outsidePressBubbles } = normalizeProp(bubbles); - const pressStartedInsideRef = React19.useRef(false); - const pressStartPreventedRef = React19.useRef(false); - const suppressNextOutsideClickRef = React19.useRef(false); - const isComposingRef = React19.useRef(false); - const currentPointerTypeRef = React19.useRef(""); - const touchStateRef = React19.useRef(null); + const pressStartedInsideRef = React16.useRef(false); + const pressStartPreventedRef = React16.useRef(false); + const suppressNextOutsideClickRef = React16.useRef(false); + const isComposingRef = React16.useRef(false); + const currentPointerTypeRef = React16.useRef(""); + const touchStateRef = React16.useRef(null); const cancelDismissOnEndTimeout = useTimeout(); const clearInsideReactTreeTimeout = useTimeout(); const clearInsideReactTree = useStableCallback(() => { @@ -2916,9 +2885,9 @@ function useDismiss(context, props = {}) { pressStartPreventedRef.current = true; } }); - React19.useEffect(() => { + React16.useEffect(() => { if (!open || !enabled) { - return void 0; + return clearInsideReactTree; } dataRef.current.__escapeKeyBubbles = escapeKeyBubbles; dataRef.current.__outsidePressBubbles = outsidePressBubbles; @@ -3164,15 +3133,15 @@ function useDismiss(context, props = {}) { preventedPressSuppressionTimeout.clear(); resetPressStartState(); suppressNextOutsideClickRef.current = false; + clearInsideReactTree(); }; }, [dataRef, floatingElement, escapeKey2, outsidePressEnabled, outsidePress2, open, enabled, escapeKeyBubbles, outsidePressBubbles, closeOnEscapeKeyDown, clearInsideReactTree, getOutsidePressEventProp, hasBlockingChild, isEventWithinOwnElements, tree, store, cancelDismissOnEndTimeout]); - React19.useEffect(clearInsideReactTree, [outsidePress2, clearInsideReactTree]); - const reference = React19.useMemo(() => ({ + const reference = React16.useMemo(() => ({ onKeyDown: closeOnEscapeKeyDown, onPointerDown: closeOnReferencePress, onClick: closeOnReferencePress }), [closeOnEscapeKeyDown, closeOnReferencePress]); - const floating = React19.useMemo(() => ({ + const floating = React16.useMemo(() => ({ onKeyDown: closeOnEscapeKeyDown, // `onMouseDown` may be blocked if `event.preventDefault()` is called in // `onPointerDown`, such as with . @@ -3192,7 +3161,7 @@ function useDismiss(context, props = {}) { onTouchEndCapture: markInsideReactTree, onTouchMoveCapture: markInsideReactTree }), [closeOnEscapeKeyDown, markInsideReactTree, markPressStartedInsideReactTree, markInsidePressStartPrevented]); - return React19.useMemo(() => enabled ? { + return React16.useMemo(() => enabled ? { reference, floating, trigger: reference @@ -3200,7 +3169,7 @@ function useDismiss(context, props = {}) { } // node_modules/@base-ui/react/floating-ui-react/hooks/useFloating.mjs -var React26 = __toESM(require_react(), 1); +var React24 = __toESM(require_react(), 1); // node_modules/@floating-ui/core/dist/floating-ui.core.mjs function computeCoordsFromPlacement(_ref, placement, rtl) { @@ -3504,67 +3473,6 @@ var flip = function(options) { } }; }; -function getSideOffsets(overflow, rect) { - return { - top: overflow.top - rect.height, - right: overflow.right - rect.width, - bottom: overflow.bottom - rect.height, - left: overflow.left - rect.width - }; -} -function isAnySideFullyClipped(overflow) { - return sides.some((side) => overflow[side] >= 0); -} -var hide = function(options) { - if (options === void 0) { - options = {}; - } - return { - name: "hide", - options, - async fn(state) { - const { - rects, - platform: platform3 - } = state; - const { - strategy = "referenceHidden", - ...detectOverflowOptions - } = evaluate(options, state); - switch (strategy) { - case "referenceHidden": { - const overflow = await platform3.detectOverflow(state, { - ...detectOverflowOptions, - elementContext: "reference" - }); - const offsets = getSideOffsets(overflow, rects.reference); - return { - data: { - referenceHiddenOffsets: offsets, - referenceHidden: isAnySideFullyClipped(offsets) - } - }; - } - case "escaped": { - const overflow = await platform3.detectOverflow(state, { - ...detectOverflowOptions, - altBoundary: true - }); - const offsets = getSideOffsets(overflow, rects.floating); - return { - data: { - escapedOffsets: offsets, - escaped: isAnySideFullyClipped(offsets) - } - }; - } - default: { - return {}; - } - } - } - }; -}; var originSides = /* @__PURE__ */ new Set(["left", "top"]); async function convertValueToCoords(state, options) { const { @@ -4431,7 +4339,6 @@ var offset2 = offset; var shift2 = shift; var flip2 = flip; var size2 = size; -var hide2 = hide; var limitShift2 = limitShift; var computePosition2 = (reference, floating, options) => { const cache = /* @__PURE__ */ new Map(); @@ -4448,7 +4355,7 @@ var computePosition2 = (reference, floating, options) => { }; // node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.mjs -var React20 = __toESM(require_react(), 1); +var React17 = __toESM(require_react(), 1); var import_react2 = __toESM(require_react(), 1); var ReactDOM3 = __toESM(require_react_dom(), 1); var isClient = typeof document !== "undefined"; @@ -4514,7 +4421,7 @@ function roundByDPR(element, value) { return Math.round(value * dpr) / dpr; } function useLatestRef(value) { - const ref = React20.useRef(value); + const ref = React17.useRef(value); index(() => { ref.current = value; }); @@ -4537,7 +4444,7 @@ function useFloating(options) { whileElementsMounted, open } = options; - const [data, setData] = React20.useState({ + const [data, setData] = React17.useState({ x: 0, y: 0, strategy, @@ -4545,19 +4452,19 @@ function useFloating(options) { middlewareData: {}, isPositioned: false }); - const [latestMiddleware, setLatestMiddleware] = React20.useState(middleware); + const [latestMiddleware, setLatestMiddleware] = React17.useState(middleware); if (!deepEqual(latestMiddleware, middleware)) { setLatestMiddleware(middleware); } - const [_reference, _setReference] = React20.useState(null); - const [_floating, _setFloating] = React20.useState(null); - const setReference = React20.useCallback((node) => { + const [_reference, _setReference] = React17.useState(null); + const [_floating, _setFloating] = React17.useState(null); + const setReference = React17.useCallback((node) => { if (node !== referenceRef.current) { referenceRef.current = node; _setReference(node); } }, []); - const setFloating = React20.useCallback((node) => { + const setFloating = React17.useCallback((node) => { if (node !== floatingRef.current) { floatingRef.current = node; _setFloating(node); @@ -4565,14 +4472,14 @@ function useFloating(options) { }, []); const referenceEl = externalReference || _reference; const floatingEl = externalFloating || _floating; - const referenceRef = React20.useRef(null); - const floatingRef = React20.useRef(null); - const dataRef = React20.useRef(data); + const referenceRef = React17.useRef(null); + const floatingRef = React17.useRef(null); + const dataRef = React17.useRef(data); const hasWhileElementsMounted = whileElementsMounted != null; const whileElementsMountedRef = useLatestRef(whileElementsMounted); const platformRef = useLatestRef(platform3); const openRef = useLatestRef(open); - const update2 = React20.useCallback(() => { + const update2 = React17.useCallback(() => { if (!referenceRef.current || !floatingRef.current) { return; } @@ -4610,7 +4517,7 @@ function useFloating(options) { })); } }, [open]); - const isMountedRef = React20.useRef(false); + const isMountedRef = React17.useRef(false); index(() => { isMountedRef.current = true; return () => { @@ -4627,17 +4534,17 @@ function useFloating(options) { update2(); } }, [referenceEl, floatingEl, update2, whileElementsMountedRef, hasWhileElementsMounted]); - const refs = React20.useMemo(() => ({ + const refs = React17.useMemo(() => ({ reference: referenceRef, floating: floatingRef, setReference, setFloating }), [setReference, setFloating]); - const elements2 = React20.useMemo(() => ({ + const elements2 = React17.useMemo(() => ({ reference: referenceEl, floating: floatingEl }), [referenceEl, floatingEl]); - const floatingStyles = React20.useMemo(() => { + const floatingStyles = React17.useMemo(() => { const initialStyles = { position: strategy, left: 0, @@ -4663,7 +4570,7 @@ function useFloating(options) { top: y2 }; }, [strategy, transform, elements2.floating, data.x, data.y]); - return React20.useMemo(() => ({ + return React17.useMemo(() => ({ ...data, update: update2, refs, @@ -4710,81 +4617,182 @@ var size3 = (options, deps) => { options: [options, deps] }; }; -var hide3 = (options, deps) => { - const result = hide2(options); - return { - name: result.name, - fn: result.fn, - options: [options, deps] - }; + +// node_modules/@base-ui/react/utils/popups/popupHandle.mjs +var BasePopupHandle = class { + /** + * Stores of every root currently using this handle, in attach order. A handle is meant to be used + * by a single mounted root, but roots can transiently overlap (e.g. during an animated route + * transition), so this stack lets `attachStore`'s cleanup restore the previous root instead of + * leaving a still-mounted root uncontrollable when a newer overlapping root detaches first. + */ + attachedStores = []; + /** + * Store of the root that currently controls the handle: the most recently attached one still + * mounted, or `null` when no root is attached. Imperative methods are no-ops while this is `null`. + */ + attachedStoreValue = null; + /** + * Listeners notified when `attachedStore` changes, so detached triggers can follow the store pointer. + */ + storeListeners = /* @__PURE__ */ new Set(); + /** + * Creates a handle backed by the store used while no root is attached. + * + * @param fallbackStore Inert, closed store handed to detached triggers while no root is attached, + * so they can render and register without a mounted root. Triggers register into whichever store + * `store` currently resolves to, so while detached they live in this store's trigger map and + * migrate themselves to the root's store (and back) as it attaches/detaches. + * @param componentName Component name used to prefix dev warnings, e.g. `'Menu'` produces + * `MenuHandle.open()` in warning text. + * @param throwOnMissingTrigger Whether `open(triggerId)` throws when no trigger with that id is + * registered. Anchored popups (Menu, Popover, Tooltip, PreviewCard) need a trigger to anchor to, + * so they throw; Dialog is not anchored and instead opens unassociated with a dev warning. + */ + constructor(fallbackStore, componentName, throwOnMissingTrigger = true) { + this.fallbackStore = fallbackStore; + this.componentName = componentName; + this.throwOnMissingTrigger = throwOnMissingTrigger; + } + get attachedStore() { + return this.attachedStoreValue; + } + /** + * Store that detached triggers read from: the attached root's store, or an inert fallback store + * used while no root is attached. + * @internal + */ + get store() { + return this.attachedStoreValue ?? this.fallbackStore; + } + /** + * Stable fallback store used for server rendering and hydration. Root stores cannot be recorded on + * the handle during render because a handle can be shared by concurrent server-rendered requests. + * @internal + */ + get serverStore() { + return this.fallbackStore; + } + /** + * Subscribes to changes of the attached store pointer so detached triggers re-render and re-bind + * when a root attaches or detaches. Returns a function that removes the listener. + * @internal + */ + subscribeStore(listener) { + this.storeListeners.add(listener); + return () => { + this.storeListeners.delete(listener); + }; + } + /** + * Points the handle at a root's store and notifies subscribers so detached triggers re-render and + * re-register into it (their registration ref re-fires on the store-pointer change). Returns a + * cleanup function that detaches the store again. + * @internal + */ + attachStore(newStore) { + this.attachedStores.push(newStore); + this.setActiveStore(newStore); + if (true) { + if (this.attachedStores.length > 1) { + const dev = this; + (dev.overlapWarningFrame ??= AnimationFrame.create()).request(() => { + if (this.attachedStores.length > 1) { + console.warn("Base UI: A handle is attached to more than one mounted root at the same time. The most recently mounted root takes over and the previous one stops being controlled by the handle. A handle should be used by a single root that stays mounted for the lifetime of the handle."); + } + }); + } + } + return () => { + const index2 = this.attachedStores.lastIndexOf(newStore); + if (index2 !== -1) { + this.attachedStores.splice(index2, 1); + } + this.setActiveStore(this.attachedStores[this.attachedStores.length - 1] ?? null); + }; + } + /** + * Sets the store that currently controls the handle and notifies subscribers when it changes, so + * detached triggers re-render and migrate their registration to the new store. + */ + setActiveStore(store) { + if (this.attachedStoreValue !== store) { + this.attachedStoreValue = store; + this.storeListeners.forEach((listener) => { + listener(); + }); + } + } + /** + * Opens the attached root's store and associates it with the trigger with the given id, or a + * no-op (with a dev warning) while no root is attached. Shared by every concrete handle's public + * `open()` method, which only narrows the parameter type. + * + * When a trigger id is given but no matching trigger is registered, anchored popups throw (see + * `throwOnMissingTrigger`); Dialog opens unassociated with a dev warning instead. + * + * This method should only be called in an event handler or an effect (not during rendering). + * + * @param triggerId ID of the trigger to associate with the popup, or `null`/`undefined` to open + * without associating any trigger. + */ + openByTrigger(triggerId) { + const attachedStore = this.attachedStore; + if (attachedStore === null) { + if (true) { + console.warn(`Base UI: ${this.componentName}Handle.open() was called while no root using this handle is mounted. The call was ignored; mount a root with this handle before opening it imperatively.`); + } + return; + } + let triggerElement; + if (triggerId) { + for (let i2 = this.attachedStores.length - 1; i2 >= 0 && !triggerElement; i2 -= 1) { + triggerElement = this.attachedStores[i2].context.triggerElements.getById(triggerId); + } + triggerElement ??= this.fallbackStore.context.triggerElements.getById(triggerId); + } + if (triggerId && !triggerElement) { + if (this.throwOnMissingTrigger) { + throw new Error(true ? `Base UI: ${this.componentName}Handle.open() was called with the trigger id "${triggerId}", but no matching trigger is registered with this handle. An anchored popup cannot open without a trigger to anchor to. Pass the id of a mounted ${this.componentName}.Trigger that has this handle set on its "handle" prop.` : formatErrorMessage_default(99, this.componentName, triggerId, this.componentName)); + } + if (true) { + console.warn(`Base UI: ${this.componentName}Handle.open: No trigger found with id "${triggerId}". The popup will open, but the trigger will not be associated with it.`); + } + } + attachedStore.setOpen(true, createChangeEventDetails(reason_parts_exports.imperativeAction, void 0, triggerElement)); + } + /** + * Closes the popup by setting the attached root's store to closed, or a no-op (with a dev warning) + * while no root is attached. Shared by every concrete handle's public `close()` method. + * + * This method should only be called in an event handler or an effect (not during rendering). + */ + closePopup() { + const attachedStore = this.attachedStore; + if (attachedStore === null) { + if (true) { + console.warn(`Base UI: ${this.componentName}Handle.close() was called while no root using this handle is mounted. The call was ignored.`); + } + return; + } + attachedStore.setOpen(false, createChangeEventDetails(reason_parts_exports.imperativeAction)); + } }; // node_modules/@base-ui/react/utils/popups/popupStoreUtils.mjs -var React25 = __toESM(require_react(), 1); +var React22 = __toESM(require_react(), 1); var ReactDOM4 = __toESM(require_react_dom(), 1); // node_modules/@base-ui/react/floating-ui-react/hooks/useSyncedFloatingRootContext.mjs -var React24 = __toESM(require_react(), 1); - -// node_modules/@base-ui/utils/store/createSelector.mjs -var createSelector = (a2, b2, c2, d2, e2, f2, ...other) => { - if (other.length > 0) { - throw new Error(true ? "Unsupported number of selectors" : formatErrorMessage_default(1)); - } - let selector; - if (a2 && b2 && c2 && d2 && e2 && f2) { - selector = (state, a1, a22, a3) => { - const va = a2(state, a1, a22, a3); - const vb = b2(state, a1, a22, a3); - const vc = c2(state, a1, a22, a3); - const vd = d2(state, a1, a22, a3); - const ve = e2(state, a1, a22, a3); - return f2(va, vb, vc, vd, ve, a1, a22, a3); - }; - } else if (a2 && b2 && c2 && d2 && e2) { - selector = (state, a1, a22, a3) => { - const va = a2(state, a1, a22, a3); - const vb = b2(state, a1, a22, a3); - const vc = c2(state, a1, a22, a3); - const vd = d2(state, a1, a22, a3); - return e2(va, vb, vc, vd, a1, a22, a3); - }; - } else if (a2 && b2 && c2 && d2) { - selector = (state, a1, a22, a3) => { - const va = a2(state, a1, a22, a3); - const vb = b2(state, a1, a22, a3); - const vc = c2(state, a1, a22, a3); - return d2(va, vb, vc, a1, a22, a3); - }; - } else if (a2 && b2 && c2) { - selector = (state, a1, a22, a3) => { - const va = a2(state, a1, a22, a3); - const vb = b2(state, a1, a22, a3); - return c2(va, vb, a1, a22, a3); - }; - } else if (a2 && b2) { - selector = (state, a1, a22, a3) => { - const va = a2(state, a1, a22, a3); - return b2(va, a1, a22, a3); - }; - } else if (a2) { - selector = a2; - } else { - throw ( - /* minify-error-disabled */ - new Error("Missing arguments") - ); - } - return selector; -}; +var React21 = __toESM(require_react(), 1); // node_modules/@base-ui/utils/store/useStore.mjs -var React22 = __toESM(require_react(), 1); +var React19 = __toESM(require_react(), 1); var import_shim = __toESM(require_shim(), 1); var import_with_selector = __toESM(require_with_selector(), 1); // node_modules/@base-ui/utils/fastHooks.mjs -var React21 = __toESM(require_react(), 1); +var React18 = __toESM(require_react(), 1); var hooks = []; var currentInstance = void 0; function getInstance() { @@ -4816,7 +4824,7 @@ function fastComponent(fn) { return FastComponent; } function fastComponentRef(fn) { - return /* @__PURE__ */ React21.forwardRef(fastComponent(fn)); + return /* @__PURE__ */ React18.forwardRef(fastComponent(fn)); } function createInstance() { return { @@ -4831,7 +4839,7 @@ function useStore(store, selector, a1, a2, a3) { return useStoreImplementation(store, selector, a1, a2, a3); } function useStoreR19(store, selector, a1, a2, a3) { - const getSelection = React22.useCallback(() => selector(store.getSnapshot(), a1, a2, a3), [store, selector, a1, a2, a3]); + const getSelection = React19.useCallback(() => selector(store.getSnapshot(), a1, a2, a3), [store, selector, a1, a2, a3]); return (0, import_shim.useSyncExternalStore)(store.subscribe, getSelection, getSelection); } register({ @@ -5018,7 +5026,7 @@ var Store = class { }; // node_modules/@base-ui/utils/store/ReactStore.mjs -var React23 = __toESM(require_react(), 1); +var React20 = __toESM(require_react(), 1); var ReactStore = class extends Store { /** * Creates a new ReactStore instance. @@ -5042,7 +5050,7 @@ var ReactStore = class extends Store { * by `useState` is updated before the next render (similarly to React's `useState`). */ useSyncedValue(key, value) { - React23.useDebugValue(key); + React20.useDebugValue(key); const store = this; useIsoLayoutEffect(() => { if (store.state[key] !== value) { @@ -5077,8 +5085,8 @@ var ReactStore = class extends Store { useSyncedValues(statePart) { const store = this; if (true) { - React23.useDebugValue(statePart, (p3) => Object.keys(p3)); - const keys = React23.useRef(Object.keys(statePart)).current; + React20.useDebugValue(statePart, (p3) => Object.keys(p3)); + const keys = React20.useRef(Object.keys(statePart)).current; const nextKeys = Object.keys(statePart); if (keys.length !== nextKeys.length || keys.some((key, index2) => key !== nextKeys[index2])) { console.error("ReactStore.useSyncedValues expects the same prop keys on every render. Keys should be stable."); @@ -5094,7 +5102,7 @@ var ReactStore = class extends Store { * is non-undefined, the store's state at `key` is updated to match `controlled`. */ useControlledProp(key, controlled) { - React23.useDebugValue(key); + React20.useDebugValue(key); const store = this; const isControlled = controlled !== void 0; useIsoLayoutEffect(() => { @@ -5132,7 +5140,7 @@ var ReactStore = class extends Store { * @param key Key of the selector to use. */ useState(key, a1, a2, a3) { - React23.useDebugValue(key); + React20.useDebugValue(key); return useStore(this, this.selectors[key], a1, a2, a3); } /** @@ -5143,7 +5151,7 @@ var ReactStore = class extends Store { * @param fn Function to assign. */ useContextCallback(key, fn) { - React23.useDebugValue(key); + React20.useDebugValue(key); const stableFunction = useStableCallback(fn ?? NOOP); this.context[key] = stableFunction; } @@ -5154,7 +5162,7 @@ var ReactStore = class extends Store { * @param key Key of the state to set. */ useStateSetter(key) { - const ref = React23.useRef(void 0); + const ref = React20.useRef(void 0); if (ref.current === void 0) { ref.current = (value) => { this.set(key, value); @@ -5190,12 +5198,12 @@ var ReactStore = class extends Store { // node_modules/@base-ui/react/floating-ui-react/components/FloatingRootStore.mjs var selectors = { - open: createSelector((state) => state.open), - transitionStatus: createSelector((state) => state.transitionStatus), - domReferenceElement: createSelector((state) => state.domReferenceElement), - referenceElement: createSelector((state) => state.positionReference ?? state.referenceElement), - floatingElement: createSelector((state) => state.floatingElement), - floatingId: createSelector((state) => state.floatingId) + open: (state) => state.open, + transitionStatus: (state) => state.transitionStatus, + domReferenceElement: (state) => state.domReferenceElement, + referenceElement: (state) => state.positionReference ?? state.referenceElement, + floatingElement: (state) => state.floatingElement, + floatingId: (state) => state.floatingId }; var FloatingRootStore = class extends ReactStore { constructor(options) { @@ -5276,7 +5284,7 @@ function useSyncedFloatingRootContext(options) { const floatingElement = popupStore.useState(treatPopupAsFloatingElement ? "popupElement" : "positionerElement"); const triggerElements = popupStore.context.triggerElements; const handleOpenChange = onOpenChange; - const internalStoreRef = React24.useRef(null); + const internalStoreRef = React21.useRef(null); if (floatingRootContextProp === void 0 && internalStoreRef.current === null) { internalStoreRef.current = new FloatingRootStore({ open, @@ -5317,14 +5325,10 @@ var FOCUSABLE_POPUP_PROPS = { tabIndex: -1, [FOCUSABLE_ATTRIBUTE]: "" }; -function usePopupStore(externalStore, createStore, treatPopupAsFloatingElement = false) { +function usePopupRootStore(createStore, treatPopupAsFloatingElement = false) { const floatingId = useId(); const nested = useFloatingParentNodeId() != null; - const internalStoreRef = React25.useRef(null); - if (externalStore === void 0 && internalStoreRef.current === null) { - internalStoreRef.current = createStore(floatingId, nested); - } - const store = externalStore ?? internalStoreRef.current; + const store = useRefWithInit(() => createStore(floatingId, nested)).current; useSyncedFloatingRootContext({ popupStore: store, treatPopupAsFloatingElement, @@ -5333,15 +5337,21 @@ function usePopupStore(externalStore, createStore, treatPopupAsFloatingElement = nested, onOpenChange: store.setOpen }); - return { - store, - internalStore: internalStoreRef.current - }; + return store; +} +function PopupHandleAttachment({ + handle, + store +}) { + useIsoLayoutEffect(() => { + return handle.attachStore(store); + }, [handle, store]); + return null; } function useTriggerRegistration(id, store) { - const registeredElementIdRef = React25.useRef(null); - const registeredElementRef = React25.useRef(null); - return React25.useCallback((element) => { + const registeredElementIdRef = React22.useRef(null); + const registeredElementRef = React22.useRef(null); + return React22.useCallback((element) => { if (id === void 0) { return; } @@ -5423,26 +5433,10 @@ function applyPopupOpenChange(store, nextOpen, eventDetails, options = {}) { changeState(); } } -function useInitialOpenSync(store, openProp, defaultOpen, defaultTriggerId) { - useOnFirstRender(() => { - if (openProp === void 0 && store.state.open === false && defaultOpen) { - store.state = { - ...store.state, - open: true, - activeTriggerId: defaultTriggerId, - preventUnmountingOnClose: false - }; - } - }); -} function useTriggerDataForwarding(triggerId, triggerElementRef, store, stateUpdates) { const isMountedByThisTrigger = store.useState("isMountedByTrigger", triggerId); const baseRegisterTrigger = useTriggerRegistration(triggerId, store); - const registerTrigger = useStableCallback((element) => { - baseRegisterTrigger(element); - if (!element) { - return; - } + const applyTriggerData = useStableCallback((element) => { const open = store.select("open"); const activeTriggerId = store.select("activeTriggerId"); if (activeTriggerId === triggerId) { @@ -5460,6 +5454,12 @@ function useTriggerDataForwarding(triggerId, triggerElementRef, store, stateUpda }); } }); + const registerTrigger = React22.useCallback((element) => { + baseRegisterTrigger(element); + if (element) { + applyTriggerData(element); + } + }, [baseRegisterTrigger, applyTriggerData]); useIsoLayoutEffect(() => { if (isMountedByThisTrigger) { store.update({ @@ -5477,10 +5477,14 @@ function useImplicitActiveTrigger(store, options = {}) { const { closeOnActiveTriggerUnmount = false } = options; + const resolvedActiveTriggerIdRef = React22.useRef(null); const open = store.useState("open"); const reactiveTriggerCount = store.useState("triggerCount"); + const activeTriggerId = store.useState("activeTriggerId"); + const reactiveActiveTriggerElement = store.useState("activeTriggerElement"); useIsoLayoutEffect(() => { if (!open) { + resolvedActiveTriggerIdRef.current = null; if (store.state.triggerCount !== 0) { store.set("triggerCount", 0); } @@ -5491,22 +5495,42 @@ function useImplicitActiveTrigger(store, options = {}) { if (store.state.triggerCount !== triggerCount) { stateUpdates.triggerCount = triggerCount; } - const activeTriggerId = store.select("activeTriggerId"); + const currentActiveTriggerId = store.select("activeTriggerId"); let lostActiveTriggerId = null; - if (activeTriggerId) { - const activeTriggerElement = store.context.triggerElements.getById(activeTriggerId); + if (currentActiveTriggerId) { + const activeTriggerElement = store.context.triggerElements.getById(currentActiveTriggerId); if (!activeTriggerElement) { - lostActiveTriggerId = activeTriggerId; - } else if (activeTriggerElement !== store.state.activeTriggerElement) { - stateUpdates.activeTriggerElement = activeTriggerElement; + for (const [triggerId, triggerElement] of store.context.triggerElements.entries()) { + if (triggerElement === store.state.activeTriggerElement) { + stateUpdates.activeTriggerId = triggerId; + stateUpdates.activeTriggerElement = triggerElement; + resolvedActiveTriggerIdRef.current = triggerId; + break; + } + } + if (stateUpdates.activeTriggerId === void 0) { + if (resolvedActiveTriggerIdRef.current === currentActiveTriggerId) { + lostActiveTriggerId = currentActiveTriggerId; + } else { + resolvedActiveTriggerIdRef.current = null; + } + } + } else { + resolvedActiveTriggerIdRef.current = currentActiveTriggerId; + if (activeTriggerElement !== store.state.activeTriggerElement) { + stateUpdates.activeTriggerElement = activeTriggerElement; + } } + } else { + resolvedActiveTriggerIdRef.current = null; } - if (!lostActiveTriggerId && !activeTriggerId && triggerCount === 1) { + if (!lostActiveTriggerId && !currentActiveTriggerId && triggerCount === 1) { const iteratorResult = store.context.triggerElements.entries().next(); if (!iteratorResult.done) { const [implicitTriggerId, implicitTriggerElement] = iteratorResult.value; stateUpdates.activeTriggerId = implicitTriggerId; stateUpdates.activeTriggerElement = implicitTriggerElement; + resolvedActiveTriggerIdRef.current = implicitTriggerId; } } if (stateUpdates.triggerCount !== void 0 || stateUpdates.activeTriggerId !== void 0 || stateUpdates.activeTriggerElement !== void 0) { @@ -5528,7 +5552,7 @@ function useImplicitActiveTrigger(store, options = {}) { }); } } - }, [open, store, reactiveTriggerCount, closeOnActiveTriggerUnmount]); + }, [open, store, reactiveTriggerCount, activeTriggerId, reactiveActiveTriggerElement, closeOnActiveTriggerUnmount]); } function useOpenStateTransitions(open, store, onUnmount) { const { @@ -5581,9 +5605,18 @@ function usePopupInteractionProps(store, statePart) { } // node_modules/@base-ui/react/utils/popups/popupTriggerMap.mjs +var devElementIdsByMap; +function getDevElementIds(map) { + devElementIdsByMap ??= /* @__PURE__ */ new WeakMap(); + let elementIds = devElementIdsByMap.get(map); + if (!elementIds) { + elementIds = /* @__PURE__ */ new WeakMap(); + devElementIdsByMap.set(map, elementIds); + } + return elementIds; +} var PopupTriggerMap = class { constructor() { - this.elementsSet = /* @__PURE__ */ new Set(); this.idMap = /* @__PURE__ */ new Map(); } /** @@ -5592,42 +5625,48 @@ var PopupTriggerMap = class { * Note: The provided element is assumed to not be registered under multiple IDs. */ add(id, element) { - const existingElement = this.idMap.get(id); - if (existingElement === element) { - return; - } - if (existingElement !== void 0) { - this.elementsSet.delete(existingElement); - } - this.elementsSet.add(element); - this.idMap.set(id, element); if (true) { - if (this.elementsSet.size !== this.idMap.size) { + const elementIds = getDevElementIds(this); + const existingId = elementIds.get(element); + if (existingId !== void 0 && existingId !== id) { throw new Error("Base UI: A trigger element cannot be registered under multiple IDs in PopupTriggerMap."); } + const previousElement = this.idMap.get(id); + if (previousElement !== void 0 && previousElement !== element) { + elementIds.delete(previousElement); + } + elementIds.set(element, id); } + this.idMap.set(id, element); } /** * Removes the trigger element with the given ID. */ delete(id) { - const element = this.idMap.get(id); - if (element) { - this.elementsSet.delete(element); - this.idMap.delete(id); + if (true) { + const element = this.idMap.get(id); + if (element !== void 0) { + devElementIdsByMap?.get(this)?.delete(element); + } } + this.idMap.delete(id); } /** * Whether the given element is registered as a trigger. */ hasElement(element) { - return this.elementsSet.has(element); - } + for (const registered of this.idMap.values()) { + if (registered === element) { + return true; + } + } + return false; + } /** * Whether there is a registered trigger element matching the given predicate. */ hasMatchingElement(predicate) { - for (const element of this.elementsSet) { + for (const element of this.idMap.values()) { if (predicate(element)) { return true; } @@ -5650,7 +5689,7 @@ var PopupTriggerMap = class { * Returns an iterable of all registered trigger elements. */ elements() { - return this.elementsSet.values(); + return this.idMap.values(); } /** * Returns the number of registered trigger elements. @@ -5710,12 +5749,12 @@ function createPopupFloatingRootContext(triggerElements, floatingId, nested = fa onOpenChange: void 0 }); } -var activeTriggerIdSelector = createSelector((state) => state.triggerIdProp ?? state.activeTriggerId); -var openSelector = createSelector((state) => state.openProp ?? state.open); -var popupIdSelector = createSelector((state) => { +var activeTriggerIdSelector = (state) => state.triggerIdProp ?? state.activeTriggerId; +var openSelector = (state) => state.openProp ?? state.open; +var popupIdSelector = (state) => { const popupId = state.popupElement?.id ?? state.floatingId; return popupId || void 0; -}); +}; function triggerOwnsOpenPopup(state, triggerId) { return triggerId !== void 0 && openSelector(state) && activeTriggerIdSelector(state) === triggerId; } @@ -5727,101 +5766,73 @@ function triggerOwnsOpenPopupOrIsOnlyTrigger(state, triggerId) { } var popupStoreSelectors = { open: openSelector, - mounted: createSelector((state) => state.mounted), - transitionStatus: createSelector((state) => state.transitionStatus), - floatingRootContext: createSelector((state) => state.floatingRootContext), - triggerCount: createSelector((state) => state.triggerCount), - preventUnmountingOnClose: createSelector((state) => state.preventUnmountingOnClose), - payload: createSelector((state) => state.payload), + mounted: (state) => state.mounted, + transitionStatus: (state) => state.transitionStatus, + floatingRootContext: (state) => state.floatingRootContext, + triggerCount: (state) => state.triggerCount, + preventUnmountingOnClose: (state) => state.preventUnmountingOnClose, + payload: (state) => state.payload, activeTriggerId: activeTriggerIdSelector, - activeTriggerElement: createSelector((state) => state.mounted ? state.activeTriggerElement : null), + activeTriggerElement: (state) => state.mounted ? state.activeTriggerElement : null, popupId: popupIdSelector, /** * Whether the trigger with the given ID was used to open the popup. */ - isTriggerActive: createSelector((state, triggerId) => triggerId !== void 0 && activeTriggerIdSelector(state) === triggerId), + isTriggerActive: (state, triggerId) => triggerId !== void 0 && activeTriggerIdSelector(state) === triggerId, /** * Whether the popup is open and was activated by a trigger with the given ID. */ - isOpenedByTrigger: createSelector((state, triggerId) => triggerOwnsOpenPopup(state, triggerId)), + isOpenedByTrigger: (state, triggerId) => triggerOwnsOpenPopup(state, triggerId), /** * Whether the popup is mounted and was activated by a trigger with the given ID. */ - isMountedByTrigger: createSelector((state, triggerId) => triggerId !== void 0 && activeTriggerIdSelector(state) === triggerId && state.mounted), - triggerProps: createSelector((state, isActive) => isActive ? state.activeTriggerProps : state.inactiveTriggerProps), + isMountedByTrigger: (state, triggerId) => triggerId !== void 0 && activeTriggerIdSelector(state) === triggerId && state.mounted, + triggerProps: (state, isActive) => isActive ? state.activeTriggerProps : state.inactiveTriggerProps, /** * Popup id for the trigger that currently owns the open popup. */ - triggerPopupId: createSelector((state, triggerId) => triggerOwnsOpenPopupOrIsOnlyTrigger(state, triggerId) ? popupIdSelector(state) : void 0), - popupProps: createSelector((state) => state.popupProps), - popupElement: createSelector((state) => state.popupElement), - positionerElement: createSelector((state) => state.positionerElement) + triggerPopupId: (state, triggerId) => triggerOwnsOpenPopupOrIsOnlyTrigger(state, triggerId) ? popupIdSelector(state) : void 0, + popupProps: (state) => state.popupProps, + popupElement: (state) => state.popupElement, + positionerElement: (state) => state.positionerElement }; -// node_modules/@base-ui/react/floating-ui-react/hooks/useFloatingRootContext.mjs -function useFloatingRootContext(options) { - const { - open = false, - onOpenChange, - elements: elements2 = {} - } = options; - const floatingId = useId(); - const nested = useFloatingParentNodeId() != null; - if (true) { - const optionDomReference = elements2.reference; - if (optionDomReference && !isElement(optionDomReference)) { - console.error("Cannot pass a virtual element to the `elements.reference` option,", "as it must be a real DOM element. Use `context.setPositionReference()`", "instead."); - } - } - const store = useRefWithInit(() => new FloatingRootStore({ - open, - transitionStatus: void 0, - onOpenChange, - referenceElement: elements2.reference ?? null, - floatingElement: elements2.floating ?? null, - triggerElements: new PopupTriggerMap(), - floatingId, - syncOnly: false, - nested - })).current; - useIsoLayoutEffect(() => { - const valuesToSync = { - open, - floatingId - }; - if (elements2.reference !== void 0) { - valuesToSync.referenceElement = elements2.reference; - valuesToSync.domReferenceElement = isElement(elements2.reference) ? elements2.reference : null; - } - if (elements2.floating !== void 0) { - valuesToSync.floatingElement = elements2.floating; +// node_modules/@base-ui/react/utils/popups/usePopupHandleStore.mjs +var React23 = __toESM(require_react(), 1); +var import_shim2 = __toESM(require_shim(), 1); +function usePopupHandleStore(handle) { + const subscribe = React23.useCallback((listener) => { + if (handle === void 0) { + return NOOP; } - store.update(valuesToSync); - }, [open, floatingId, elements2.reference, elements2.floating, store]); - store.context.onOpenChange = onOpenChange; - store.context.nested = nested; - return store; + return handle.subscribeStore(listener); + }, [handle]); + const getSnapshot = React23.useCallback(() => { + return handle === void 0 ? void 0 : handle.store; + }, [handle]); + return (0, import_shim2.useSyncExternalStore)(subscribe, getSnapshot, () => handle?.serverStore); } // node_modules/@base-ui/react/floating-ui-react/hooks/useFloating.mjs -function useFloating2(options = {}) { +function useBaseUIFloating(options) { + return useFloatingWithStore(options, options.rootContext); +} +function useFloatingWithStore(options, store) { const { nodeId, externalTree } = options; - const internalStore = useFloatingRootContext(options); - const store = options.rootContext || internalStore; const referenceElement = store.useState("referenceElement"); const floatingElement = store.useState("floatingElement"); const domReferenceElement = store.useState("domReferenceElement"); const open = store.useState("open"); const floatingId = store.useState("floatingId"); - const [positionReference, setPositionReferenceRaw] = React26.useState(null); - const [localDomReference, setLocalDomReference] = React26.useState(void 0); - const [localFloatingElement, setLocalFloatingElement] = React26.useState(void 0); - const domReferenceRef = React26.useRef(null); + const [positionReference, setPositionReferenceRaw] = React24.useState(null); + const [localDomReference, setLocalDomReference] = React24.useState(void 0); + const [localFloatingElement, setLocalFloatingElement] = React24.useState(void 0); + const domReferenceRef = React24.useRef(null); const tree = useFloatingTree(externalTree); - const storeElements = React26.useMemo(() => ({ + const storeElements = React24.useMemo(() => ({ reference: referenceElement, floating: floatingElement, domReference: domReferenceElement @@ -5840,7 +5851,7 @@ function useFloating2(options = {}) { store.useSyncedValue("referenceElement", localDomReference ?? null); store.useSyncedValue("domReferenceElement", localDomReference === void 0 ? domReferenceElement : localDomReferenceElement); store.useSyncedValue("floatingElement", syncedFloatingElement); - const setPositionReference = React26.useCallback((node) => { + const setPositionReference = React24.useCallback((node) => { const computedPositionReference = isElement(node) ? { getBoundingClientRect: () => node.getBoundingClientRect(), getClientRects: () => node.getClientRects(), @@ -5849,7 +5860,7 @@ function useFloating2(options = {}) { setPositionReferenceRaw(computedPositionReference); position.refs.setReference(computedPositionReference); }, [position.refs]); - const setReference = React26.useCallback((node) => { + const setReference = React24.useCallback((node) => { if (isElement(node) || node === null) { domReferenceRef.current = node; setLocalDomReference(node); @@ -5861,22 +5872,22 @@ function useFloating2(options = {}) { position.refs.setReference(node); } }, [position.refs, setLocalDomReference]); - const setFloating = React26.useCallback((node) => { + const setFloating = React24.useCallback((node) => { setLocalFloatingElement(node); position.refs.setFloating(node); }, [position.refs]); - const refs = React26.useMemo(() => ({ + const refs = React24.useMemo(() => ({ ...position.refs, setReference, setFloating, setPositionReference, domReference: domReferenceRef }), [position.refs, setReference, setFloating, setPositionReference]); - const elements2 = React26.useMemo(() => ({ + const elements2 = React24.useMemo(() => ({ ...position.elements, domReference: domReferenceElement }), [position.elements, domReferenceElement]); - const context = React26.useMemo(() => ({ + const context = React24.useMemo(() => ({ ...position, dataRef: store.context.dataRef, open, @@ -5900,7 +5911,7 @@ function useFloating2(options = {}) { node.context = context; } }); - return React26.useMemo(() => ({ + return React24.useMemo(() => ({ ...position, context, refs, @@ -5910,7 +5921,7 @@ function useFloating2(options = {}) { } // node_modules/@base-ui/react/floating-ui-react/hooks/useFocus.mjs -var React27 = __toESM(require_react(), 1); +var React25 = __toESM(require_react(), 1); var isMacSafari = parts_exports.os.mac && parts_exports.engine.webkit; function useFocus(context, props = {}) { const { @@ -5922,11 +5933,11 @@ function useFocus(context, props = {}) { events, dataRef } = store.context; - const blockFocusRef = React27.useRef(false); - const blockedReferenceRef = React27.useRef(null); - const keyboardModalityRef = React27.useRef(true); + const blockFocusRef = React25.useRef(false); + const blockedReferenceRef = React25.useRef(null); + const keyboardModalityRef = React25.useRef(true); const timeout = useTimeout(); - React27.useEffect(() => { + React25.useEffect(() => { const domReference = store.select("domReferenceElement"); if (!enabled) { return void 0; @@ -5946,7 +5957,7 @@ function useFocus(context, props = {}) { } return mergeCleanups(addEventListener(win, "blur", onBlur), isMacSafari && addEventListener(win, "keydown", onKeyDown, true), isMacSafari && addEventListener(win, "pointerdown", onPointerDown, true)); }, [store, enabled]); - React27.useEffect(() => { + React25.useEffect(() => { if (!enabled) { return void 0; } @@ -5964,7 +5975,7 @@ function useFocus(context, props = {}) { events.off("openchange", onOpenChangeLocal); }; }, [events, enabled, store]); - const reference = React27.useMemo(() => { + const reference = React25.useMemo(() => { function resetBlockedFocus() { blockFocusRef.current = false; blockedReferenceRef.current = null; @@ -6031,14 +6042,14 @@ function useFocus(context, props = {}) { } }; }, [dataRef, delay, store, timeout]); - return React27.useMemo(() => enabled ? { + return React25.useMemo(() => enabled ? { reference, trigger: reference } : {}, [enabled, reference]); } // node_modules/@base-ui/react/floating-ui-react/hooks/useHoverFloatingInteraction.mjs -var React28 = __toESM(require_react(), 1); +var React26 = __toESM(require_react(), 1); // node_modules/@base-ui/react/floating-ui-react/hooks/useHoverInteractionSharedState.mjs var HoverInteraction = class _HoverInteraction { @@ -6149,7 +6160,7 @@ function useHoverFloatingInteraction(context, parameters = {}) { clearPointerEvents(); } }, [open, instance, clearPointerEvents]); - React28.useEffect(() => { + React26.useEffect(() => { return clearPointerEvents; }, [clearPointerEvents]); useIsoLayoutEffect(() => { @@ -6178,7 +6189,7 @@ function useHoverFloatingInteraction(context, parameters = {}) { } return void 0; }, [enabled, open, domReferenceElement, floatingElement, instance, isHoverOpen, tree, parentId, clearPointerEvents]); - React28.useEffect(() => { + React26.useEffect(() => { if (!enabled) { return void 0; } @@ -6253,7 +6264,7 @@ function useHoverFloatingInteraction(context, parameters = {}) { } // node_modules/@base-ui/react/floating-ui-react/hooks/useHoverReferenceInteraction.mjs -var React29 = __toESM(require_react(), 1); +var React27 = __toESM(require_react(), 1); var ReactDOM5 = __toESM(require_react_dom(), 1); var EMPTY_REF = { current: null @@ -6271,7 +6282,8 @@ function useHoverReferenceInteraction(context, props = {}) { isActiveTrigger = true, getHandleCloseContext, isClosing, - shouldOpen: shouldOpenProp + shouldOpen: shouldOpenProp, + guardStaleOpen = false } = props; const store = "rootStore" in context ? context.rootStore : context; const { @@ -6280,7 +6292,7 @@ function useHoverReferenceInteraction(context, props = {}) { } = store.context; const tree = useFloatingTree(externalTree); const instance = useHoverInteractionSharedState(store); - const isHoverCloseActiveRef = React29.useRef(false); + const isHoverCloseActiveRef = React27.useRef(false); const handleCloseRef = useValueAsRef(handleClose); const delayRef = useValueAsRef(delay); const restMsRef = useValueAsRef(restMs); @@ -6318,8 +6330,8 @@ function useHoverReferenceInteraction(context, props = {}) { if (isActiveTrigger) { instance.handleCloseOptions = handleCloseRef.current?.__options; } - React29.useEffect(() => cleanupMouseMoveHandler, [cleanupMouseMoveHandler]); - React29.useEffect(() => { + React27.useEffect(() => cleanupMouseMoveHandler, [cleanupMouseMoveHandler]); + React27.useEffect(() => { if (!enabled) { return void 0; } @@ -6340,7 +6352,7 @@ function useHoverReferenceInteraction(context, props = {}) { events.off("openchange", onOpenChangeLocal); }; }, [enabled, events, instance, cleanupMouseMoveHandler]); - React29.useEffect(() => { + React27.useEffect(() => { if (!enabled) { return void 0; } @@ -6454,14 +6466,23 @@ function useHoverReferenceInteraction(context, props = {}) { closeWithDelay(event); } } + function onMouseOut(event) { + if (contains(trigger, event.relatedTarget)) { + return; + } + instance.openChangeTimeout.clear(); + instance.restTimeout.clear(); + instance.restTimeoutPending = false; + } + const staleOpenGuard = guardStaleOpen ? addEventListener(trigger, "mouseout", onMouseOut) : void 0; if (move) { return mergeCleanups(addEventListener(trigger, "mousemove", onMouseEnter, { once: true - }), addEventListener(trigger, "mouseenter", onMouseEnter), addEventListener(trigger, "mouseleave", onMouseLeave)); + }), addEventListener(trigger, "mouseenter", onMouseEnter), addEventListener(trigger, "mouseleave", onMouseLeave), staleOpenGuard); } - return mergeCleanups(addEventListener(trigger, "mouseenter", onMouseEnter), addEventListener(trigger, "mouseleave", onMouseLeave)); - }, [cleanupMouseMoveHandler, clearPointerEvents, dataRef, delayRef, store, enabled, handleCloseRef, instance, isActiveTrigger, isOverInactiveTrigger, isClickLikeOpenEvent2, mouseOnly, move, restMsRef, triggerElementRef, tree, enabledRef, getHandleCloseContext, isClosingRef, checkShouldOpen]); - return React29.useMemo(() => { + return mergeCleanups(addEventListener(trigger, "mouseenter", onMouseEnter), addEventListener(trigger, "mouseleave", onMouseLeave), staleOpenGuard); + }, [cleanupMouseMoveHandler, clearPointerEvents, dataRef, delayRef, store, enabled, handleCloseRef, instance, isActiveTrigger, isOverInactiveTrigger, isClickLikeOpenEvent2, mouseOnly, move, restMsRef, triggerElementRef, tree, enabledRef, getHandleCloseContext, isClosingRef, checkShouldOpen, guardStaleOpen]); + return React27.useMemo(() => { if (!enabled) { return void 0; } @@ -6742,6 +6763,21 @@ function safePolygon(options = {}) { return fn; } +// node_modules/@base-ui/react/utils/NullStore.mjs +var NullStore = class extends ReactStore { + // `update`/`set`/`notifyAll` funnel through `setState` in the base `Store`, so overriding + // `setState` alone would neutralize them today. They are overridden explicitly so the store stays + // inert even if a future base-class change stops routing a mutator through `setState`. + setState(_newState) { + } + update(_changes) { + } + set(_key, _value) { + } + notifyAll() { + } +}; + // node_modules/@base-ui/react/utils/popupStateMapping.mjs var CommonPopupDataAttributes = (function(CommonPopupDataAttributes2) { CommonPopupDataAttributes2["open"] = "data-open"; @@ -6753,26 +6789,17 @@ var CommonPopupDataAttributes = (function(CommonPopupDataAttributes2) { CommonPopupDataAttributes2["align"] = "data-align"; return CommonPopupDataAttributes2; })({}); -var CommonTriggerDataAttributes = /* @__PURE__ */ (function(CommonTriggerDataAttributes2) { - CommonTriggerDataAttributes2["popupOpen"] = "data-popup-open"; - CommonTriggerDataAttributes2["pressed"] = "data-pressed"; - return CommonTriggerDataAttributes2; -})({}); var TRIGGER_HOOK = { - [CommonTriggerDataAttributes.popupOpen]: "" -}; -var PRESSABLE_TRIGGER_HOOK = { - [CommonTriggerDataAttributes.popupOpen]: "", - [CommonTriggerDataAttributes.pressed]: "" + "data-popup-open": "" }; var POPUP_OPEN_HOOK = { - [CommonPopupDataAttributes.open]: "" + "data-open": "" }; var POPUP_CLOSED_HOOK = { - [CommonPopupDataAttributes.closed]: "" + "data-closed": "" }; var ANCHOR_HIDDEN_HOOK = { - [CommonPopupDataAttributes.anchorHidden]: "" + "data-anchor-hidden": "" }; var triggerOpenStateMapping = { open(value) { @@ -6796,6 +6823,10 @@ var popupStateMapping = { return null; } }; +var popupTransitionStateMapping = { + ...popupStateMapping, + ...transitionStatusMapping +}; // node_modules/@base-ui/utils/inertValue.mjs function inertValue(value) { @@ -6805,8 +6836,17 @@ function inertValue(value) { return value ? "true" : void 0; } -// node_modules/@base-ui/react/utils/useAnchorPositioning.mjs -var React30 = __toESM(require_react(), 1); +// node_modules/@base-ui/react/internals/direction-context/DirectionContext.mjs +var React28 = __toESM(require_react(), 1); +var DirectionContext = /* @__PURE__ */ React28.createContext(void 0); +if (true) DirectionContext.displayName = "DirectionContext"; +function useDirection() { + const context = React28.useContext(DirectionContext); + return context?.direction ?? "ltr"; +} + +// node_modules/@base-ui/react/internals/useAnchorPositioning.mjs +var React29 = __toESM(require_react(), 1); // node_modules/@base-ui/react/floating-ui-react/middleware/arrow.mjs var baseArrow = (options) => ({ @@ -6878,7 +6918,6 @@ var arrow4 = (options, deps) => ({ }); // node_modules/@base-ui/react/utils/hideMiddleware.mjs -var nativeHideFn = hide3().fn; var hide4 = { name: "hide", async fn(state) { @@ -6889,88 +6928,27 @@ var hide4 = { y: y2 } = state.rects.reference; const anchorHidden = width === 0 && height === 0 && x2 === 0 && y2 === 0; - const nativeHideResult = await nativeHideFn(state); + const overflow = await state.platform.detectOverflow(state, { + elementContext: "reference" + }); + const referenceHidden = overflow.top - height >= 0 || overflow.right - width >= 0 || overflow.bottom - height >= 0 || overflow.left - width >= 0; return { data: { - referenceHidden: nativeHideResult.data?.referenceHidden || anchorHidden + referenceHidden: referenceHidden || anchorHidden } }; } }; -// node_modules/@base-ui/react/utils/adaptiveOriginMiddleware.mjs +// node_modules/@base-ui/react/utils/adaptiveOriginConstants.mjs var DEFAULT_SIDES = { sideX: "left", sideY: "top" }; -var adaptiveOrigin = { - name: "adaptiveOrigin", - async fn(state) { - const { - x: rawX, - y: rawY, - rects: { - floating: floatRect - }, - elements: { - floating - }, - platform: platform3, - strategy, - placement - } = state; - const win = getWindow(floating); - const styles = win.getComputedStyle(floating); - const hasTransition = styles.transitionDuration !== "0s" && styles.transitionDuration !== ""; - if (!hasTransition) { - return { - x: rawX, - y: rawY, - data: DEFAULT_SIDES - }; - } - const offsetParent = await platform3.getOffsetParent?.(floating); - let offsetDimensions = { - width: 0, - height: 0 - }; - if (strategy === "fixed" && win?.visualViewport) { - offsetDimensions = { - width: win.visualViewport.width, - height: win.visualViewport.height - }; - } else if (offsetParent === win) { - const doc = ownerDocument(floating); - offsetDimensions = { - width: doc.documentElement.clientWidth, - height: doc.documentElement.clientHeight - }; - } else if (await platform3.isElement?.(offsetParent)) { - offsetDimensions = await platform3.getDimensions(offsetParent); - } - const currentSide = getSide(placement); - let x2 = rawX; - let y2 = rawY; - if (currentSide === "left") { - x2 = offsetDimensions.width - (rawX + floatRect.width); - } - if (currentSide === "top") { - y2 = offsetDimensions.height - (rawY + floatRect.height); - } - const sideX = currentSide === "left" ? "right" : DEFAULT_SIDES.sideX; - const sideY = currentSide === "top" ? "bottom" : DEFAULT_SIDES.sideY; - return { - x: x2, - y: y2, - data: { - sideX, - sideY - } - }; - } -}; -// node_modules/@base-ui/react/utils/useAnchorPositioning.mjs +// node_modules/@base-ui/react/internals/useAnchorPositioning.mjs +var AVAILABLE_WIDTH_VAR = "--available-width"; +var AVAILABLE_HEIGHT_VAR = "--available-height"; function getLogicalSide(sideParam, renderedSide, isRtl) { const isLogicalSideParam = sideParam === "inline-start" || sideParam === "inline-end"; const logicalRight = isRtl ? "inline-start" : "inline-end"; @@ -7002,6 +6980,9 @@ function getOffsetData(state, sideParam, isRtl) { return data; } function useAnchorPositioning(params) { + return useAnchorPositioningWithHook(params, useBaseUIFloating); +} +function useAnchorPositioningWithHook(params, useFloatingHook) { const { // Public parameters anchor, @@ -7021,19 +7002,21 @@ function useAnchorPositioning(params) { floatingRootContext, mounted, collisionAvoidance, - shiftCrossAxis = false, + shift: shift4, nodeId, adaptiveOrigin: adaptiveOrigin2, lazyFlip = false, externalTree } = params; - const [mountSide, setMountSide] = React30.useState(null); + const [mountSide, setMountSide] = React29.useState(null); if (!mounted && mountSide !== null) { setMountSide(null); } const collisionAvoidanceSide = collisionAvoidance.side || "flip"; const collisionAvoidanceAlign = collisionAvoidance.align || "flip"; const collisionAvoidanceFallbackAxisSide = collisionAvoidance.fallbackAxisSide || "end"; + const shiftCrossAxis = shift4?.crossAxis ?? false; + const shiftRootBoundary = shift4?.rootBoundary; const anchorFn = typeof anchor === "function" ? anchor : void 0; const anchorFnCallback = useStableCallback(anchorFn); const anchorDep = anchorFn ? anchorFnCallback : anchor; @@ -7051,31 +7034,31 @@ function useAnchorPositioning(params) { }[sideParam]; const placement = align === "center" ? side : `${side}-${align}`; let collisionPadding = collisionPaddingParam; - const bias = 1; - const biasTop = sideParam === "bottom" ? bias : 0; - const biasBottom = sideParam === "top" ? bias : 0; - const biasLeft = sideParam === "right" ? bias : 0; - const biasRight = sideParam === "left" ? bias : 0; if (typeof collisionPadding === "number") { collisionPadding = { - top: collisionPadding + biasTop, - right: collisionPadding + biasRight, - bottom: collisionPadding + biasBottom, - left: collisionPadding + biasLeft + top: collisionPadding, + right: collisionPadding, + bottom: collisionPadding, + left: collisionPadding }; } else if (collisionPadding) { collisionPadding = { - top: (collisionPadding.top || 0) + biasTop, - right: (collisionPadding.right || 0) + biasRight, - bottom: (collisionPadding.bottom || 0) + biasBottom, - left: (collisionPadding.left || 0) + biasLeft + top: collisionPadding.top || 0, + right: collisionPadding.right || 0, + bottom: collisionPadding.bottom || 0, + left: collisionPadding.left || 0 }; } + const bias = 1; + const biasTop = sideParam === "bottom" ? bias : 0; + const biasBottom = sideParam === "top" ? bias : 0; + const biasLeft = sideParam === "right" ? bias : 0; + const biasRight = sideParam === "left" ? bias : 0; const commonCollisionProps = { boundary: collisionBoundary === "clipping-ancestors" ? "clippingAncestors" : collisionBoundary, padding: collisionPadding }; - const arrowRef = React30.useRef(null); + const arrowRef = React29.useRef(null); const sideOffsetRef = useValueAsRef(sideOffset); const alignOffsetRef = useValueAsRef(alignOffset); const sideOffsetDep = typeof sideOffset !== "function" ? sideOffset : 0; @@ -7101,46 +7084,37 @@ function useAnchorPositioning(params) { // Ensure the popup flips if it's been limited by its --available-height and it resizes. // Since the size() padding is smaller than the flip() padding, flip() will take precedence. padding: { - top: collisionPadding.top + bias, - right: collisionPadding.right + bias, - bottom: collisionPadding.bottom + bias, - left: collisionPadding.left + bias + top: collisionPadding.top + bias + biasTop, + right: collisionPadding.right + bias + biasRight, + bottom: collisionPadding.bottom + bias + biasBottom, + left: collisionPadding.left + bias + biasLeft }, mainAxis: !shiftCrossAxis && collisionAvoidanceSide === "flip", crossAxis: collisionAvoidanceAlign === "flip" ? "alignment" : false, fallbackAxisSideDirection: collisionAvoidanceFallbackAxisSide }); - const shiftMiddleware = shiftDisabled ? null : shift3((data) => { - const html = ownerDocument(data.elements.floating).documentElement; - return { - ...commonCollisionProps, - // Use the Layout Viewport to avoid shifting around when pinch-zooming - // for context menus. - rootBoundary: shiftCrossAxis ? { - x: 0, - y: 0, - width: html.clientWidth, - height: html.clientHeight - } : void 0, - mainAxis: collisionAvoidanceAlign !== "none", - crossAxis: crossAxisShiftEnabled, - limiter: sticky || shiftCrossAxis ? void 0 : limitShift3((limitData) => { - if (!arrowRef.current) { - return {}; - } - const { - width, - height - } = arrowRef.current.getBoundingClientRect(); - const sideAxis = getSideAxis(getSide(limitData.placement)); - const arrowSize = sideAxis === "y" ? width : height; - const offsetAmount = sideAxis === "y" ? collisionPadding.left + collisionPadding.right : collisionPadding.top + collisionPadding.bottom; - return { - offset: arrowSize / 2 + offsetAmount / 2 - }; - }) - }; - }, [commonCollisionProps, sticky, shiftCrossAxis, collisionPadding, collisionAvoidanceAlign]); + const shiftMiddleware = shiftDisabled ? null : shift3({ + ...commonCollisionProps, + // Use the Layout Viewport to avoid shifting around when pinch-zooming. + rootBoundary: shiftRootBoundary, + mainAxis: collisionAvoidanceAlign !== "none", + crossAxis: crossAxisShiftEnabled, + limiter: sticky || shiftCrossAxis ? void 0 : limitShift3((limitData) => { + if (!arrowRef.current) { + return {}; + } + const { + width, + height + } = arrowRef.current.getBoundingClientRect(); + const sideAxis = getSideAxis(getSide(limitData.placement)); + const arrowSize = sideAxis === "y" ? width : height; + const offsetAmount = sideAxis === "y" ? collisionPadding.left + collisionPadding.right : collisionPadding.top + collisionPadding.bottom; + return { + offset: arrowSize / 2 + offsetAmount / 2 + }; + }) + }, [commonCollisionProps, sticky, shiftCrossAxis, shiftRootBoundary, collisionPadding, collisionAvoidanceAlign]); if (collisionAvoidanceSide === "shift" || collisionAvoidanceAlign === "shift" || align === "center") { middleware.push(shiftMiddleware, flipMiddleware); } else { @@ -7160,8 +7134,8 @@ function useAnchorPositioning(params) { return; } const floatingStyle = floating.style; - floatingStyle.setProperty("--available-width", `${availableWidth}px`); - floatingStyle.setProperty("--available-height", `${availableHeight}px`); + floatingStyle.setProperty(AVAILABLE_WIDTH_VAR, `${availableWidth}px`); + floatingStyle.setProperty(AVAILABLE_HEIGHT_VAR, `${availableHeight}px`); const dpr = getWindow(floating).devicePixelRatio || 1; const { x: x3, @@ -7224,7 +7198,7 @@ function useAnchorPositioning(params) { }); } }, [mounted, floatingRootContext]); - const autoUpdateOptions = React30.useMemo(() => ({ + const autoUpdateOptions = React29.useMemo(() => ({ elementResize: !disableAnchorTracking && typeof ResizeObserver !== "undefined", layoutShift: !disableAnchorTracking && typeof IntersectionObserver !== "undefined" }), [disableAnchorTracking]); @@ -7239,7 +7213,7 @@ function useAnchorPositioning(params) { context, isPositioned, floatingStyles: originalFloatingStyles - } = useFloating2({ + } = useFloatingHook({ rootContext: floatingRootContext, open: keepMounted ? mounted : void 0, placement, @@ -7254,21 +7228,34 @@ function useAnchorPositioning(params) { sideY } = middlewareData.adaptiveOrigin || DEFAULT_SIDES; const resolvedPosition = isPositioned ? positionMethod : "fixed"; - const floatingStyles = React30.useMemo(() => { - const base = adaptiveOrigin2 ? { - position: resolvedPosition, - [sideX]: x2, - [sideY]: y2 - } : { - position: resolvedPosition, - ...originalFloatingStyles - }; + const floatingStyles = React29.useMemo(() => { + let base; + if (!isPositioned) { + base = { + position: resolvedPosition, + top: 0, + left: 0 + }; + } else if (adaptiveOrigin2) { + base = { + position: resolvedPosition, + [sideX]: x2, + [sideY]: y2 + }; + } else { + base = { + ...originalFloatingStyles, + position: resolvedPosition + }; + } + base[AVAILABLE_WIDTH_VAR] = "100vw"; + base[AVAILABLE_HEIGHT_VAR] = "100vh"; if (!isPositioned) { base.opacity = 0; } return base; }, [adaptiveOrigin2, resolvedPosition, sideX, x2, sideY, y2, originalFloatingStyles, isPositioned]); - const registeredPositionReferenceRef = React30.useRef(null); + const registeredPositionReferenceRef = React29.useRef(null); useIsoLayoutEffect(() => { if (!mounted) { return; @@ -7282,7 +7269,7 @@ function useAnchorPositioning(params) { registeredPositionReferenceRef.current = finalAnchor; } }, [mounted, refs, anchorDep, anchorValueRef]); - React30.useEffect(() => { + React29.useEffect(() => { if (!mounted) { return; } @@ -7295,7 +7282,7 @@ function useAnchorPositioning(params) { registeredPositionReferenceRef.current = anchorValue.current; } }, [mounted, refs, anchorDep, anchorValueRef]); - React30.useEffect(() => { + React29.useEffect(() => { if (keepMounted && mounted && elements2.reference && elements2.floating) { return autoUpdate(elements2.reference, elements2.floating, update2, autoUpdateOptions); } @@ -7306,17 +7293,17 @@ function useAnchorPositioning(params) { const renderedAlign = getAlignment(renderedPlacement) || "center"; const anchorHidden = Boolean(middlewareData.hide?.referenceHidden); useIsoLayoutEffect(() => { - if (lazyFlip && mounted && isPositioned) { + if (lazyFlip && mounted && isPositioned && renderedSide !== side) { setMountSide(renderedSide); } - }, [lazyFlip, mounted, isPositioned, renderedSide]); - const arrowStyles = React30.useMemo(() => ({ + }, [lazyFlip, mounted, isPositioned, renderedSide, side]); + const arrowStyles = React29.useMemo(() => ({ position: "absolute", top: middlewareData.arrow?.y, left: middlewareData.arrow?.x }), [middlewareData.arrow]); const arrowUncentered = middlewareData.arrow?.centerOffset !== 0; - return React30.useMemo(() => ({ + return React29.useMemo(() => ({ positionerStyles: floatingStyles, arrowStyles, arrowRef, @@ -7335,7 +7322,7 @@ function isRef(param) { return param != null && "current" in param; } -// node_modules/@base-ui/react/utils/getDisabledMountTransitionStyles.mjs +// node_modules/@base-ui/react/internals/getDisabledMountTransitionStyles.mjs function getDisabledMountTransitionStyles(transitionStatus) { return transitionStatus === "starting" ? DISABLED_TRANSITIONS_STYLE : EMPTY_OBJECT; } @@ -7368,17 +7355,17 @@ function usePositioner(componentProps, state, { } // node_modules/@base-ui/react/utils/usePopupViewport.mjs -var React34 = __toESM(require_react(), 1); +var React33 = __toESM(require_react(), 1); var ReactDOM6 = __toESM(require_react_dom(), 1); // node_modules/@base-ui/utils/usePreviousValue.mjs -var React31 = __toESM(require_react(), 1); +var React30 = __toESM(require_react(), 1); function usePreviousValue(value) { - const [state, setState] = React31.useState({ + const [state, setState] = React30.useState({ current: value, previous: null }); - if (value !== state.current) { + if (!Object.is(value, state.current)) { setState({ current: value, previous: state.current @@ -7388,7 +7375,7 @@ function usePreviousValue(value) { } // node_modules/@base-ui/react/utils/usePopupAutoResize.mjs -var React32 = __toESM(require_react(), 1); +var React31 = __toESM(require_react(), 1); // node_modules/@base-ui/react/utils/getCssDimensions.mjs function getCssDimensions2(element) { @@ -7421,29 +7408,14 @@ function usePopupAutoResize(parameters) { side, direction } = parameters; - const runOnceAnimationsFinish = useAnimationsFinished(popupElement, true, false); + const runOnceAnimationsFinish = useAnimationsFinished(popupElement, true); const animationFrame = useAnimationFrame(); - const committedDimensionsRef = React32.useRef(null); - const isInitialRenderRef = React32.useRef(true); - const restoreAnchoringStylesRef = React32.useRef(NOOP); + const committedDimensionsRef = React31.useRef(null); + const isInitialRenderRef = React31.useRef(true); + const restoreAnchoringStylesRef = React31.useRef(NOOP); const onMeasureLayout = useStableCallback(onMeasureLayoutParam); const onMeasureLayoutComplete = useStableCallback(onMeasureLayoutCompleteParam); - const anchoringStyles = React32.useMemo(() => { - let isOriginSide = side === "top"; - let isPhysicalLeft = side === "left"; - if (direction === "rtl") { - isOriginSide = isOriginSide || side === "inline-end"; - isPhysicalLeft = isPhysicalLeft || side === "inline-end"; - } else { - isOriginSide = isOriginSide || side === "inline-start"; - isPhysicalLeft = isPhysicalLeft || side === "inline-start"; - } - return isOriginSide ? { - position: "absolute", - [side === "top" ? "bottom" : "top"]: "0", - [isPhysicalLeft ? "right" : "left"]: "0" - } : EMPTY_OBJECT; - }, [side, direction]); + const anchoringStyles = React31.useMemo(() => getPopupAnchoringStyles(side, direction), [side, direction]); useIsoLayoutEffect(() => { if (!mounted) { restoreAnchoringStylesRef.current = NOOP; @@ -7510,6 +7482,18 @@ function usePopupAutoResize(parameters) { }; }, [content, popupElement, positionerElement, runOnceAnimationsFinish, animationFrame, mounted, onMeasureLayout, onMeasureLayoutComplete, anchoringStyles]); } +function getPopupAnchoringStyles(side, direction) { + const isPhysicalTop = side === "top"; + const isPhysicalLeft = side === "left" || side === (direction === "rtl" ? "inline-end" : "inline-start"); + if (!isPhysicalTop && !isPhysicalLeft) { + return EMPTY_OBJECT; + } + return { + position: "absolute", + [isPhysicalTop ? "bottom" : "top"]: "0", + [isPhysicalLeft ? "right" : "left"]: "0" + }; +} function overrideElementStyle(element, property, value) { const originalValue = element.style.getPropertyValue(property); element.style.setProperty(property, value); @@ -7540,13 +7524,13 @@ function setPositionerCssSize(positionerElement, size4) { } // node_modules/@base-ui/react/direction-provider/DirectionProvider.mjs -var React33 = __toESM(require_react(), 1); +var React32 = __toESM(require_react(), 1); var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1); var DirectionProvider = function DirectionProvider2(props) { const { direction = "ltr" } = props; - const contextValue = React33.useMemo(() => ({ + const contextValue = React32.useMemo(() => ({ direction }), [direction]); return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DirectionContext.Provider, { @@ -7556,78 +7540,164 @@ var DirectionProvider = function DirectionProvider2(props) { }; if (true) DirectionProvider.displayName = "DirectionProvider"; -// node_modules/@base-ui/react/utils/usePopupViewport.mjs -var import_jsx_runtime6 = __toESM(require_jsx_runtime(), 1); -function usePopupViewport(parameters) { - const { - store, - side, - cssVars, - children - } = parameters; - const direction = useDirection(); - const activeTrigger = store.useState("activeTriggerElement"); - const activeTriggerId = store.useState("activeTriggerId"); - const open = store.useState("open"); - const payload = store.useState("payload"); - const mounted = store.useState("mounted"); - const popupElement = store.useState("popupElement"); - const positionerElement = store.useState("positionerElement"); - const previousActiveTrigger = usePreviousValue(open ? activeTrigger : null); - const currentContentKey = usePopupContentKey(activeTriggerId, payload); - const capturedNodeRef = React34.useRef(null); - const [previousContentNode, setPreviousContentNode] = React34.useState(null); - const [newTriggerOffset, setNewTriggerOffset] = React34.useState(null); - const currentContainerRef = React34.useRef(null); - const previousContainerRef = React34.useRef(null); - const onAnimationsFinished = useAnimationsFinished(currentContainerRef, true, false); - const cleanupFrame = useAnimationFrame(); - const [previousContentDimensions, setPreviousContentDimensions] = React34.useState(null); - const [showStartingStyleAttribute, setShowStartingStyleAttribute] = React34.useState(false); - useIsoLayoutEffect(() => { - store.set("hasViewport", true); - return () => { - store.set("hasViewport", false); - }; - }, [store]); - const handleMeasureLayout = useStableCallback(() => { - currentContainerRef.current?.style.setProperty("animation", "none"); - currentContainerRef.current?.style.setProperty("transition", "none"); - previousContainerRef.current?.style.setProperty("display", "none"); - }); - const handleMeasureLayoutComplete = useStableCallback((previousDimensions) => { - currentContainerRef.current?.style.removeProperty("animation"); - currentContainerRef.current?.style.removeProperty("transition"); - previousContainerRef.current?.style.removeProperty("display"); - if (previousDimensions) { - setPreviousContentDimensions(previousDimensions); - } - }); - const lastHandledTriggerRef = React34.useRef(null); - useIsoLayoutEffect(() => { - if (!open || !mounted) { - lastHandledTriggerRef.current = null; +// node_modules/@base-ui/react/utils/adaptiveOriginMiddleware.mjs +var adaptiveOrigin = { + name: "adaptiveOrigin", + async fn(state) { + const { + x: rawX, + y: rawY, + rects: { + floating: floatRect + }, + elements: { + floating + }, + platform: platform3, + strategy, + placement + } = state; + const win = getWindow(floating); + const styles = win.getComputedStyle(floating); + const hasTransition = styles.transitionDuration !== "0s" && styles.transitionDuration !== ""; + if (!hasTransition) { + return { + x: rawX, + y: rawY, + data: DEFAULT_SIDES + }; } - }, [open, mounted]); + const offsetParent = await platform3.getOffsetParent?.(floating); + let offsetDimensions = { + width: 0, + height: 0 + }; + if (strategy === "fixed" && win?.visualViewport) { + offsetDimensions = { + width: win.visualViewport.width, + height: win.visualViewport.height + }; + } else if (offsetParent === win) { + const doc = ownerDocument(floating); + offsetDimensions = { + width: doc.documentElement.clientWidth, + height: doc.documentElement.clientHeight + }; + } else if (await platform3.isElement?.(offsetParent)) { + offsetDimensions = await platform3.getDimensions(offsetParent); + } + const currentSide = getSide(placement); + let x2 = rawX; + let y2 = rawY; + if (currentSide === "left") { + x2 = offsetDimensions.width - (rawX + floatRect.width); + } + if (currentSide === "top") { + y2 = offsetDimensions.height - (rawY + floatRect.height); + } + const sideX = currentSide === "left" ? "right" : DEFAULT_SIDES.sideX; + const sideY = currentSide === "top" ? "bottom" : DEFAULT_SIDES.sideY; + return { + x: x2, + y: y2, + data: { + sideX, + sideY + } + }; + } +}; + +// node_modules/@base-ui/react/utils/usePopupViewport.mjs +var import_jsx_runtime6 = __toESM(require_jsx_runtime(), 1); +var popupViewportStateMapping = { + activationDirection: (value) => value ? { + "data-activation-direction": value + } : null +}; +function usePopupViewport(parameters) { + const { + store, + side, + children + } = parameters; + const direction = useDirection(); + const activeTrigger = store.useState("activeTriggerElement"); + const activeTriggerId = store.useState("activeTriggerId"); + const open = store.useState("open"); + const payload = store.useState("payload"); + const mounted = store.useState("mounted"); + const popupElement = store.useState("popupElement"); + const positionerElement = store.useState("positionerElement"); + const previousActiveTrigger = usePreviousValue(open ? activeTrigger : null); + const currentContentKey = usePopupContentKey(activeTriggerId, payload); + const capturedNodeRef = React33.useRef(null); + const [previousContentNode, setPreviousContentNode] = React33.useState(null); + const [newTriggerOffset, setNewTriggerOffset] = React33.useState(null); + const currentContainerRef = React33.useRef(null); + const previousContainerRef = React33.useRef(null); + const onAnimationsFinished = useAnimationsFinished(currentContainerRef, true); + const cleanupFrame = useAnimationFrame(); + const cleanupControllerRef = React33.useRef(null); + const [previousContentDimensions, setPreviousContentDimensions] = React33.useState(null); + const [showStartingStyleAttribute, setShowStartingStyleAttribute] = React33.useState(false); + useIsoLayoutEffect(() => { + store.set("adaptiveOrigin", adaptiveOrigin); + return () => { + store.set("adaptiveOrigin", void 0); + }; + }, [store]); + const handleMeasureLayout = useStableCallback(() => { + currentContainerRef.current?.style.setProperty("animation", "none"); + currentContainerRef.current?.style.setProperty("transition", "none"); + previousContainerRef.current?.style.setProperty("display", "none"); + }); + const handleMeasureLayoutComplete = useStableCallback((previousDimensions) => { + currentContainerRef.current?.style.removeProperty("animation"); + currentContainerRef.current?.style.removeProperty("transition"); + previousContainerRef.current?.style.removeProperty("display"); + if (previousDimensions) { + setPreviousContentDimensions(previousDimensions); + } + }); + const armViewportCleanup = useStableCallback(() => { + cleanupControllerRef.current?.abort(); + const controller = new AbortController(); + cleanupControllerRef.current = controller; + onAnimationsFinished(() => { + setPreviousContentNode(null); + setPreviousContentDimensions(null); + capturedNodeRef.current = null; + }, controller.signal); + }); + const lastHandledTriggerRef = React33.useRef(null); + useIsoLayoutEffect(() => { + if (!open || !mounted) { + lastHandledTriggerRef.current = null; + } + }, [open, mounted]); useIsoLayoutEffect(() => { if (activeTrigger && previousActiveTrigger && activeTrigger !== previousActiveTrigger && lastHandledTriggerRef.current !== activeTrigger && capturedNodeRef.current) { setPreviousContentNode(capturedNodeRef.current); setShowStartingStyleAttribute(true); const offset4 = calculateRelativePosition(previousActiveTrigger, activeTrigger); setNewTriggerOffset(offset4); - cleanupFrame.request(() => { - ReactDOM6.flushSync(() => { - setShowStartingStyleAttribute(false); - }); - onAnimationsFinished(() => { - setPreviousContentNode(null); - setPreviousContentDimensions(null); - capturedNodeRef.current = null; - }); - }); lastHandledTriggerRef.current = activeTrigger; } - }, [activeTrigger, previousActiveTrigger, previousContentNode, onAnimationsFinished, cleanupFrame]); + }, [activeTrigger, previousActiveTrigger]); + useIsoLayoutEffect(() => { + if (previousContentNode == null) { + return; + } + cleanupControllerRef.current?.abort(); + setShowStartingStyleAttribute(true); + cleanupFrame.request(() => { + ReactDOM6.flushSync(() => { + setShowStartingStyleAttribute(false); + }); + armViewportCleanup(); + }); + }, [currentContentKey, previousContentNode, armViewportCleanup, cleanupFrame]); useIsoLayoutEffect(() => { const source = currentContainerRef.current; if (!source) { @@ -7648,15 +7718,15 @@ function usePopupViewport(parameters) { children }, currentContentKey); } else { - childrenToRender = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(React34.Fragment, { + childrenToRender = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(React33.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { "data-previous": true, inert: inertValue(true), ref: previousContainerRef, style: { ...previousContentDimensions ? { - [cssVars.popupWidth]: `${previousContentDimensions.width}px`, - [cssVars.popupHeight]: `${previousContentDimensions.height}px` + "--popup-width": `${previousContentDimensions.width}px`, + "--popup-height": `${previousContentDimensions.height}px` } : null, position: "absolute" }, @@ -7727,10 +7797,10 @@ function calculateRelativePosition(from, to) { }; } function usePopupContentKey(activeTriggerId, payload) { - const [contentKey, setContentKey] = React34.useState(0); - const previousActiveTriggerIdRef = React34.useRef(activeTriggerId); - const previousPayloadRef = React34.useRef(payload); - const pendingPayloadUpdateRef = React34.useRef(false); + const [contentKey, setContentKey] = React33.useState(0); + const previousActiveTriggerIdRef = React33.useRef(activeTriggerId); + const previousPayloadRef = React33.useRef(payload); + const pendingPayloadUpdateRef = React33.useRef(false); useIsoLayoutEffect(() => { const previousActiveTriggerId = previousActiveTriggerIdRef.current; const previousPayload = previousPayloadRef.current; @@ -7750,10 +7820,10 @@ function usePopupContentKey(activeTriggerId, payload) { } // node_modules/@base-ui/react/utils/FloatingPortalLite.mjs -var React35 = __toESM(require_react(), 1); +var React34 = __toESM(require_react(), 1); var ReactDOM7 = __toESM(require_react_dom(), 1); var import_jsx_runtime7 = __toESM(require_jsx_runtime(), 1); -var FloatingPortalLite = /* @__PURE__ */ React35.forwardRef(function FloatingPortalLite2(componentProps, forwardedRef) { +var FloatingPortalLite = /* @__PURE__ */ React34.forwardRef(function FloatingPortalLite2(componentProps, forwardedRef) { const { children, container, @@ -7763,8 +7833,8 @@ var FloatingPortalLite = /* @__PURE__ */ React35.forwardRef(function FloatingPor ...elementProps } = componentProps; const { - portalNode, - portalSubtree + node: portalNode, + subtree: portalSubtree } = useFloatingPortalNode({ container, ref: forwardedRef, @@ -7774,7 +7844,7 @@ var FloatingPortalLite = /* @__PURE__ */ React35.forwardRef(function FloatingPor if (!portalSubtree && !portalNode) { return null; } - return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(React35.Fragment, { + return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(React34.Fragment, { children: [portalSubtree, portalNode && /* @__PURE__ */ ReactDOM7.createPortal(children, portalNode)] }); }); @@ -7796,14 +7866,14 @@ __export(index_parts_exports, { }); // node_modules/@base-ui/react/tooltip/root/TooltipRoot.mjs -var React38 = __toESM(require_react(), 1); +var React37 = __toESM(require_react(), 1); // node_modules/@base-ui/react/tooltip/root/TooltipRootContext.mjs -var React36 = __toESM(require_react(), 1); -var TooltipRootContext = /* @__PURE__ */ React36.createContext(void 0); +var React35 = __toESM(require_react(), 1); +var TooltipRootContext = /* @__PURE__ */ React35.createContext(void 0); if (true) TooltipRootContext.displayName = "TooltipRootContext"; function useTooltipRootContext(optional) { - const context = React36.useContext(TooltipRootContext); + const context = React35.useContext(TooltipRootContext); if (context === void 0 && !optional) { throw new Error(true ? "Base UI: TooltipRootContext is missing. Tooltip parts must be placed within ." : formatErrorMessage_default(72)); } @@ -7811,33 +7881,23 @@ function useTooltipRootContext(optional) { } // node_modules/@base-ui/react/tooltip/store/TooltipStore.mjs -var React37 = __toESM(require_react(), 1); +var React36 = __toESM(require_react(), 1); var selectors2 = { ...popupStoreSelectors, - disabled: createSelector((state) => state.disabled), - instantType: createSelector((state) => state.instantType), - isInstantPhase: createSelector((state) => state.isInstantPhase), - trackCursorAxis: createSelector((state) => state.trackCursorAxis), - disableHoverablePopup: createSelector((state) => state.disableHoverablePopup), - lastOpenChangeReason: createSelector((state) => state.openChangeReason), - closeOnClick: createSelector((state) => state.closeOnClick), - closeDelay: createSelector((state) => state.closeDelay), - hasViewport: createSelector((state) => state.hasViewport) -}; -var TooltipStore = class _TooltipStore extends ReactStore { - constructor(initialState, floatingId, nested = false) { + disabled: (state) => state.disabled, + instantType: (state) => state.instantType, + isInstantPhase: (state) => state.isInstantPhase, + trackCursorAxis: (state) => state.trackCursorAxis, + disableHoverablePopup: (state) => state.disableHoverablePopup, + lastOpenChangeReason: (state) => state.openChangeReason, + closeOnClick: (state) => state.closeOnClick, + closeDelay: (state) => state.closeDelay, + adaptiveOrigin: (state) => state.adaptiveOrigin +}; +var TooltipStore = class extends ReactStore { + constructor(initialState, floatingId, nested) { const triggerElements = new PopupTriggerMap(); - const state = { - ...createInitialState(), - ...initialState - }; - state.floatingRootContext = createPopupFloatingRootContext(triggerElements, floatingId, nested); - super(state, { - popupRef: /* @__PURE__ */ React37.createRef(), - onOpenChange: void 0, - onOpenChangeComplete: void 0, - triggerElements - }, selectors2); + super(createInitialState(initialState, triggerElements, floatingId, nested), createInitialContext(triggerElements), selectors2); } setOpen = (nextOpen, eventDetails) => { applyPopupOpenChange(this, nextOpen, eventDetails, { @@ -7850,13 +7910,17 @@ var TooltipStore = class _TooltipStore extends ReactStore { cancelPendingOpen(event) { this.state.floatingRootContext.dispatchOpenChange(false, createChangeEventDetails(reason_parts_exports.triggerPress, event)); } - static useStore(externalStore, initialState) { - const store = usePopupStore(externalStore, (floatingId, nested) => new _TooltipStore(initialState, floatingId, nested)).store; - return store; - } }; -function createInitialState() { - return { +function createNullTooltipStore() { + const triggerElements = new PopupTriggerMap(); + const store = new NullStore(Object.freeze(createInitialState(void 0, triggerElements)), Object.freeze(createInitialContext(triggerElements)), selectors2); + return Object.assign(store, { + setOpen: NOOP, + cancelPendingOpen: NOOP + }); +} +function createInitialState(initialState, triggerElements, floatingId, nested = false) { + const state = { ...createInitialPopupStoreState(), disabled: false, instantType: void 0, @@ -7866,7 +7930,18 @@ function createInitialState() { openChangeReason: null, closeOnClick: true, closeDelay: 0, - hasViewport: false + adaptiveOrigin: void 0, + ...initialState + }; + state.floatingRootContext = createPopupFloatingRootContext(triggerElements, floatingId, nested); + return state; +} +function createInitialContext(triggerElements) { + return { + popupRef: /* @__PURE__ */ React36.createRef(), + onOpenChange: void 0, + onOpenChangeComplete: void 0, + triggerElements }; } @@ -7887,13 +7962,12 @@ var TooltipRoot = fastComponent(function TooltipRoot2(props) { defaultTriggerId: defaultTriggerIdProp = null, children } = props; - const store = TooltipStore.useStore(handle?.store, { + const store = usePopupRootStore((floatingId, nested) => new TooltipStore({ open: defaultOpen, openProp, activeTriggerId: defaultTriggerIdProp, triggerIdProp - }); - useInitialOpenSync(store, openProp, defaultOpen, defaultTriggerIdProp); + }, floatingId, nested)); store.useControlledProp("openProp", openProp); store.useControlledProp("triggerIdProp", triggerIdProp); store.useContextCallback("onOpenChange", onOpenChange); @@ -7905,9 +7979,9 @@ var TooltipRoot = fastComponent(function TooltipRoot2(props) { const payload = store.useState("payload"); store.useSyncedValues({ trackCursorAxis, - disableHoverablePopup + disableHoverablePopup, + disabled: disabled2 }); - store.useSyncedValue("disabled", disabled2); useImplicitActiveTrigger(store, { closeOnActiveTriggerUnmount: true }); @@ -7918,7 +7992,7 @@ var TooltipRoot = fastComponent(function TooltipRoot2(props) { const isInstantPhase = store.useState("isInstantPhase"); const instantType = store.useState("instantType"); const lastOpenChangeReason = store.useState("lastOpenChangeReason"); - const previousInstantTypeRef = React38.useRef(null); + const previousInstantTypeRef = React37.useRef(null); useIsoLayoutEffect(() => { if (openState && disabled2) { store.setOpen(false, createChangeEventDetails(reason_parts_exports.disabled)); @@ -7942,17 +8016,17 @@ var TooltipRoot = fastComponent(function TooltipRoot2(props) { } } }, [store, activeTriggerId, open]); - const handleImperativeClose = React38.useCallback(() => { - store.setOpen(false, createChangeEventDetails(reason_parts_exports.imperativeAction)); - }, [store]); - React38.useImperativeHandle(actionsRef, () => ({ + React37.useImperativeHandle(actionsRef, () => ({ unmount: forceUnmount, - close: handleImperativeClose - }), [forceUnmount, handleImperativeClose]); + close: () => store.setOpen(false, createChangeEventDetails(reason_parts_exports.imperativeAction)) + }), [forceUnmount, store]); const shouldRenderInteractions = open || mounted || !disabled2 && trackCursorAxis !== "none"; return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(TooltipRootContext.Provider, { value: store, - children: [shouldRenderInteractions && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipInteractions, { + children: [handle && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PopupHandleAttachment, { + handle, + store + }), shouldRenderInteractions && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipInteractions, { store, disabled: disabled2, trackCursorAxis @@ -7976,35 +8050,26 @@ function TooltipInteractions({ enabled: !disabled2 && trackCursorAxis !== "none", axis: trackCursorAxis === "none" ? void 0 : trackCursorAxis }); - const activeTriggerProps = React38.useMemo(() => mergeProps(clientPoint.reference, dismiss.reference), [clientPoint.reference, dismiss.reference]); - const inactiveTriggerProps = React38.useMemo(() => mergeProps(clientPoint.trigger, dismiss.trigger), [clientPoint.trigger, dismiss.trigger]); - const popupProps = React38.useMemo(() => mergeProps(FOCUSABLE_POPUP_PROPS, clientPoint.floating, dismiss.floating), [clientPoint.floating, dismiss.floating]); + const triggerProps = React37.useMemo(() => mergeProps(clientPoint.reference, dismiss.reference), [clientPoint.reference, dismiss.reference]); usePopupInteractionProps(store, { - activeTriggerProps, - inactiveTriggerProps, - popupProps + activeTriggerProps: triggerProps, + inactiveTriggerProps: triggerProps, + popupProps: dismiss.floating ?? EMPTY_OBJECT }); return null; } // node_modules/@base-ui/react/tooltip/trigger/TooltipTrigger.mjs -var React40 = __toESM(require_react(), 1); +var React39 = __toESM(require_react(), 1); // node_modules/@base-ui/react/tooltip/provider/TooltipProviderContext.mjs -var React39 = __toESM(require_react(), 1); -var TooltipProviderContext = /* @__PURE__ */ React39.createContext(void 0); +var React38 = __toESM(require_react(), 1); +var TooltipProviderContext = /* @__PURE__ */ React38.createContext(void 0); if (true) TooltipProviderContext.displayName = "TooltipProviderContext"; function useTooltipProviderContext() { - return React39.useContext(TooltipProviderContext); + return React38.useContext(TooltipProviderContext); } -// node_modules/@base-ui/react/tooltip/trigger/TooltipTriggerDataAttributes.mjs -var TooltipTriggerDataAttributes = (function(TooltipTriggerDataAttributes2) { - TooltipTriggerDataAttributes2[TooltipTriggerDataAttributes2["popupOpen"] = CommonTriggerDataAttributes.popupOpen] = "popupOpen"; - TooltipTriggerDataAttributes2["triggerDisabled"] = "data-trigger-disabled"; - return TooltipTriggerDataAttributes2; -})({}); - // node_modules/@base-ui/react/tooltip/utils/constants.mjs var OPEN_DELAY = 600; @@ -8029,13 +8094,9 @@ function getTargetElement(event) { function closestEnabledTooltipTrigger(element) { let current = element; while (current) { - if (current.hasAttribute(TOOLTIP_TRIGGER_IDENTIFIER)) { - return current; - } - const parentElement = current.parentElement; - if (parentElement) { - current = parentElement; - continue; + const trigger = current.closest(`[${TOOLTIP_TRIGGER_IDENTIFIER}]`); + if (trigger) { + return trigger; } const root = current.getRootNode(); current = "host" in root && isElement(root.host) ? root.host : null; @@ -8057,7 +8118,8 @@ var TooltipTrigger = fastComponentRef(function TooltipTrigger2(componentProps, f ...elementProps } = componentProps; const rootContext = useTooltipRootContext(true); - const store = handle?.store ?? rootContext; + const handleStore = usePopupHandleStore(handle); + const store = handleStore ?? rootContext; if (!store) { throw new Error(true ? "Base UI: must be either used within a component or provided with a handle." : formatErrorMessage_default(82)); } @@ -8065,7 +8127,7 @@ var TooltipTrigger = fastComponentRef(function TooltipTrigger2(componentProps, f const isTriggerActive = store.useState("isTriggerActive", thisTriggerId); const isOpenedByThisTrigger = store.useState("isOpenedByTrigger", thisTriggerId); const floatingRootContext = store.useState("floatingRootContext"); - const triggerElementRef = React40.useRef(null); + const triggerElementRef = React39.useRef(null); const delayWithDefault = delay ?? OPEN_DELAY; const closeDelayWithDefault = closeDelay ?? 0; const { @@ -8076,7 +8138,7 @@ var TooltipTrigger = fastComponentRef(function TooltipTrigger2(componentProps, f closeOnClick, closeDelay: closeDelayWithDefault }); - const providerContext = useTooltipProviderContext(); + const providerDelay = useTooltipProviderContext(); const { delayRef, isInstantPhase, @@ -8091,21 +8153,14 @@ var TooltipTrigger = fastComponentRef(function TooltipTrigger2(componentProps, f const disabledRef = useValueAsRef(disabled2); const trackCursorAxis = store.useState("trackCursorAxis"); const disableHoverablePopup = store.useState("disableHoverablePopup"); - const isNestedTriggerHoveredRef = React40.useRef(false); + const isNestedTriggerHoveredRef = React39.useRef(false); const nestedTriggerOpenTimeout = useTimeout(); - const pointerTypeRef = React40.useRef(void 0); + const pointerTypeRef = React39.useRef(void 0); function getOpenDelay() { - const providerDelay = providerContext?.delay; - const groupOpenValue = typeof delayRef.current === "object" ? delayRef.current.open : void 0; - let computedOpenDelay = delayWithDefault; - if (hasProvider) { - if (groupOpenValue !== 0) { - computedOpenDelay = delay ?? providerDelay ?? delayWithDefault; - } else { - computedOpenDelay = 0; - } + if (!hasProvider) { + return delayWithDefault; } - return computedOpenDelay; + return getDelay(delayRef.current, "open") === 0 ? 0 : delay ?? providerDelay ?? OPEN_DELAY; } function isEnabledNestedTriggerTarget(target) { const triggerEl = triggerElementRef.current; @@ -8133,13 +8188,13 @@ var TooltipTrigger = fastComponentRef(function TooltipTrigger2(componentProps, f handleClose: !disableHoverablePopup && trackCursorAxis !== "both" ? safePolygon() : null, restMs: getOpenDelay, delay() { - const closeValue = typeof delayRef.current === "object" ? delayRef.current.close : void 0; - let computedCloseDelay = closeDelayWithDefault; if (closeDelay == null && hasProvider) { - computedCloseDelay = closeValue; + return { + close: getDelay(delayRef.current, "close") + }; } return { - close: computedCloseDelay + close: closeDelayWithDefault }; }, triggerElementRef, @@ -8216,7 +8271,7 @@ var TooltipTrigger = fastComponentRef(function TooltipTrigger2(componentProps, f } }, id: thisTriggerId, - [TooltipTriggerDataAttributes.triggerDisabled]: disabled2 ? "" : void 0, + "data-trigger-disabled": disabled2 ? "" : void 0, [TOOLTIP_TRIGGER_IDENTIFIER]: disabled2 ? void 0 : "" }, elementProps], stateAttributesMapping: triggerOpenStateMapping @@ -8226,14 +8281,14 @@ var TooltipTrigger = fastComponentRef(function TooltipTrigger2(componentProps, f if (true) TooltipTrigger.displayName = "TooltipTrigger"; // node_modules/@base-ui/react/tooltip/portal/TooltipPortal.mjs -var React42 = __toESM(require_react(), 1); +var React41 = __toESM(require_react(), 1); // node_modules/@base-ui/react/tooltip/portal/TooltipPortalContext.mjs -var React41 = __toESM(require_react(), 1); -var TooltipPortalContext = /* @__PURE__ */ React41.createContext(void 0); +var React40 = __toESM(require_react(), 1); +var TooltipPortalContext = /* @__PURE__ */ React40.createContext(void 0); if (true) TooltipPortalContext.displayName = "TooltipPortalContext"; function useTooltipPortalContext() { - const value = React41.useContext(TooltipPortalContext); + const value = React40.useContext(TooltipPortalContext); if (value === void 0) { throw new Error(true ? "Base UI: is missing." : formatErrorMessage_default(70)); } @@ -8242,7 +8297,7 @@ function useTooltipPortalContext() { // node_modules/@base-ui/react/tooltip/portal/TooltipPortal.mjs var import_jsx_runtime9 = __toESM(require_jsx_runtime(), 1); -var TooltipPortal = /* @__PURE__ */ React42.forwardRef(function TooltipPortal2(props, forwardedRef) { +var TooltipPortal = /* @__PURE__ */ React41.forwardRef(function TooltipPortal2(props, forwardedRef) { const { keepMounted = false, ...portalProps @@ -8264,14 +8319,14 @@ var TooltipPortal = /* @__PURE__ */ React42.forwardRef(function TooltipPortal2(p if (true) TooltipPortal.displayName = "TooltipPortal"; // node_modules/@base-ui/react/tooltip/positioner/TooltipPositioner.mjs -var React44 = __toESM(require_react(), 1); +var React43 = __toESM(require_react(), 1); // node_modules/@base-ui/react/tooltip/positioner/TooltipPositionerContext.mjs -var React43 = __toESM(require_react(), 1); -var TooltipPositionerContext = /* @__PURE__ */ React43.createContext(void 0); +var React42 = __toESM(require_react(), 1); +var TooltipPositionerContext = /* @__PURE__ */ React42.createContext(void 0); if (true) TooltipPositionerContext.displayName = "TooltipPositionerContext"; function useTooltipPositionerContext() { - const context = React43.useContext(TooltipPositionerContext); + const context = React42.useContext(TooltipPositionerContext); if (context === void 0) { throw new Error(true ? "Base UI: TooltipPositionerContext is missing. TooltipPositioner parts must be placed within ." : formatErrorMessage_default(71)); } @@ -8280,7 +8335,7 @@ function useTooltipPositionerContext() { // node_modules/@base-ui/react/tooltip/positioner/TooltipPositioner.mjs var import_jsx_runtime10 = __toESM(require_jsx_runtime(), 1); -var TooltipPositioner = /* @__PURE__ */ React44.forwardRef(function TooltipPositioner2(componentProps, forwardedRef) { +var TooltipPositioner = /* @__PURE__ */ React43.forwardRef(function TooltipPositioner2(componentProps, forwardedRef) { const { render, className, @@ -8308,7 +8363,7 @@ var TooltipPositioner = /* @__PURE__ */ React44.forwardRef(function TooltipPosit const floatingRootContext = store.useState("floatingRootContext"); const instantType = store.useState("instantType"); const transitionStatus = store.useState("transitionStatus"); - const hasViewport = store.useState("hasViewport"); + const adaptiveOrigin2 = store.useState("adaptiveOrigin"); const positioning = useAnchorPositioning({ anchor, positionMethod, @@ -8325,9 +8380,9 @@ var TooltipPositioner = /* @__PURE__ */ React44.forwardRef(function TooltipPosit disableAnchorTracking, keepMounted, collisionAvoidance, - adaptiveOrigin: hasViewport ? adaptiveOrigin : void 0 + adaptiveOrigin: adaptiveOrigin2 }); - const state = React44.useMemo(() => ({ + const state = React43.useMemo(() => ({ open, side: positioning.side, align: positioning.align, @@ -8350,12 +8405,8 @@ var TooltipPositioner = /* @__PURE__ */ React44.forwardRef(function TooltipPosit if (true) TooltipPositioner.displayName = "TooltipPositioner"; // node_modules/@base-ui/react/tooltip/popup/TooltipPopup.mjs -var React45 = __toESM(require_react(), 1); -var stateAttributesMapping = { - ...popupStateMapping, - ...transitionStatusMapping -}; -var TooltipPopup = /* @__PURE__ */ React45.forwardRef(function TooltipPopup2(componentProps, forwardedRef) { +var React44 = __toESM(require_react(), 1); +var TooltipPopup = /* @__PURE__ */ React44.forwardRef(function TooltipPopup2(componentProps, forwardedRef) { const { render, className, @@ -8398,16 +8449,16 @@ var TooltipPopup = /* @__PURE__ */ React45.forwardRef(function TooltipPopup2(com const element = useRenderElement("div", componentProps, { state, ref: [forwardedRef, store.context.popupRef, setPopupElement], - props: [popupProps, getDisabledMountTransitionStyles(transitionStatus), elementProps], - stateAttributesMapping + props: [FOCUSABLE_POPUP_PROPS, popupProps, getDisabledMountTransitionStyles(transitionStatus), elementProps], + stateAttributesMapping: popupTransitionStateMapping }); return element; }); if (true) TooltipPopup.displayName = "TooltipPopup"; // node_modules/@base-ui/react/tooltip/arrow/TooltipArrow.mjs -var React46 = __toESM(require_react(), 1); -var TooltipArrow = /* @__PURE__ */ React46.forwardRef(function TooltipArrow2(componentProps, forwardedRef) { +var React45 = __toESM(require_react(), 1); +var TooltipArrow = /* @__PURE__ */ React45.forwardRef(function TooltipArrow2(componentProps, forwardedRef) { const { render, className, @@ -8445,7 +8496,7 @@ var TooltipArrow = /* @__PURE__ */ React46.forwardRef(function TooltipArrow2(com if (true) TooltipArrow.displayName = "TooltipArrow"; // node_modules/@base-ui/react/tooltip/provider/TooltipProvider.mjs -var React47 = __toESM(require_react(), 1); +var React46 = __toESM(require_react(), 1); var import_jsx_runtime11 = __toESM(require_jsx_runtime(), 1); var TooltipProvider = function TooltipProvider2(props) { const { @@ -8453,16 +8504,12 @@ var TooltipProvider = function TooltipProvider2(props) { closeDelay, timeout = 400 } = props; - const contextValue = React47.useMemo(() => ({ - delay, - closeDelay - }), [delay, closeDelay]); - const delayValue = React47.useMemo(() => ({ + const delayValue = React46.useMemo(() => ({ open: delay, close: closeDelay }), [delay, closeDelay]); return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TooltipProviderContext.Provider, { - value: contextValue, + value: delay, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(FloatingDelayGroup, { delay: delayValue, timeoutMs: timeout, @@ -8473,22 +8520,8 @@ var TooltipProvider = function TooltipProvider2(props) { if (true) TooltipProvider.displayName = "TooltipProvider"; // node_modules/@base-ui/react/tooltip/viewport/TooltipViewport.mjs -var React48 = __toESM(require_react(), 1); - -// node_modules/@base-ui/react/tooltip/viewport/TooltipViewportCssVars.mjs -var TooltipViewportCssVars = /* @__PURE__ */ (function(TooltipViewportCssVars2) { - TooltipViewportCssVars2["popupWidth"] = "--popup-width"; - TooltipViewportCssVars2["popupHeight"] = "--popup-height"; - return TooltipViewportCssVars2; -})({}); - -// node_modules/@base-ui/react/tooltip/viewport/TooltipViewport.mjs -var stateAttributesMapping2 = { - activationDirection: (value) => value ? { - "data-activation-direction": value - } : null -}; -var TooltipViewport = /* @__PURE__ */ React48.forwardRef(function TooltipViewport2(componentProps, forwardedRef) { +var React47 = __toESM(require_react(), 1); +var TooltipViewport = /* @__PURE__ */ React47.forwardRef(function TooltipViewport2(componentProps, forwardedRef) { const { render, className, @@ -8505,7 +8538,6 @@ var TooltipViewport = /* @__PURE__ */ React48.forwardRef(function TooltipViewpor } = usePopupViewport({ store, side: positioner.side, - cssVars: TooltipViewportCssVars, children }); const state = { @@ -8519,46 +8551,40 @@ var TooltipViewport = /* @__PURE__ */ React48.forwardRef(function TooltipViewpor props: [elementProps, { children: childrenToRender }], - stateAttributesMapping: stateAttributesMapping2 + stateAttributesMapping: popupViewportStateMapping }); }); if (true) TooltipViewport.displayName = "TooltipViewport"; // node_modules/@base-ui/react/tooltip/store/TooltipHandle.mjs -var TooltipHandle = class { - /** - * Internal store holding the tooltip state. - * @internal - */ +var TooltipHandle = class extends BasePopupHandle { constructor() { - this.store = new TooltipStore(); + super(createNullTooltipStore(), "Tooltip"); } /** - * Opens the tooltip and associates it with the trigger with the given ID. - * The trigger must be a Tooltip.Trigger component with this handle passed as a prop. + * Opens the tooltip and associates it with the trigger with the given id. * * This method should only be called in an event handler or an effect (not during rendering). * - * @param triggerId ID of the trigger to associate with the tooltip. + * @param triggerId ID of the trigger to associate with the tooltip. The trigger must be a matching + * `Tooltip.Trigger` with this handle passed as a prop. */ open(triggerId) { - const triggerElement = triggerId ? this.store.context.triggerElements.getById(triggerId) : void 0; - if (triggerId && !triggerElement) { - throw new Error(true ? `Base UI: TooltipHandle.open: No trigger found with id "${triggerId}".` : formatErrorMessage_default(81, triggerId)); - } - this.store.setOpen(true, createChangeEventDetails(reason_parts_exports.imperativeAction, void 0, triggerElement)); + this.openByTrigger(triggerId); } /** * Closes the tooltip. + * + * This method should only be called in an event handler or an effect (not during rendering). */ close() { - this.store.setOpen(false, createChangeEventDetails(reason_parts_exports.imperativeAction, void 0, void 0)); + this.closePopup(); } /** - * Indicates whether the tooltip is currently open. + * Whether the tooltip is currently open. Returns `false` while no root is attached to the handle. */ get isOpen() { - return this.store.select("open"); + return this.attachedStore?.select("open") ?? false; } }; function createTooltipHandle() { @@ -8716,41 +8742,24 @@ var import_primitives5 = __toESM(require_primitives(), 1); var import_jsx_runtime16 = __toESM(require_jsx_runtime(), 1); var previous_default = /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_primitives5.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_primitives5.Path, { d: "M11.6 7l-1.1-1L5 12l5.5 6 1.1-1L7 12l4.6-5zm6 0l-1.1-1-5.5 6 5.5 6 1.1-1-4.6-5 4.6-5z" }) }); -// packages/ui/build-module/utils/render-slot-with-children.mjs -var import_element12 = __toESM(require_element(), 1); -function renderSlotWithChildren(slot, defaultSlot, children) { - return (0, import_element12.cloneElement)(slot ?? defaultSlot, { children }); -} - -// packages/ui/build-module/utils/theme-provider.mjs -var theme = __toESM(require_theme(), 1); +// packages/ui/build-module/tooltip/index.mjs +var tooltip_exports = {}; +__export(tooltip_exports, { + Popup: () => Popup, + Portal: () => Portal, + Positioner: () => Positioner, + Provider: () => Provider, + Root: () => Root, + Trigger: () => Trigger +}); -// packages/ui/build-module/lock-unlock.mjs -var import_private_apis = __toESM(require_private_apis(), 1); -var { lock, unlock } = (0, import_private_apis.__dangerousOptInToUnstableAPIsOnlyForCoreModules)( - "I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.", - "@wordpress/ui" -); +// packages/ui/build-module/tooltip/popup.mjs +var import_element15 = __toESM(require_element(), 1); -// packages/ui/build-module/utils/theme-provider.mjs -function getThemeProvider() { - const themePackage = theme; - if (themePackage.ThemeProvider) { - return themePackage.ThemeProvider; - } - if (!themePackage.privateApis) { - throw new Error( - "@wordpress/ui: @wordpress/theme must expose `ThemeProvider` or `privateApis.ThemeProvider`." - ); - } - return unlock( - themePackage.privateApis - ).ThemeProvider; -} -var ThemeProvider = getThemeProvider(); +// packages/ui/build-module/tooltip/portal.mjs +var import_element12 = __toESM(require_element(), 1); -// packages/ui/build-module/stack/stack.mjs -var import_element13 = __toESM(require_element(), 1); +// packages/ui/build-module/utils/wp-compat-overlay-slot.mjs var STYLE_HASH_ATTRIBUTE2 = "data-wp-hash"; function getRuntime2() { const globalScope = globalThis; @@ -8832,152 +8841,25 @@ function registerStyle2(hash, css) { } } if (typeof process === "undefined" || true) { - registerStyle2("32aba35fe1", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._19ce0419607e1896__stack{display:flex}}}"); + registerStyle2("be37f31c1e", "._11fc52b637ff8a7e__slot{inset:0;isolation:isolate;pointer-events:none;position:fixed;z-index:1000000003}@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._11fc52b637ff8a7e__slot>*{pointer-events:auto}}}"); } -var style_default2 = { "stack": "_19ce0419607e1896__stack" }; -var gapTokens = { - xs: "var(--wpds-dimension-gap-xs, 4px)", - sm: "var(--wpds-dimension-gap-sm, 8px)", - md: "var(--wpds-dimension-gap-md, 12px)", - lg: "var(--wpds-dimension-gap-lg, 16px)", - xl: "var(--wpds-dimension-gap-xl, 24px)", - "2xl": "var(--wpds-dimension-gap-2xl, 32px)", - "3xl": "var(--wpds-dimension-gap-3xl, 40px)" -}; -var Stack = (0, import_element13.forwardRef)(function Stack2({ direction, gap, align, justify, wrap, render, ...props }, ref) { - const style = { - gap: gap && gapTokens[gap], - alignItems: align, - justifyContent: justify, - flexDirection: direction, - flexWrap: wrap - }; - const element = useRender({ - render, - ref, - props: mergeProps(props, { style, className: style_default2.stack }) - }); - return element; -}); - -// packages/ui/build-module/tooltip/index.mjs -var tooltip_exports = {}; -__export(tooltip_exports, { - Popup: () => Popup, - Portal: () => Portal, - Positioner: () => Positioner, - Provider: () => Provider, - Root: () => Root, - Trigger: () => Trigger -}); - -// packages/ui/build-module/tooltip/popup.mjs -var import_element16 = __toESM(require_element(), 1); - -// packages/ui/build-module/tooltip/portal.mjs -var import_element14 = __toESM(require_element(), 1); - -// packages/ui/build-module/utils/wp-compat-overlay-slot.mjs -var STYLE_HASH_ATTRIBUTE3 = "data-wp-hash"; -function getRuntime3() { - const globalScope = globalThis; - if (globalScope.__wpStyleRuntime) { - return globalScope.__wpStyleRuntime; - } - globalScope.__wpStyleRuntime = { - documents: /* @__PURE__ */ new Map(), - styles: /* @__PURE__ */ new Map(), - injectedStyles: /* @__PURE__ */ new WeakMap() - }; - if (typeof document !== "undefined") { - registerDocument3(document); - } - return globalScope.__wpStyleRuntime; -} -function documentContainsStyleHash3(targetDocument, hash) { - if (!targetDocument.head) { - return false; - } - for (const style of targetDocument.head.querySelectorAll( - `style[${STYLE_HASH_ATTRIBUTE3}]` - )) { - if (style.getAttribute(STYLE_HASH_ATTRIBUTE3) === hash) { - return true; - } - } - return false; -} -function injectStyle3(targetDocument, hash, css) { - if (!targetDocument.head) { - return; - } - const runtime = getRuntime3(); - let injectedStyles = runtime.injectedStyles.get(targetDocument); - if (!injectedStyles) { - injectedStyles = /* @__PURE__ */ new Set(); - runtime.injectedStyles.set(targetDocument, injectedStyles); - } - if (injectedStyles.has(hash)) { - return; - } - if (documentContainsStyleHash3(targetDocument, hash)) { - injectedStyles.add(hash); - return; - } - const style = targetDocument.createElement("style"); - style.setAttribute(STYLE_HASH_ATTRIBUTE3, hash); - style.appendChild(targetDocument.createTextNode(css)); - targetDocument.head.appendChild(style); - injectedStyles.add(hash); -} -function registerDocument3(targetDocument) { - const runtime = getRuntime3(); - runtime.documents.set( - targetDocument, - (runtime.documents.get(targetDocument) ?? 0) + 1 - ); - for (const [hash, css] of runtime.styles) { - injectStyle3(targetDocument, hash, css); - } - return () => { - const count = runtime.documents.get(targetDocument); - if (count === void 0) { - return; - } - if (count <= 1) { - runtime.documents.delete(targetDocument); - return; - } - runtime.documents.set(targetDocument, count - 1); - }; -} -function registerStyle3(hash, css) { - const runtime = getRuntime3(); - runtime.styles.set(hash, css); - for (const targetDocument of runtime.documents.keys()) { - injectStyle3(targetDocument, hash, css); - } -} -if (typeof process === "undefined" || true) { - registerStyle3("be37f31c1e", "._11fc52b637ff8a7e__slot{inset:0;isolation:isolate;pointer-events:none;position:fixed;z-index:1000000003}@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._11fc52b637ff8a7e__slot>*{pointer-events:auto}}}"); -} -var wp_compat_overlay_slot_default = { "slot": "_11fc52b637ff8a7e__slot" }; -var WP_COMPAT_OVERLAY_SLOT_ATTRIBUTE = "data-wp-compat-overlay-slot"; -function resolveOwnerDocument() { - return typeof document === "undefined" ? null : document; -} -function isInWordPressEnvironment() { - let topWp; - try { - topWp = window.top?.wp; - } catch { - } - const wp = topWp ?? window.wp; - return typeof wp?.components === "object" && wp.components !== null; -} -var cachedSlot = null; -function ensureSlotIsAccessible(element) { - element.setAttribute("aria-hidden", "false"); +var wp_compat_overlay_slot_default = { "slot": "_11fc52b637ff8a7e__slot" }; +var WP_COMPAT_OVERLAY_SLOT_ATTRIBUTE = "data-wp-compat-overlay-slot"; +function resolveOwnerDocument() { + return typeof document === "undefined" ? null : document; +} +function isInWordPressEnvironment() { + let topWp; + try { + topWp = window.top?.wp; + } catch { + } + const wp = topWp ?? window.wp; + return typeof wp?.components === "object" && wp.components !== null; +} +var cachedSlot = null; +function ensureSlotIsAccessible(element) { + element.setAttribute("aria-hidden", "false"); return element; } function createSlot(ownerDocument2) { @@ -9019,7 +8901,7 @@ function getWpCompatOverlaySlot() { // packages/ui/build-module/tooltip/portal.mjs var import_jsx_runtime17 = __toESM(require_jsx_runtime(), 1); -var Portal = (0, import_element14.forwardRef)( +var Portal = (0, import_element12.forwardRef)( function TooltipPortal3({ container, ...restProps }, ref) { return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)( index_parts_exports.Portal, @@ -9033,10 +8915,10 @@ var Portal = (0, import_element14.forwardRef)( ); // packages/ui/build-module/tooltip/positioner.mjs -var import_element15 = __toESM(require_element(), 1); +var import_element13 = __toESM(require_element(), 1); var import_jsx_runtime18 = __toESM(require_jsx_runtime(), 1); -var STYLE_HASH_ATTRIBUTE4 = "data-wp-hash"; -function getRuntime4() { +var STYLE_HASH_ATTRIBUTE3 = "data-wp-hash"; +function getRuntime3() { const globalScope = globalThis; if (globalScope.__wpStyleRuntime) { return globalScope.__wpStyleRuntime; @@ -9047,28 +8929,28 @@ function getRuntime4() { injectedStyles: /* @__PURE__ */ new WeakMap() }; if (typeof document !== "undefined") { - registerDocument4(document); + registerDocument3(document); } return globalScope.__wpStyleRuntime; } -function documentContainsStyleHash4(targetDocument, hash) { +function documentContainsStyleHash3(targetDocument, hash) { if (!targetDocument.head) { return false; } for (const style of targetDocument.head.querySelectorAll( - `style[${STYLE_HASH_ATTRIBUTE4}]` + `style[${STYLE_HASH_ATTRIBUTE3}]` )) { - if (style.getAttribute(STYLE_HASH_ATTRIBUTE4) === hash) { + if (style.getAttribute(STYLE_HASH_ATTRIBUTE3) === hash) { return true; } } return false; } -function injectStyle4(targetDocument, hash, css) { +function injectStyle3(targetDocument, hash, css) { if (!targetDocument.head) { return; } - const runtime = getRuntime4(); + const runtime = getRuntime3(); let injectedStyles = runtime.injectedStyles.get(targetDocument); if (!injectedStyles) { injectedStyles = /* @__PURE__ */ new Set(); @@ -9077,24 +8959,24 @@ function injectStyle4(targetDocument, hash, css) { if (injectedStyles.has(hash)) { return; } - if (documentContainsStyleHash4(targetDocument, hash)) { + if (documentContainsStyleHash3(targetDocument, hash)) { injectedStyles.add(hash); return; } const style = targetDocument.createElement("style"); - style.setAttribute(STYLE_HASH_ATTRIBUTE4, hash); + style.setAttribute(STYLE_HASH_ATTRIBUTE3, hash); style.appendChild(targetDocument.createTextNode(css)); targetDocument.head.appendChild(style); injectedStyles.add(hash); } -function registerDocument4(targetDocument) { - const runtime = getRuntime4(); +function registerDocument3(targetDocument) { + const runtime = getRuntime3(); runtime.documents.set( targetDocument, (runtime.documents.get(targetDocument) ?? 0) + 1 ); for (const [hash, css] of runtime.styles) { - injectStyle4(targetDocument, hash, css); + injectStyle3(targetDocument, hash, css); } return () => { const count = runtime.documents.get(targetDocument); @@ -9108,22 +8990,22 @@ function registerDocument4(targetDocument) { runtime.documents.set(targetDocument, count - 1); }; } -function registerStyle4(hash, css) { - const runtime = getRuntime4(); +function registerStyle3(hash, css) { + const runtime = getRuntime3(); runtime.styles.set(hash, css); for (const targetDocument of runtime.documents.keys()) { - injectStyle4(targetDocument, hash, css); + injectStyle3(targetDocument, hash, css); } } if (typeof process === "undefined" || true) { - registerStyle4("10f3806643", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}"); + registerStyle3("10f3806643", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}"); } var resets_default = { "box-sizing": "_336cd3e4e743482f__box-sizing" }; if (typeof process === "undefined" || true) { - registerStyle4("19fcc06039", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}'); + registerStyle3("19fcc06039", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}'); } -var style_default3 = { "positioner": "_480b748dd3510e64__positioner", "popup": "_50096b232db7709d__popup" }; -var Positioner = (0, import_element15.forwardRef)( +var style_default2 = { "positioner": "_480b748dd3510e64__positioner", "popup": "_50096b232db7709d__popup" }; +var Positioner = (0, import_element13.forwardRef)( function TooltipPositioner3({ align = "center", className, side = "top", sideOffset = 4, ...props }, ref) { return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)( index_parts_exports.Positioner, @@ -9135,7 +9017,7 @@ var Positioner = (0, import_element15.forwardRef)( ...props, className: clsx_default( resets_default["box-sizing"], - style_default3.positioner, + style_default2.positioner, className ) } @@ -9143,10 +9025,43 @@ var Positioner = (0, import_element15.forwardRef)( } ); +// packages/ui/build-module/utils/render-slot-with-children.mjs +var import_element14 = __toESM(require_element(), 1); +function renderSlotWithChildren(slot, defaultSlot, children) { + return (0, import_element14.cloneElement)(slot ?? defaultSlot, { children }); +} + +// packages/ui/build-module/utils/theme-provider.mjs +var theme = __toESM(require_theme(), 1); + +// packages/ui/build-module/lock-unlock.mjs +var import_private_apis = __toESM(require_private_apis(), 1); +var { lock, unlock } = (0, import_private_apis.__dangerousOptInToUnstableAPIsOnlyForCoreModules)( + "I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.", + "@wordpress/ui" +); + +// packages/ui/build-module/utils/theme-provider.mjs +function getThemeProvider() { + const themePackage = theme; + if (themePackage.ThemeProvider) { + return themePackage.ThemeProvider; + } + if (!themePackage.privateApis) { + throw new Error( + "@wordpress/ui: @wordpress/theme must expose `ThemeProvider` or `privateApis.ThemeProvider`." + ); + } + return unlock( + themePackage.privateApis + ).ThemeProvider; +} +var ThemeProvider = getThemeProvider(); + // packages/ui/build-module/tooltip/popup.mjs var import_jsx_runtime19 = __toESM(require_jsx_runtime(), 1); -var STYLE_HASH_ATTRIBUTE5 = "data-wp-hash"; -function getRuntime5() { +var STYLE_HASH_ATTRIBUTE4 = "data-wp-hash"; +function getRuntime4() { const globalScope = globalThis; if (globalScope.__wpStyleRuntime) { return globalScope.__wpStyleRuntime; @@ -9157,28 +9072,28 @@ function getRuntime5() { injectedStyles: /* @__PURE__ */ new WeakMap() }; if (typeof document !== "undefined") { - registerDocument5(document); + registerDocument4(document); } return globalScope.__wpStyleRuntime; } -function documentContainsStyleHash5(targetDocument, hash) { +function documentContainsStyleHash4(targetDocument, hash) { if (!targetDocument.head) { return false; } for (const style of targetDocument.head.querySelectorAll( - `style[${STYLE_HASH_ATTRIBUTE5}]` + `style[${STYLE_HASH_ATTRIBUTE4}]` )) { - if (style.getAttribute(STYLE_HASH_ATTRIBUTE5) === hash) { + if (style.getAttribute(STYLE_HASH_ATTRIBUTE4) === hash) { return true; } } return false; } -function injectStyle5(targetDocument, hash, css) { +function injectStyle4(targetDocument, hash, css) { if (!targetDocument.head) { return; } - const runtime = getRuntime5(); + const runtime = getRuntime4(); let injectedStyles = runtime.injectedStyles.get(targetDocument); if (!injectedStyles) { injectedStyles = /* @__PURE__ */ new Set(); @@ -9187,24 +9102,24 @@ function injectStyle5(targetDocument, hash, css) { if (injectedStyles.has(hash)) { return; } - if (documentContainsStyleHash5(targetDocument, hash)) { + if (documentContainsStyleHash4(targetDocument, hash)) { injectedStyles.add(hash); return; } const style = targetDocument.createElement("style"); - style.setAttribute(STYLE_HASH_ATTRIBUTE5, hash); + style.setAttribute(STYLE_HASH_ATTRIBUTE4, hash); style.appendChild(targetDocument.createTextNode(css)); targetDocument.head.appendChild(style); injectedStyles.add(hash); } -function registerDocument5(targetDocument) { - const runtime = getRuntime5(); +function registerDocument4(targetDocument) { + const runtime = getRuntime4(); runtime.documents.set( targetDocument, (runtime.documents.get(targetDocument) ?? 0) + 1 ); for (const [hash, css] of runtime.styles) { - injectStyle5(targetDocument, hash, css); + injectStyle4(targetDocument, hash, css); } return () => { const count = runtime.documents.get(targetDocument); @@ -9218,24 +9133,24 @@ function registerDocument5(targetDocument) { runtime.documents.set(targetDocument, count - 1); }; } -function registerStyle5(hash, css) { - const runtime = getRuntime5(); +function registerStyle4(hash, css) { + const runtime = getRuntime4(); runtime.styles.set(hash, css); for (const targetDocument of runtime.documents.keys()) { - injectStyle5(targetDocument, hash, css); + injectStyle4(targetDocument, hash, css); } } if (typeof process === "undefined" || true) { - registerStyle5("19fcc06039", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}'); + registerStyle4("19fcc06039", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}'); } -var style_default4 = { "positioner": "_480b748dd3510e64__positioner", "popup": "_50096b232db7709d__popup" }; +var style_default3 = { "positioner": "_480b748dd3510e64__positioner", "popup": "_50096b232db7709d__popup" }; var POPUP_COLOR = { background: "#1e1e1e" }; -var Popup = (0, import_element16.forwardRef)(function TooltipPopup3({ portal, positioner, children, className, ...props }, ref) { +var Popup = (0, import_element15.forwardRef)(function TooltipPopup3({ portal, positioner, children, className, ...props }, ref) { const popupContent = /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ThemeProvider, { color: POPUP_COLOR, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)( index_parts_exports.Popup, { ref, - className: clsx_default(style_default4.popup, className), + className: clsx_default(style_default3.popup, className), ...props, children } @@ -9249,9 +9164,9 @@ var Popup = (0, import_element16.forwardRef)(function TooltipPopup3({ portal, po }); // packages/ui/build-module/tooltip/trigger.mjs -var import_element17 = __toESM(require_element(), 1); +var import_element16 = __toESM(require_element(), 1); var import_jsx_runtime20 = __toESM(require_jsx_runtime(), 1); -var Trigger = (0, import_element17.forwardRef)( +var Trigger = (0, import_element16.forwardRef)( function TooltipTrigger3(props, ref) { return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(index_parts_exports.Trigger, { ref, ...props }); } @@ -9276,10 +9191,10 @@ function Provider({ ...props }) { return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(index_parts_exports.Provider, { ...props }); } -// packages/ui/build-module/skeleton/skeleton.mjs -var import_element18 = __toESM(require_element(), 1); -var STYLE_HASH_ATTRIBUTE6 = "data-wp-hash"; -function getRuntime6() { +// packages/ui/build-module/visually-hidden/visually-hidden.mjs +var import_element17 = __toESM(require_element(), 1); +var STYLE_HASH_ATTRIBUTE5 = "data-wp-hash"; +function getRuntime5() { const globalScope = globalThis; if (globalScope.__wpStyleRuntime) { return globalScope.__wpStyleRuntime; @@ -9290,28 +9205,28 @@ function getRuntime6() { injectedStyles: /* @__PURE__ */ new WeakMap() }; if (typeof document !== "undefined") { - registerDocument6(document); + registerDocument5(document); } return globalScope.__wpStyleRuntime; } -function documentContainsStyleHash6(targetDocument, hash) { +function documentContainsStyleHash5(targetDocument, hash) { if (!targetDocument.head) { return false; } for (const style of targetDocument.head.querySelectorAll( - `style[${STYLE_HASH_ATTRIBUTE6}]` + `style[${STYLE_HASH_ATTRIBUTE5}]` )) { - if (style.getAttribute(STYLE_HASH_ATTRIBUTE6) === hash) { + if (style.getAttribute(STYLE_HASH_ATTRIBUTE5) === hash) { return true; } } return false; } -function injectStyle6(targetDocument, hash, css) { +function injectStyle5(targetDocument, hash, css) { if (!targetDocument.head) { return; } - const runtime = getRuntime6(); + const runtime = getRuntime5(); let injectedStyles = runtime.injectedStyles.get(targetDocument); if (!injectedStyles) { injectedStyles = /* @__PURE__ */ new Set(); @@ -9320,24 +9235,24 @@ function injectStyle6(targetDocument, hash, css) { if (injectedStyles.has(hash)) { return; } - if (documentContainsStyleHash6(targetDocument, hash)) { + if (documentContainsStyleHash5(targetDocument, hash)) { injectedStyles.add(hash); return; } const style = targetDocument.createElement("style"); - style.setAttribute(STYLE_HASH_ATTRIBUTE6, hash); + style.setAttribute(STYLE_HASH_ATTRIBUTE5, hash); style.appendChild(targetDocument.createTextNode(css)); targetDocument.head.appendChild(style); injectedStyles.add(hash); } -function registerDocument6(targetDocument) { - const runtime = getRuntime6(); +function registerDocument5(targetDocument) { + const runtime = getRuntime5(); runtime.documents.set( targetDocument, (runtime.documents.get(targetDocument) ?? 0) + 1 ); for (const [hash, css] of runtime.styles) { - injectStyle6(targetDocument, hash, css); + injectStyle5(targetDocument, hash, css); } return () => { const count = runtime.documents.get(targetDocument); @@ -9351,32 +9266,390 @@ function registerDocument6(targetDocument) { runtime.documents.set(targetDocument, count - 1); }; } -function registerStyle6(hash, css) { - const runtime = getRuntime6(); +function registerStyle5(hash, css) { + const runtime = getRuntime5(); runtime.styles.set(hash, css); for (const targetDocument of runtime.documents.keys()) { - injectStyle6(targetDocument, hash, css); + injectStyle5(targetDocument, hash, css); } } if (typeof process === "undefined" || true) { - registerStyle6("10f3806643", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}"); + registerStyle5("fa606a57ae", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.f37b9e2e191ebd66__visually-hidden{word-wrap:normal;border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-break:normal}}}"); } -var resets_default2 = { "box-sizing": "_336cd3e4e743482f__box-sizing" }; -if (typeof process === "undefined" || true) { - registerStyle6("ed2c39ec90", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.b20cc1690085c2f0__skeleton{background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);display:block;@media (forced-colors:active){border:var(--wpds-border-width-xs,1px) solid CanvasText}}._9b143194fdb45f93__pulse{@media not (prefers-reduced-motion){animation:e2b9fe0690281bc8__skeleton-pulse 1.5s ease-in-out infinite}}@keyframes e2b9fe0690281bc8__skeleton-pulse{0%,to{opacity:1}50%{opacity:.4}}}}"); -} -var style_default5 = { "skeleton": "b20cc1690085c2f0__skeleton", "pulse": "_9b143194fdb45f93__pulse", "skeleton-pulse": "e2b9fe0690281bc8__skeleton-pulse" }; -var Skeleton = (0, import_element18.forwardRef)( - function Skeleton2({ render, ...props }, ref) { +var style_default4 = { "visually-hidden": "f37b9e2e191ebd66__visually-hidden" }; +var VisuallyHidden = (0, import_element17.forwardRef)( + function VisuallyHidden2({ render, ...restProps }, ref) { + const element = useRender({ + render, + ref, + props: mergeProps( + { className: style_default4["visually-hidden"] }, + restProps, + { + // @ts-expect-error Arbitrary data-* attributes aren't indexable on the typed div props. Kept hardcoded so consumers can't change or remove it. + "data-visually-hidden": "" + } + ) + }); + return element; + } +); + +// packages/ui/build-module/stack/stack.mjs +var import_element18 = __toESM(require_element(), 1); +var STYLE_HASH_ATTRIBUTE6 = "data-wp-hash"; +function getRuntime6() { + const globalScope = globalThis; + if (globalScope.__wpStyleRuntime) { + return globalScope.__wpStyleRuntime; + } + globalScope.__wpStyleRuntime = { + documents: /* @__PURE__ */ new Map(), + styles: /* @__PURE__ */ new Map(), + injectedStyles: /* @__PURE__ */ new WeakMap() + }; + if (typeof document !== "undefined") { + registerDocument6(document); + } + return globalScope.__wpStyleRuntime; +} +function documentContainsStyleHash6(targetDocument, hash) { + if (!targetDocument.head) { + return false; + } + for (const style of targetDocument.head.querySelectorAll( + `style[${STYLE_HASH_ATTRIBUTE6}]` + )) { + if (style.getAttribute(STYLE_HASH_ATTRIBUTE6) === hash) { + return true; + } + } + return false; +} +function injectStyle6(targetDocument, hash, css) { + if (!targetDocument.head) { + return; + } + const runtime = getRuntime6(); + let injectedStyles = runtime.injectedStyles.get(targetDocument); + if (!injectedStyles) { + injectedStyles = /* @__PURE__ */ new Set(); + runtime.injectedStyles.set(targetDocument, injectedStyles); + } + if (injectedStyles.has(hash)) { + return; + } + if (documentContainsStyleHash6(targetDocument, hash)) { + injectedStyles.add(hash); + return; + } + const style = targetDocument.createElement("style"); + style.setAttribute(STYLE_HASH_ATTRIBUTE6, hash); + style.appendChild(targetDocument.createTextNode(css)); + targetDocument.head.appendChild(style); + injectedStyles.add(hash); +} +function registerDocument6(targetDocument) { + const runtime = getRuntime6(); + runtime.documents.set( + targetDocument, + (runtime.documents.get(targetDocument) ?? 0) + 1 + ); + for (const [hash, css] of runtime.styles) { + injectStyle6(targetDocument, hash, css); + } + return () => { + const count = runtime.documents.get(targetDocument); + if (count === void 0) { + return; + } + if (count <= 1) { + runtime.documents.delete(targetDocument); + return; + } + runtime.documents.set(targetDocument, count - 1); + }; +} +function registerStyle6(hash, css) { + const runtime = getRuntime6(); + runtime.styles.set(hash, css); + for (const targetDocument of runtime.documents.keys()) { + injectStyle6(targetDocument, hash, css); + } +} +if (typeof process === "undefined" || true) { + registerStyle6("32aba35fe1", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._19ce0419607e1896__stack{display:flex}}}"); +} +var style_default5 = { "stack": "_19ce0419607e1896__stack" }; +var gapTokens = { + xs: "var(--wpds-dimension-gap-xs, 4px)", + sm: "var(--wpds-dimension-gap-sm, 8px)", + md: "var(--wpds-dimension-gap-md, 12px)", + lg: "var(--wpds-dimension-gap-lg, 16px)", + xl: "var(--wpds-dimension-gap-xl, 24px)", + "2xl": "var(--wpds-dimension-gap-2xl, 32px)", + "3xl": "var(--wpds-dimension-gap-3xl, 40px)" +}; +var Stack = (0, import_element18.forwardRef)(function Stack2({ direction, gap, align, justify, wrap, render, ...props }, ref) { + const style = { + gap: gap && gapTokens[gap], + alignItems: align, + justifyContent: justify, + flexDirection: direction, + flexWrap: wrap + }; + const element = useRender({ + render, + ref, + props: mergeProps(props, { style, className: style_default5.stack }) + }); + return element; +}); + +// packages/ui/build-module/link/link.mjs +var import_element19 = __toESM(require_element(), 1); +var import_i18n2 = __toESM(require_i18n(), 1); +var import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1); +var STYLE_HASH_ATTRIBUTE7 = "data-wp-hash"; +function getRuntime7() { + const globalScope = globalThis; + if (globalScope.__wpStyleRuntime) { + return globalScope.__wpStyleRuntime; + } + globalScope.__wpStyleRuntime = { + documents: /* @__PURE__ */ new Map(), + styles: /* @__PURE__ */ new Map(), + injectedStyles: /* @__PURE__ */ new WeakMap() + }; + if (typeof document !== "undefined") { + registerDocument7(document); + } + return globalScope.__wpStyleRuntime; +} +function documentContainsStyleHash7(targetDocument, hash) { + if (!targetDocument.head) { + return false; + } + for (const style of targetDocument.head.querySelectorAll( + `style[${STYLE_HASH_ATTRIBUTE7}]` + )) { + if (style.getAttribute(STYLE_HASH_ATTRIBUTE7) === hash) { + return true; + } + } + return false; +} +function injectStyle7(targetDocument, hash, css) { + if (!targetDocument.head) { + return; + } + const runtime = getRuntime7(); + let injectedStyles = runtime.injectedStyles.get(targetDocument); + if (!injectedStyles) { + injectedStyles = /* @__PURE__ */ new Set(); + runtime.injectedStyles.set(targetDocument, injectedStyles); + } + if (injectedStyles.has(hash)) { + return; + } + if (documentContainsStyleHash7(targetDocument, hash)) { + injectedStyles.add(hash); + return; + } + const style = targetDocument.createElement("style"); + style.setAttribute(STYLE_HASH_ATTRIBUTE7, hash); + style.appendChild(targetDocument.createTextNode(css)); + targetDocument.head.appendChild(style); + injectedStyles.add(hash); +} +function registerDocument7(targetDocument) { + const runtime = getRuntime7(); + runtime.documents.set( + targetDocument, + (runtime.documents.get(targetDocument) ?? 0) + 1 + ); + for (const [hash, css] of runtime.styles) { + injectStyle7(targetDocument, hash, css); + } + return () => { + const count = runtime.documents.get(targetDocument); + if (count === void 0) { + return; + } + if (count <= 1) { + runtime.documents.delete(targetDocument); + return; + } + runtime.documents.set(targetDocument, count - 1); + }; +} +function registerStyle7(hash, css) { + const runtime = getRuntime7(); + runtime.styles.set(hash, css); + for (const targetDocument of runtime.documents.keys()) { + injectStyle7(targetDocument, hash, css); + } +} +if (typeof process === "undefined" || true) { + registerStyle7("10f3806643", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}"); +} +var resets_default2 = { "box-sizing": "_336cd3e4e743482f__box-sizing" }; +if (typeof process === "undefined" || true) { + registerStyle7("96553466c8", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._64de9947bf305b7a__outset-ring--focus-within-visible:focus-within:has(:focus-visible),.af79fb116edb0dd7__outset-ring--focus:focus,.dfcfdc28396e5d98__outset-ring--focus-visible:focus-visible,.e5cd9ee879f6403a__outset-ring--focus-within:focus-within,:focus-visible ._81935a08e952f267__outset-ring--focus-parent-visible{--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within,.abc777e9713fa711__outset-ring--focus-except-active:focus{outline:none}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within:not(:has(:active)),.abc777e9713fa711__outset-ring--focus-except-active:focus:not(:active){--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}}}"); +} +var focus_module_default = { "outset-ring--focus": "af79fb116edb0dd7__outset-ring--focus", "outset-ring--focus-visible": "dfcfdc28396e5d98__outset-ring--focus-visible", "outset-ring--focus-within": "e5cd9ee879f6403a__outset-ring--focus-within", "outset-ring--focus-within-visible": "_64de9947bf305b7a__outset-ring--focus-within-visible", "outset-ring--focus-parent-visible": "_81935a08e952f267__outset-ring--focus-parent-visible", "outset-ring--focus-except-active": "abc777e9713fa711__outset-ring--focus-except-active", "outset-ring--focus-within-except-active": "_3c9f5ee9fc9c136d__outset-ring--focus-within-except-active" }; +if (typeof process === "undefined" || true) { + registerStyle7("e8e6a9be37", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.d4250949359b05ce__link{text-decoration-thickness:from-font;text-underline-offset:.2em}.c6055659b8e2cd2c__is-brand,.c6055659b8e2cd2c__is-brand:visited{--_gcd-a-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9))}.c6055659b8e2cd2c__is-brand:active,.c6055659b8e2cd2c__is-brand:hover{--_gcd-a-color:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));color:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000))}._92e0dfcaeee15b88__is-neutral,._92e0dfcaeee15b88__is-neutral:visited{--_gcd-a-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);text-decoration-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d)}._92e0dfcaeee15b88__is-neutral:active,._92e0dfcaeee15b88__is-neutral:hover{--_gcd-a-color:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);color:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e)}.cf122a9bf1035d42__is-unstyled{--_gcd-a-color:inherit;color:inherit;text-decoration:none}._0cb411afac4c86c7__link-icon{display:inline-block;font-weight:var(--wpds-typography-font-weight-default,400);line-height:1;margin-inline-start:var(--wpds-dimension-padding-xs,4px);text-decoration:none}._0cb411afac4c86c7__link-icon:after{content:"\\2197"}._0cb411afac4c86c7__link-icon:dir(rtl):after{content:"\\2196"}}}'); +} +var style_default6 = { "link": "d4250949359b05ce__link", "is-brand": "c6055659b8e2cd2c__is-brand", "is-neutral": "_92e0dfcaeee15b88__is-neutral", "is-unstyled": "cf122a9bf1035d42__is-unstyled", "link-icon": "_0cb411afac4c86c7__link-icon" }; +if (typeof process === "undefined" || true) { + registerStyle7("af6d9984a6", "._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}"); +} +var global_css_defense_default2 = { "button": "_6defc79820e382c6__button", "input": "d2cff2e5dea83bd1__input", "textarea": "_547d86373d02e108__textarea", "div": "_8c15fd0ed9f28ba4__div", "p": "_43cec3e1eec1066d__p", "heading": "e97669c6d9a38497__heading", "a": "_2c0831b0499dbd6e__a" }; +var Link = (0, import_element19.forwardRef)(function Link2({ + children, + variant = "default", + tone = "brand", + openInNewTab = false, + render, + className, + ...props +}, ref) { + const element = useRender({ + render, + defaultTagName: "a", + ref, + props: mergeProps(props, { + className: clsx_default( + global_css_defense_default2.a, + resets_default2["box-sizing"], + focus_module_default["outset-ring--focus-except-active"], + variant !== "unstyled" && style_default6.link, + variant !== "unstyled" && style_default6[`is-${tone}`], + variant === "unstyled" && style_default6["is-unstyled"], + className + ), + target: openInNewTab ? "_blank" : void 0, + children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [ + children, + openInNewTab && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)( + "span", + { + className: style_default6["link-icon"], + role: "img", + "aria-label": ( + /* translators: accessibility text appended to link text */ + (0, import_i18n2.__)("(opens in a new tab)") + ) + } + ) + ] }) + }) + }); + return element; +}); + +// packages/ui/build-module/skeleton/skeleton.mjs +var import_element20 = __toESM(require_element(), 1); +var STYLE_HASH_ATTRIBUTE8 = "data-wp-hash"; +function getRuntime8() { + const globalScope = globalThis; + if (globalScope.__wpStyleRuntime) { + return globalScope.__wpStyleRuntime; + } + globalScope.__wpStyleRuntime = { + documents: /* @__PURE__ */ new Map(), + styles: /* @__PURE__ */ new Map(), + injectedStyles: /* @__PURE__ */ new WeakMap() + }; + if (typeof document !== "undefined") { + registerDocument8(document); + } + return globalScope.__wpStyleRuntime; +} +function documentContainsStyleHash8(targetDocument, hash) { + if (!targetDocument.head) { + return false; + } + for (const style of targetDocument.head.querySelectorAll( + `style[${STYLE_HASH_ATTRIBUTE8}]` + )) { + if (style.getAttribute(STYLE_HASH_ATTRIBUTE8) === hash) { + return true; + } + } + return false; +} +function injectStyle8(targetDocument, hash, css) { + if (!targetDocument.head) { + return; + } + const runtime = getRuntime8(); + let injectedStyles = runtime.injectedStyles.get(targetDocument); + if (!injectedStyles) { + injectedStyles = /* @__PURE__ */ new Set(); + runtime.injectedStyles.set(targetDocument, injectedStyles); + } + if (injectedStyles.has(hash)) { + return; + } + if (documentContainsStyleHash8(targetDocument, hash)) { + injectedStyles.add(hash); + return; + } + const style = targetDocument.createElement("style"); + style.setAttribute(STYLE_HASH_ATTRIBUTE8, hash); + style.appendChild(targetDocument.createTextNode(css)); + targetDocument.head.appendChild(style); + injectedStyles.add(hash); +} +function registerDocument8(targetDocument) { + const runtime = getRuntime8(); + runtime.documents.set( + targetDocument, + (runtime.documents.get(targetDocument) ?? 0) + 1 + ); + for (const [hash, css] of runtime.styles) { + injectStyle8(targetDocument, hash, css); + } + return () => { + const count = runtime.documents.get(targetDocument); + if (count === void 0) { + return; + } + if (count <= 1) { + runtime.documents.delete(targetDocument); + return; + } + runtime.documents.set(targetDocument, count - 1); + }; +} +function registerStyle8(hash, css) { + const runtime = getRuntime8(); + runtime.styles.set(hash, css); + for (const targetDocument of runtime.documents.keys()) { + injectStyle8(targetDocument, hash, css); + } +} +if (typeof process === "undefined" || true) { + registerStyle8("10f3806643", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}"); +} +var resets_default3 = { "box-sizing": "_336cd3e4e743482f__box-sizing" }; +if (typeof process === "undefined" || true) { + registerStyle8("ed2c39ec90", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.b20cc1690085c2f0__skeleton{background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);display:block;@media (forced-colors:active){border:var(--wpds-border-width-xs,1px) solid CanvasText}}._9b143194fdb45f93__pulse{@media not (prefers-reduced-motion){animation:e2b9fe0690281bc8__skeleton-pulse 1.5s ease-in-out infinite}}@keyframes e2b9fe0690281bc8__skeleton-pulse{0%,to{opacity:1}50%{opacity:.4}}}}"); +} +var style_default7 = { "skeleton": "b20cc1690085c2f0__skeleton", "pulse": "_9b143194fdb45f93__pulse", "skeleton-pulse": "e2b9fe0690281bc8__skeleton-pulse" }; +var Skeleton = (0, import_element20.forwardRef)( + function Skeleton2({ render, ...props }, ref) { return useRender({ render, ref, props: mergeProps( { className: clsx_default( - style_default5.skeleton, - style_default5.pulse, - resets_default2["box-sizing"] + style_default7.skeleton, + style_default7.pulse, + resets_default3["box-sizing"] ), // Decorative by default; consumers mark the loading // region with aria-busy / role="status". @@ -9389,11 +9662,11 @@ var Skeleton = (0, import_element18.forwardRef)( ); // packages/admin-ui/build-module/navigable-region/index.mjs -var import_element19 = __toESM(require_element(), 1); -var import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1); -var NavigableRegion = (0, import_element19.forwardRef)( +var import_element21 = __toESM(require_element(), 1); +var import_jsx_runtime25 = __toESM(require_jsx_runtime(), 1); +var NavigableRegion = (0, import_element21.forwardRef)( ({ children, className, ariaLabel, as: Tag = "div", ...props }, ref) => { - return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)( + return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)( Tag, { ref, @@ -9410,14 +9683,159 @@ var NavigableRegion = (0, import_element19.forwardRef)( NavigableRegion.displayName = "NavigableRegion"; var navigable_region_default = NavigableRegion; +// packages/admin-ui/build-module/navigation/index.mjs +var import_i18n3 = __toESM(require_i18n(), 1); +var import_jsx_runtime26 = __toESM(require_jsx_runtime(), 1); +var STYLE_HASH_ATTRIBUTE9 = "data-wp-hash"; +function getRuntime9() { + const globalScope = globalThis; + if (globalScope.__wpStyleRuntime) { + return globalScope.__wpStyleRuntime; + } + globalScope.__wpStyleRuntime = { + documents: /* @__PURE__ */ new Map(), + styles: /* @__PURE__ */ new Map(), + injectedStyles: /* @__PURE__ */ new WeakMap() + }; + if (typeof document !== "undefined") { + registerDocument9(document); + } + return globalScope.__wpStyleRuntime; +} +function documentContainsStyleHash9(targetDocument, hash) { + if (!targetDocument.head) { + return false; + } + for (const style of targetDocument.head.querySelectorAll( + `style[${STYLE_HASH_ATTRIBUTE9}]` + )) { + if (style.getAttribute(STYLE_HASH_ATTRIBUTE9) === hash) { + return true; + } + } + return false; +} +function injectStyle9(targetDocument, hash, css) { + if (!targetDocument.head) { + return; + } + const runtime = getRuntime9(); + let injectedStyles = runtime.injectedStyles.get(targetDocument); + if (!injectedStyles) { + injectedStyles = /* @__PURE__ */ new Set(); + runtime.injectedStyles.set(targetDocument, injectedStyles); + } + if (injectedStyles.has(hash)) { + return; + } + if (documentContainsStyleHash9(targetDocument, hash)) { + injectedStyles.add(hash); + return; + } + const style = targetDocument.createElement("style"); + style.setAttribute(STYLE_HASH_ATTRIBUTE9, hash); + style.appendChild(targetDocument.createTextNode(css)); + targetDocument.head.appendChild(style); + injectedStyles.add(hash); +} +function registerDocument9(targetDocument) { + const runtime = getRuntime9(); + runtime.documents.set( + targetDocument, + (runtime.documents.get(targetDocument) ?? 0) + 1 + ); + for (const [hash, css] of runtime.styles) { + injectStyle9(targetDocument, hash, css); + } + return () => { + const count = runtime.documents.get(targetDocument); + if (count === void 0) { + return; + } + if (count <= 1) { + runtime.documents.delete(targetDocument); + return; + } + runtime.documents.set(targetDocument, count - 1); + }; +} +function registerStyle9(hash, css) { + const runtime = getRuntime9(); + runtime.styles.set(hash, css); + for (const targetDocument of runtime.documents.keys()) { + injectStyle9(targetDocument, hash, css); + } +} +if (typeof process === "undefined" || true) { + registerStyle9("72ef022400", ".bfb5a2dd8cceebd3__list{--focus-ring-size:calc(var(--wpds-border-width-focus, var(--wp-admin-border-width-focus, 2px))*2);list-style:none;margin:calc(var(--focus-ring-size)*-1);overflow-x:auto;padding:var(--focus-ring-size);scroll-padding:var(--focus-ring-size)}.a4759b4cb2c8bd92__li{flex-shrink:0}._07da506d3f2d9afe__item{align-items:center;color:var(--wpds-color-foreground-interactive-neutral-weak,#707070);display:flex;font-weight:var(--wpds-typography-font-weight-default,400);min-block-size:44px;min-inline-size:44px;text-decoration:none}._07da506d3f2d9afe__item:hover,._07da506d3f2d9afe__item[aria-current=page]{color:var(--wpds-color-foreground-interactive-neutral-weak-active,#1e1e1e)}._07da506d3f2d9afe__item[aria-current=page]{font-weight:var(--wpds-typography-font-weight-emphasis,600)}"); +} +var style_default8 = { "list": "bfb5a2dd8cceebd3__list", "li": "a4759b4cb2c8bd92__li", "item": "_07da506d3f2d9afe__item" }; +var Navigation = ({ + items, + currentHref, + ariaLabel = (0, import_i18n3.__)("Sections"), + linkComponent, + className +}) => { + if (!items.length) { + return null; + } + const LinkComponent = linkComponent ?? "a"; + if (true) { + const invalidItem = items.find( + (item) => typeof item.href !== "string" + ); + if (invalidItem) { + throw new Error( + `Navigation: item "${invalidItem.label}" is missing an \`href\` prop.` + ); + } + const duplicate = items.find( + (item, index2) => items.findIndex((other) => other.href === item.href) !== index2 + ); + if (duplicate) { + throw new Error( + `Navigation: duplicate \`href\` "${duplicate.href}". Each item must have a unique \`href\` so a single item receives \`aria-current="page"\`.` + ); + } + } + return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("nav", { "aria-label": ariaLabel, className, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)( + Stack, + { + render: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("ul", { role: "list" }), + direction: "row", + align: "center", + gap: "md", + className: style_default8.list, + children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("li", { className: style_default8.li, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)( + Text, + { + variant: "body-md", + className: style_default8.item, + render: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)( + Link, + { + variant: "unstyled", + "aria-current": item.href === currentHref ? "page" : void 0, + render: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(LinkComponent, { href: item.href }) + } + ), + children: item.label + } + ) }, item.href)) + } + ) }); +}; +var navigation_default = Navigation; + // packages/admin-ui/build-module/page/sidebar-toggle-slot.mjs var import_components = __toESM(require_components(), 1); var { Fill: SidebarToggleFill, Slot: SidebarToggleSlot } = (0, import_components.createSlotFill)("SidebarToggle"); // packages/admin-ui/build-module/page/header.mjs -var import_jsx_runtime25 = __toESM(require_jsx_runtime(), 1); -var STYLE_HASH_ATTRIBUTE7 = "data-wp-hash"; -function getRuntime7() { +var import_jsx_runtime27 = __toESM(require_jsx_runtime(), 1); +var STYLE_HASH_ATTRIBUTE10 = "data-wp-hash"; +function getRuntime10() { const globalScope = globalThis; if (globalScope.__wpStyleRuntime) { return globalScope.__wpStyleRuntime; @@ -9428,28 +9846,28 @@ function getRuntime7() { injectedStyles: /* @__PURE__ */ new WeakMap() }; if (typeof document !== "undefined") { - registerDocument7(document); + registerDocument10(document); } return globalScope.__wpStyleRuntime; } -function documentContainsStyleHash7(targetDocument, hash) { +function documentContainsStyleHash10(targetDocument, hash) { if (!targetDocument.head) { return false; } for (const style of targetDocument.head.querySelectorAll( - `style[${STYLE_HASH_ATTRIBUTE7}]` + `style[${STYLE_HASH_ATTRIBUTE10}]` )) { - if (style.getAttribute(STYLE_HASH_ATTRIBUTE7) === hash) { + if (style.getAttribute(STYLE_HASH_ATTRIBUTE10) === hash) { return true; } } return false; } -function injectStyle7(targetDocument, hash, css) { +function injectStyle10(targetDocument, hash, css) { if (!targetDocument.head) { return; } - const runtime = getRuntime7(); + const runtime = getRuntime10(); let injectedStyles = runtime.injectedStyles.get(targetDocument); if (!injectedStyles) { injectedStyles = /* @__PURE__ */ new Set(); @@ -9458,24 +9876,24 @@ function injectStyle7(targetDocument, hash, css) { if (injectedStyles.has(hash)) { return; } - if (documentContainsStyleHash7(targetDocument, hash)) { + if (documentContainsStyleHash10(targetDocument, hash)) { injectedStyles.add(hash); return; } const style = targetDocument.createElement("style"); - style.setAttribute(STYLE_HASH_ATTRIBUTE7, hash); + style.setAttribute(STYLE_HASH_ATTRIBUTE10, hash); style.appendChild(targetDocument.createTextNode(css)); targetDocument.head.appendChild(style); injectedStyles.add(hash); } -function registerDocument7(targetDocument) { - const runtime = getRuntime7(); +function registerDocument10(targetDocument) { + const runtime = getRuntime10(); runtime.documents.set( targetDocument, (runtime.documents.get(targetDocument) ?? 0) + 1 ); for (const [hash, css] of runtime.styles) { - injectStyle7(targetDocument, hash, css); + injectStyle10(targetDocument, hash, css); } return () => { const count = runtime.documents.get(targetDocument); @@ -9489,17 +9907,17 @@ function registerDocument7(targetDocument) { runtime.documents.set(targetDocument, count - 1); }; } -function registerStyle7(hash, css) { - const runtime = getRuntime7(); +function registerStyle10(hash, css) { + const runtime = getRuntime10(); runtime.styles.set(hash, css); for (const targetDocument of runtime.documents.keys()) { - injectStyle7(targetDocument, hash, css); + injectStyle10(targetDocument, hash, css); } } if (typeof process === "undefined" || true) { - registerStyle7("ddd9aab364", "._956b6df0898efed0__page{text-wrap:pretty;background-color:var(--wpds-color-background-surface-neutral,#fcfcfc);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);display:flex;flex-flow:column;height:100%;position:relative;z-index:1}._0625b55e82a0d93d__header{background:var(--wpds-color-background-surface-neutral-strong,#fff);border-block-end:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral-weak,#f0f0f0);inset-block-start:0;padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px);position:sticky;z-index:1}.a43c44d5ae28b2e8__header-content{min-height:var(--wpds-dimension-size-md,32px)}.b7cb5b9daf3a3b25__header-actions{flex-shrink:0}._8113be94e7caf73c__header-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._9a776c7f70996f61__header-visual{display:grid;flex-shrink:0;grid-template-columns:1fr;grid-template-rows:1fr;height:var(--wpds-dimension-size-sm,24px);width:var(--wpds-dimension-size-sm,24px);>*{grid-column:1/-1;grid-row:1/-1;max-height:100%;max-width:100%}}.d5e0920cd15d35bc__sidebar-toggle-slot:empty{display:none}._60fea2f6bf5319cd__header-subtitle{color:var(--wpds-color-foreground-content-neutral-weak,#707070);padding-block-end:var(--wpds-dimension-padding-xs,4px)}.be5e57d029ec4036__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;&._128806d0b26e3a50__has-padding{padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px)}}"); + registerStyle10("1f3750277d", "._956b6df0898efed0__page{text-wrap:pretty;background-color:var(--wpds-color-background-surface-neutral,#fcfcfc);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);display:flex;flex-flow:column;height:100%;position:relative;z-index:1}._0625b55e82a0d93d__header{background:var(--wpds-color-background-surface-neutral-strong,#fff);border-block-end:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral-weak,#f0f0f0);inset-block-start:0;padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px);position:sticky;z-index:1}.a43c44d5ae28b2e8__header-content{min-height:var(--wpds-dimension-size-md,32px)}.b7cb5b9daf3a3b25__header-actions{flex-shrink:0}._8bcd33103b451f30__header-lockup{min-width:0}._8113be94e7caf73c__header-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._9a776c7f70996f61__header-visual{display:grid;flex-shrink:0;grid-template-columns:1fr;grid-template-rows:1fr;height:var(--wpds-dimension-size-sm,24px);width:var(--wpds-dimension-size-sm,24px);>*{grid-column:1/-1;grid-row:1/-1;max-height:100%;max-width:100%}}.d5e0920cd15d35bc__sidebar-toggle-slot:empty{display:none}._60fea2f6bf5319cd__header-subtitle{color:var(--wpds-color-foreground-content-neutral-weak,#707070);padding-block-end:var(--wpds-dimension-padding-xs,4px)}._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation,._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation ._60fea2f6bf5319cd__header-subtitle{padding-block-end:0}._673c99dcbfb58211__header-navigation{margin-block-start:var(--wpds-dimension-gap-md,12px)}.be5e57d029ec4036__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;&._128806d0b26e3a50__has-padding{padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px)}}"); } -var style_default6 = { "page": "_956b6df0898efed0__page", "header": "_0625b55e82a0d93d__header", "header-content": "a43c44d5ae28b2e8__header-content", "header-actions": "b7cb5b9daf3a3b25__header-actions", "header-title": "_8113be94e7caf73c__header-title", "header-visual": "_9a776c7f70996f61__header-visual", "sidebar-toggle-slot": "d5e0920cd15d35bc__sidebar-toggle-slot", "header-subtitle": "_60fea2f6bf5319cd__header-subtitle", "content": "be5e57d029ec4036__content", "has-padding": "_128806d0b26e3a50__has-padding" }; +var style_default9 = { "page": "_956b6df0898efed0__page", "header": "_0625b55e82a0d93d__header", "header-content": "a43c44d5ae28b2e8__header-content", "header-actions": "b7cb5b9daf3a3b25__header-actions", "header-lockup": "_8bcd33103b451f30__header-lockup", "header-title": "_8113be94e7caf73c__header-title", "header-visual": "_9a776c7f70996f61__header-visual", "sidebar-toggle-slot": "d5e0920cd15d35bc__sidebar-toggle-slot", "header-subtitle": "_60fea2f6bf5319cd__header-subtitle", "has-navigation": "_4b0f17e503d11619__has-navigation", "header-navigation": "_673c99dcbfb58211__header-navigation", "content": "be5e57d029ec4036__content", "has-padding": "_128806d0b26e3a50__has-padding" }; function Header({ headingLevel = 1, breadcrumbs, @@ -9508,75 +9926,106 @@ function Header({ title, subTitle, actions, + navigation, + components, showSidebarToggle = true }) { const HeadingTag = `h${headingLevel}`; - return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Stack, { direction: "column", className: style_default6.header, children: [ - /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)( - Stack, - { - className: style_default6["header-content"], - direction: "row", - gap: "sm", - justify: "space-between", - children: [ - /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Stack, { direction: "row", gap: "sm", align: "center", justify: "start", children: [ - showSidebarToggle && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)( - SidebarToggleSlot, - { - bubblesVirtually: true, - className: style_default6["sidebar-toggle-slot"] - } - ), - visual && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)( - "div", - { - className: style_default6["header-visual"], - "aria-hidden": "true", - children: visual - } - ), - title && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)( - Text, - { - className: style_default6["header-title"], - render: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(HeadingTag, {}), - variant: "heading-lg", - children: title - } - ), - breadcrumbs, - badges - ] }), - actions && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)( - Stack, - { - align: "center", - className: style_default6["header-actions"], - direction: "row", - gap: "sm", - children: actions - } - ) - ] - } - ), - subTitle && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)( - Text, - { - render: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", {}), - variant: "body-md", - className: style_default6["header-subtitle"], - children: subTitle - } - ) - ] }); + const hasNavigation = !!navigation?.items?.length; + return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)( + Stack, + { + direction: "column", + className: clsx_default( + style_default9.header, + hasNavigation && style_default9["has-navigation"] + ), + children: [ + /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)( + Stack, + { + className: style_default9["header-content"], + direction: "row", + gap: "sm", + justify: "space-between", + children: [ + /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)( + Stack, + { + direction: "row", + gap: "sm", + align: "center", + justify: "start", + className: style_default9["header-lockup"], + children: [ + showSidebarToggle && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)( + SidebarToggleSlot, + { + bubblesVirtually: true, + className: style_default9["sidebar-toggle-slot"] + } + ), + visual && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)( + "div", + { + className: style_default9["header-visual"], + "aria-hidden": "true", + children: visual + } + ), + title && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)( + Text, + { + className: style_default9["header-title"], + render: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(HeadingTag, {}), + variant: "heading-lg", + children: title + } + ), + breadcrumbs, + badges + ] + } + ), + actions && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)( + Stack, + { + align: "center", + className: style_default9["header-actions"], + direction: "row", + gap: "sm", + children: actions + } + ) + ] + } + ), + subTitle && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)( + Text, + { + render: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", {}), + variant: "body-md", + className: style_default9["header-subtitle"], + children: subTitle + } + ), + hasNavigation && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)( + navigation_default, + { + ...navigation, + linkComponent: components?.link, + className: style_default9["header-navigation"] + } + ) + ] + } + ); } // packages/admin-ui/build-module/page/index.mjs -var import_jsx_runtime26 = __toESM(require_jsx_runtime(), 1); -var STYLE_HASH_ATTRIBUTE8 = "data-wp-hash"; -function getRuntime8() { +var import_jsx_runtime28 = __toESM(require_jsx_runtime(), 1); +var STYLE_HASH_ATTRIBUTE11 = "data-wp-hash"; +function getRuntime11() { const globalScope = globalThis; if (globalScope.__wpStyleRuntime) { return globalScope.__wpStyleRuntime; @@ -9587,28 +10036,28 @@ function getRuntime8() { injectedStyles: /* @__PURE__ */ new WeakMap() }; if (typeof document !== "undefined") { - registerDocument8(document); + registerDocument11(document); } return globalScope.__wpStyleRuntime; } -function documentContainsStyleHash8(targetDocument, hash) { +function documentContainsStyleHash11(targetDocument, hash) { if (!targetDocument.head) { return false; } for (const style of targetDocument.head.querySelectorAll( - `style[${STYLE_HASH_ATTRIBUTE8}]` + `style[${STYLE_HASH_ATTRIBUTE11}]` )) { - if (style.getAttribute(STYLE_HASH_ATTRIBUTE8) === hash) { + if (style.getAttribute(STYLE_HASH_ATTRIBUTE11) === hash) { return true; } } return false; } -function injectStyle8(targetDocument, hash, css) { +function injectStyle11(targetDocument, hash, css) { if (!targetDocument.head) { return; } - const runtime = getRuntime8(); + const runtime = getRuntime11(); let injectedStyles = runtime.injectedStyles.get(targetDocument); if (!injectedStyles) { injectedStyles = /* @__PURE__ */ new Set(); @@ -9617,24 +10066,24 @@ function injectStyle8(targetDocument, hash, css) { if (injectedStyles.has(hash)) { return; } - if (documentContainsStyleHash8(targetDocument, hash)) { + if (documentContainsStyleHash11(targetDocument, hash)) { injectedStyles.add(hash); return; } const style = targetDocument.createElement("style"); - style.setAttribute(STYLE_HASH_ATTRIBUTE8, hash); + style.setAttribute(STYLE_HASH_ATTRIBUTE11, hash); style.appendChild(targetDocument.createTextNode(css)); targetDocument.head.appendChild(style); injectedStyles.add(hash); } -function registerDocument8(targetDocument) { - const runtime = getRuntime8(); +function registerDocument11(targetDocument) { + const runtime = getRuntime11(); runtime.documents.set( targetDocument, (runtime.documents.get(targetDocument) ?? 0) + 1 ); for (const [hash, css] of runtime.styles) { - injectStyle8(targetDocument, hash, css); + injectStyle11(targetDocument, hash, css); } return () => { const count = runtime.documents.get(targetDocument); @@ -9648,17 +10097,17 @@ function registerDocument8(targetDocument) { runtime.documents.set(targetDocument, count - 1); }; } -function registerStyle8(hash, css) { - const runtime = getRuntime8(); +function registerStyle11(hash, css) { + const runtime = getRuntime11(); runtime.styles.set(hash, css); for (const targetDocument of runtime.documents.keys()) { - injectStyle8(targetDocument, hash, css); + injectStyle11(targetDocument, hash, css); } } if (typeof process === "undefined" || true) { - registerStyle8("ddd9aab364", "._956b6df0898efed0__page{text-wrap:pretty;background-color:var(--wpds-color-background-surface-neutral,#fcfcfc);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);display:flex;flex-flow:column;height:100%;position:relative;z-index:1}._0625b55e82a0d93d__header{background:var(--wpds-color-background-surface-neutral-strong,#fff);border-block-end:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral-weak,#f0f0f0);inset-block-start:0;padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px);position:sticky;z-index:1}.a43c44d5ae28b2e8__header-content{min-height:var(--wpds-dimension-size-md,32px)}.b7cb5b9daf3a3b25__header-actions{flex-shrink:0}._8113be94e7caf73c__header-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._9a776c7f70996f61__header-visual{display:grid;flex-shrink:0;grid-template-columns:1fr;grid-template-rows:1fr;height:var(--wpds-dimension-size-sm,24px);width:var(--wpds-dimension-size-sm,24px);>*{grid-column:1/-1;grid-row:1/-1;max-height:100%;max-width:100%}}.d5e0920cd15d35bc__sidebar-toggle-slot:empty{display:none}._60fea2f6bf5319cd__header-subtitle{color:var(--wpds-color-foreground-content-neutral-weak,#707070);padding-block-end:var(--wpds-dimension-padding-xs,4px)}.be5e57d029ec4036__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;&._128806d0b26e3a50__has-padding{padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px)}}"); + registerStyle11("1f3750277d", "._956b6df0898efed0__page{text-wrap:pretty;background-color:var(--wpds-color-background-surface-neutral,#fcfcfc);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);display:flex;flex-flow:column;height:100%;position:relative;z-index:1}._0625b55e82a0d93d__header{background:var(--wpds-color-background-surface-neutral-strong,#fff);border-block-end:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral-weak,#f0f0f0);inset-block-start:0;padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px);position:sticky;z-index:1}.a43c44d5ae28b2e8__header-content{min-height:var(--wpds-dimension-size-md,32px)}.b7cb5b9daf3a3b25__header-actions{flex-shrink:0}._8bcd33103b451f30__header-lockup{min-width:0}._8113be94e7caf73c__header-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._9a776c7f70996f61__header-visual{display:grid;flex-shrink:0;grid-template-columns:1fr;grid-template-rows:1fr;height:var(--wpds-dimension-size-sm,24px);width:var(--wpds-dimension-size-sm,24px);>*{grid-column:1/-1;grid-row:1/-1;max-height:100%;max-width:100%}}.d5e0920cd15d35bc__sidebar-toggle-slot:empty{display:none}._60fea2f6bf5319cd__header-subtitle{color:var(--wpds-color-foreground-content-neutral-weak,#707070);padding-block-end:var(--wpds-dimension-padding-xs,4px)}._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation,._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation ._60fea2f6bf5319cd__header-subtitle{padding-block-end:0}._673c99dcbfb58211__header-navigation{margin-block-start:var(--wpds-dimension-gap-md,12px)}.be5e57d029ec4036__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;&._128806d0b26e3a50__has-padding{padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px)}}"); } -var style_default7 = { "page": "_956b6df0898efed0__page", "header": "_0625b55e82a0d93d__header", "header-content": "a43c44d5ae28b2e8__header-content", "header-actions": "b7cb5b9daf3a3b25__header-actions", "header-title": "_8113be94e7caf73c__header-title", "header-visual": "_9a776c7f70996f61__header-visual", "sidebar-toggle-slot": "d5e0920cd15d35bc__sidebar-toggle-slot", "header-subtitle": "_60fea2f6bf5319cd__header-subtitle", "content": "be5e57d029ec4036__content", "has-padding": "_128806d0b26e3a50__has-padding" }; +var style_default10 = { "page": "_956b6df0898efed0__page", "header": "_0625b55e82a0d93d__header", "header-content": "a43c44d5ae28b2e8__header-content", "header-actions": "b7cb5b9daf3a3b25__header-actions", "header-lockup": "_8bcd33103b451f30__header-lockup", "header-title": "_8113be94e7caf73c__header-title", "header-visual": "_9a776c7f70996f61__header-visual", "sidebar-toggle-slot": "d5e0920cd15d35bc__sidebar-toggle-slot", "header-subtitle": "_60fea2f6bf5319cd__header-subtitle", "has-navigation": "_4b0f17e503d11619__has-navigation", "header-navigation": "_673c99dcbfb58211__header-navigation", "content": "be5e57d029ec4036__content", "has-padding": "_128806d0b26e3a50__has-padding" }; function Page({ headingLevel, breadcrumbs, @@ -9669,14 +10118,16 @@ function Page({ children, className, actions, + navigation, + components, ariaLabel, hasPadding = false, showSidebarToggle = true }) { - const classes = clsx_default(style_default7.page, className); + const classes = clsx_default(style_default10.page, className); const effectiveAriaLabel = ariaLabel ?? (typeof title === "string" ? title : ""); - return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(navigable_region_default, { className: classes, ariaLabel: effectiveAriaLabel, children: [ - (title || breadcrumbs || badges || actions || visual) && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)( + return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(navigable_region_default, { className: classes, ariaLabel: effectiveAriaLabel, children: [ + (title || breadcrumbs || badges || actions || visual || !!navigation?.items?.length) && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)( Header, { headingLevel, @@ -9686,15 +10137,17 @@ function Page({ title, subTitle, actions, + navigation, + components, showSidebarToggle } ), - hasPadding ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)( + hasPadding ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)( "div", { className: clsx_default( - style_default7.content, - style_default7["has-padding"] + style_default10.content, + style_default10["has-padding"] ), children } @@ -9705,20 +10158,20 @@ Page.SidebarToggleFill = SidebarToggleFill; var page_default = Page; // routes/font-list/stage.tsx -var import_i18n48 = __toESM(require_i18n()); +var import_i18n51 = __toESM(require_i18n()); var import_components58 = __toESM(require_components()); var import_editor = __toESM(require_editor()); var import_core_data12 = __toESM(require_core_data()); var import_data13 = __toESM(require_data()); -var import_element51 = __toESM(require_element()); +var import_element54 = __toESM(require_element()); // packages/global-styles-ui/build-module/global-styles-ui.mjs var import_components57 = __toESM(require_components(), 1); var import_blocks5 = __toESM(require_blocks(), 1); var import_data12 = __toESM(require_data(), 1); var import_block_editor14 = __toESM(require_block_editor(), 1); -var import_element50 = __toESM(require_element(), 1); -var import_compose6 = __toESM(require_compose(), 1); +var import_element53 = __toESM(require_element(), 1); +var import_compose7 = __toESM(require_compose(), 1); // packages/global-styles-engine/build-module/utils/object.mjs function setImmutably(object, path, value) { @@ -11110,11 +11563,11 @@ lock2(privateApis, { }); // packages/global-styles-ui/build-module/provider.mjs -var import_element21 = __toESM(require_element(), 1); +var import_element23 = __toESM(require_element(), 1); // packages/global-styles-ui/build-module/context.mjs -var import_element20 = __toESM(require_element(), 1); -var GlobalStylesContext = (0, import_element20.createContext)({ +var import_element22 = __toESM(require_element(), 1); +var GlobalStylesContext = (0, import_element22.createContext)({ user: { styles: {}, settings: {} }, base: { styles: {}, settings: {} }, merged: { styles: {}, settings: {} }, @@ -11124,7 +11577,7 @@ var GlobalStylesContext = (0, import_element20.createContext)({ }); // packages/global-styles-ui/build-module/provider.mjs -var import_jsx_runtime27 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime29 = __toESM(require_jsx_runtime(), 1); function GlobalStylesProvider({ children, value, @@ -11132,10 +11585,10 @@ function GlobalStylesProvider({ onChange, fontLibraryEnabled }) { - const merged = (0, import_element21.useMemo)(() => { + const merged = (0, import_element23.useMemo)(() => { return mergeGlobalStyles(baseValue, value); }, [baseValue, value]); - const contextValue = (0, import_element21.useMemo)( + const contextValue = (0, import_element23.useMemo)( () => ({ user: value, base: baseValue, @@ -11145,22 +11598,22 @@ function GlobalStylesProvider({ }), [value, baseValue, merged, onChange, fontLibraryEnabled] ); - return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(GlobalStylesContext.Provider, { value: contextValue, children }); + return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(GlobalStylesContext.Provider, { value: contextValue, children }); } // packages/global-styles-ui/build-module/screen-root.mjs var import_components8 = __toESM(require_components(), 1); -var import_i18n6 = __toESM(require_i18n(), 1); +var import_i18n8 = __toESM(require_i18n(), 1); var import_data2 = __toESM(require_data(), 1); var import_core_data2 = __toESM(require_core_data(), 1); // packages/global-styles-ui/build-module/icon-with-current-color.mjs -var import_jsx_runtime28 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime30 = __toESM(require_jsx_runtime(), 1); function IconWithCurrentColor({ className, ...props }) { - return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)( + return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)( icon_default, { className: clsx_default( @@ -11174,27 +11627,27 @@ function IconWithCurrentColor({ // packages/global-styles-ui/build-module/navigation-button.mjs var import_components2 = __toESM(require_components(), 1); -var import_jsx_runtime29 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime31 = __toESM(require_jsx_runtime(), 1); function GenericNavigationButton({ icon, children, ...props }) { - return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_components2.__experimentalItem, { ...props, children: [ - icon && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_components2.__experimentalHStack, { justify: "flex-start", children: [ - /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(IconWithCurrentColor, { icon, size: 24 }), - /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_components2.FlexItem, { children }) + return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_components2.__experimentalItem, { ...props, children: [ + icon && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_components2.__experimentalHStack, { justify: "flex-start", children: [ + /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(IconWithCurrentColor, { icon, size: 24 }), + /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_components2.FlexItem, { children }) ] }), !icon && children ] }); } function NavigationButtonAsItem(props) { - return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_components2.Navigator.Button, { as: GenericNavigationButton, ...props }); + return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_components2.Navigator.Button, { as: GenericNavigationButton, ...props }); } // packages/global-styles-ui/build-module/root-menu.mjs var import_components3 = __toESM(require_components(), 1); -var import_i18n4 = __toESM(require_i18n(), 1); +var import_i18n6 = __toESM(require_i18n(), 1); var import_block_editor = __toESM(require_block_editor(), 1); // node_modules/colord/plugins/a11y.mjs @@ -11220,13 +11673,13 @@ function a11y_default(o3) { } // packages/global-styles-ui/build-module/hooks.mjs -var import_element22 = __toESM(require_element(), 1); +var import_element24 = __toESM(require_element(), 1); var import_data = __toESM(require_data(), 1); var import_core_data = __toESM(require_core_data(), 1); -var import_i18n3 = __toESM(require_i18n(), 1); +var import_i18n5 = __toESM(require_i18n(), 1); // packages/global-styles-ui/build-module/utils.mjs -var import_i18n2 = __toESM(require_i18n(), 1); +var import_i18n4 = __toESM(require_i18n(), 1); // packages/global-styles-ui/build-module/lock-unlock.mjs var import_private_apis4 = __toESM(require_private_apis(), 1); @@ -11239,35 +11692,35 @@ var { lock: lock3, unlock: unlock3 } = (0, import_private_apis4.__dangerousOptIn var { getViewportBreakpoints: getViewportBreakpoints2 } = unlock3(privateApis); var VALID_ELEMENT_STATES = { link: [ - { value: ":link", label: (0, import_i18n2.__)("Link") }, - { value: ":any-link", label: (0, import_i18n2.__)("Any Link") }, - { value: ":visited", label: (0, import_i18n2.__)("Visited") }, - { value: ":hover", label: (0, import_i18n2.__)("Hover") }, - { value: ":focus", label: (0, import_i18n2.__)("Focus") }, - { value: ":focus-visible", label: (0, import_i18n2.__)("Focus-visible") }, - { value: ":active", label: (0, import_i18n2.__)("Active") } + { value: ":link", label: (0, import_i18n4.__)("Link") }, + { value: ":any-link", label: (0, import_i18n4.__)("Any Link") }, + { value: ":visited", label: (0, import_i18n4.__)("Visited") }, + { value: ":hover", label: (0, import_i18n4.__)("Hover") }, + { value: ":focus", label: (0, import_i18n4.__)("Focus") }, + { value: ":focus-visible", label: (0, import_i18n4.__)("Focus-visible") }, + { value: ":active", label: (0, import_i18n4.__)("Active") } ], button: [ - { value: ":link", label: (0, import_i18n2.__)("Link") }, - { value: ":any-link", label: (0, import_i18n2.__)("Any Link") }, - { value: ":visited", label: (0, import_i18n2.__)("Visited") }, - { value: ":hover", label: (0, import_i18n2.__)("Hover") }, - { value: ":focus", label: (0, import_i18n2.__)("Focus") }, - { value: ":focus-visible", label: (0, import_i18n2.__)("Focus-visible") }, - { value: ":active", label: (0, import_i18n2.__)("Active") } + { value: ":link", label: (0, import_i18n4.__)("Link") }, + { value: ":any-link", label: (0, import_i18n4.__)("Any Link") }, + { value: ":visited", label: (0, import_i18n4.__)("Visited") }, + { value: ":hover", label: (0, import_i18n4.__)("Hover") }, + { value: ":focus", label: (0, import_i18n4.__)("Focus") }, + { value: ":focus-visible", label: (0, import_i18n4.__)("Focus-visible") }, + { value: ":active", label: (0, import_i18n4.__)("Active") } ] }; var VALID_BLOCK_STATES = { "core/button": [ - { value: ":hover", label: (0, import_i18n2.__)("Hover") }, - { value: ":focus", label: (0, import_i18n2.__)("Focus") }, - { value: ":focus-visible", label: (0, import_i18n2.__)("Focus-visible") }, - { value: ":active", label: (0, import_i18n2.__)("Active") } + { value: ":hover", label: (0, import_i18n4.__)("Hover") }, + { value: ":focus", label: (0, import_i18n4.__)("Focus") }, + { value: ":focus-visible", label: (0, import_i18n4.__)("Focus-visible") }, + { value: ":active", label: (0, import_i18n4.__)("Active") } ] }; var RESPONSIVE_STATES = [ - { value: "@tablet", label: (0, import_i18n2.__)("Tablet") }, - { value: "@mobile", label: (0, import_i18n2.__)("Mobile") } + { value: "@tablet", label: (0, import_i18n4.__)("Tablet") }, + { value: "@mobile", label: (0, import_i18n4.__)("Mobile") } ]; function removePropertiesFromObject(object, properties) { if (!properties?.length) { @@ -11354,7 +11807,7 @@ function getFontFamilies(themeJson) { // packages/global-styles-ui/build-module/hooks.mjs k([a11y_default]); function useStyle(path, blockName, readFrom = "merged", shouldDecodeEncode = true, state) { - const { user, base, merged, onChange } = (0, import_element22.useContext)(GlobalStylesContext); + const { user, base, merged, onChange } = (0, import_element24.useContext)(GlobalStylesContext); const statePathParts = state?.split(".").filter(Boolean) ?? []; const pseudoSelectorState = statePathParts.find( (value) => value.startsWith(":") @@ -11367,7 +11820,7 @@ function useStyle(path, blockName, readFrom = "merged", shouldDecodeEncode = tru } else if (readFrom === "user") { sourceValue = user; } - const styleValue = (0, import_element22.useMemo)(() => { + const styleValue = (0, import_element24.useMemo)(() => { const rawValue = getStyle( sourceValue, stylePath, @@ -11385,7 +11838,7 @@ function useStyle(path, blockName, readFrom = "merged", shouldDecodeEncode = tru shouldDecodeEncode, pseudoSelectorState ]); - const setStyleValue = (0, import_element22.useCallback)( + const setStyleValue = (0, import_element24.useCallback)( (newValue) => { let valueToSet = newValue; if (pseudoSelectorState) { @@ -11413,18 +11866,18 @@ function useStyle(path, blockName, readFrom = "merged", shouldDecodeEncode = tru return [styleValue, setStyleValue]; } function useSetting(path, blockName, readFrom = "merged") { - const { user, base, merged, onChange } = (0, import_element22.useContext)(GlobalStylesContext); + const { user, base, merged, onChange } = (0, import_element24.useContext)(GlobalStylesContext); let sourceValue = merged; if (readFrom === "base") { sourceValue = base; } else if (readFrom === "user") { sourceValue = user; } - const settingValue = (0, import_element22.useMemo)( + const settingValue = (0, import_element24.useMemo)( () => getSetting(sourceValue, path, blockName), [sourceValue, path, blockName] ); - const setSettingValue = (0, import_element22.useCallback)( + const setSettingValue = (0, import_element24.useCallback)( (newValue) => { const newGlobalStyles = setSetting( user, @@ -11444,7 +11897,7 @@ function hasThemeVariation({ settings, styles }) { - return title === (0, import_i18n3.__)("Default") || Object.keys(settings || {}).length > 0 || Object.keys(styles || {}).length > 0; + return title === (0, import_i18n5.__)("Default") || Object.keys(settings || {}).length > 0 || Object.keys(styles || {}).length > 0; } function useCurrentMergeThemeStyleVariationsWithUserConfig(properties = []) { const { variationsFromTheme } = (0, import_data.useSelect)((select) => { @@ -11455,14 +11908,14 @@ function useCurrentMergeThemeStyleVariationsWithUserConfig(properties = []) { variationsFromTheme: _variationsFromTheme || EMPTY_ARRAY2 }; }, []); - const { user: userVariation } = (0, import_element22.useContext)(GlobalStylesContext); - return (0, import_element22.useMemo)(() => { + const { user: userVariation } = (0, import_element24.useContext)(GlobalStylesContext); + return (0, import_element24.useMemo)(() => { const clonedUserVariation = structuredClone(userVariation); const userVariationWithoutProperties = removePropertiesFromObject( clonedUserVariation, properties ); - userVariationWithoutProperties.title = (0, import_i18n3.__)("Default"); + userVariationWithoutProperties.title = (0, import_i18n5.__)("Default"); const variationsWithPropertiesAndBase = variationsFromTheme.filter((variation) => { return isVariationWithProperties(variation, properties); }).map((variation) => { @@ -11480,7 +11933,7 @@ function useCurrentMergeThemeStyleVariationsWithUserConfig(properties = []) { } // packages/global-styles-ui/build-module/root-menu.mjs -var import_jsx_runtime30 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime32 = __toESM(require_jsx_runtime(), 1); var { useHasDimensionsPanel, useHasTypographyPanel, @@ -11526,9 +11979,9 @@ function useStylesPreviewColors() { } // packages/global-styles-ui/build-module/typography-example.mjs -var import_element23 = __toESM(require_element(), 1); +var import_element25 = __toESM(require_element(), 1); var import_components4 = __toESM(require_components(), 1); -var import_i18n5 = __toESM(require_i18n(), 1); +var import_i18n7 = __toESM(require_i18n(), 1); // packages/global-styles-ui/build-module/font-library/utils/preview-styles.mjs function findNearest(input, numbers) { @@ -11538,21 +11991,23 @@ function findNearest(input, numbers) { numbers.sort((a2, b2) => Math.abs(input - a2) - Math.abs(input - b2)); return numbers[0]; } -function extractFontWeights(fontFaces) { - const result = []; - fontFaces.forEach((face) => { - const weights = String(face.fontWeight).split(" "); - if (weights.length === 2) { - const start = parseInt(weights[0]); - const end = parseInt(weights[1]); - for (let i2 = start; i2 <= end; i2 += 100) { - result.push(i2); - } - } else if (weights.length === 1) { - result.push(parseInt(weights[0])); - } - }); - return result; +var FONT_WEIGHT_KEYWORDS = { + normal: 400, + bold: 700 +}; +function isValidWeight(weight) { + return weight !== void 0 && Number.isFinite(weight) && weight >= 1 && weight <= 1e3; +} +function resolveFontWeight(fontWeight) { + const weights = String(fontWeight ?? "").trim().toLowerCase().split(/\s+/).filter(Boolean).map((value) => FONT_WEIGHT_KEYWORDS[value] ?? Number(value)); + const [start, end] = weights; + if (!isValidWeight(start)) { + return "400"; + } + if (weights.length !== 2 || !isValidWeight(end)) { + return String(start); + } + return String(Math.min(Math.max(400, start), end)); } function formatFontFamily(input) { const regex = /^(?!generic\([ a-zA-Z\-]+\)$)(?!^[a-zA-Z\-]+$).+/; @@ -11599,12 +12054,15 @@ function getFamilyPreviewStyle(family) { ); if (normalFaces.length > 0) { style.fontStyle = "normal"; - const normalWeights = extractFontWeights(normalFaces); - const nearestWeight = findNearest(400, normalWeights); - style.fontWeight = String(nearestWeight) || "400"; + const normalWeights = normalFaces.map( + (face) => Number(resolveFontWeight(face.fontWeight)) + ); + style.fontWeight = String( + findNearest(400, normalWeights) ?? 400 + ); } else { style.fontStyle = family.fontFace.length && family.fontFace[0].fontStyle || "normal"; - style.fontWeight = family.fontFace.length && String(family.fontFace[0].fontWeight) || "400"; + style.fontWeight = family.fontFace.length && resolveFontWeight(family.fontFace[0].fontWeight) || "400"; } } return style; @@ -11613,17 +12071,17 @@ function getFacePreviewStyle(face) { return { fontFamily: formatFontFamily(face.fontFamily), fontStyle: face.fontStyle || "normal", - fontWeight: face.fontWeight || "400" + fontWeight: resolveFontWeight(face.fontWeight) }; } // packages/global-styles-ui/build-module/typography-example.mjs -var import_jsx_runtime31 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime33 = __toESM(require_jsx_runtime(), 1); function PreviewTypography({ fontSize, variation }) { - const { base } = (0, import_element23.useContext)(GlobalStylesContext); + const { base } = (0, import_element25.useContext)(GlobalStylesContext); let config = base; if (variation) { config = { ...base, ...variation }; @@ -11640,7 +12098,7 @@ function PreviewTypography({ bodyPreviewStyle.fontSize = fontSize; headingPreviewStyle.fontSize = fontSize; } - return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)( + return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)( import_components4.__unstableMotion.div, { animate: { @@ -11660,8 +12118,8 @@ function PreviewTypography({ lineHeight: 1 }, children: [ - /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { style: headingPreviewStyle, children: (0, import_i18n5._x)("A", "Uppercase letter A") }), - /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { style: bodyPreviewStyle, children: (0, import_i18n5._x)("a", "Lowercase letter A") }) + /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { style: headingPreviewStyle, children: (0, import_i18n7._x)("A", "Uppercase letter A") }), + /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { style: bodyPreviewStyle, children: (0, import_i18n7._x)("a", "Lowercase letter A") }) ] } ); @@ -11669,14 +12127,14 @@ function PreviewTypography({ // packages/global-styles-ui/build-module/highlighted-colors.mjs var import_components5 = __toESM(require_components(), 1); -var import_jsx_runtime32 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime34 = __toESM(require_jsx_runtime(), 1); function HighlightedColors({ normalizedColorSwatchSize, ratio }) { const { highlightedColors } = useStylesPreviewColors(); const scaledSwatchSize = normalizedColorSwatchSize * ratio; - return highlightedColors.map(({ slug, color }, index2) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)( + return highlightedColors.map(({ slug, color }, index2) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)( import_components5.__unstableMotion.div, { style: { @@ -11704,8 +12162,8 @@ function HighlightedColors({ // packages/global-styles-ui/build-module/preview-wrapper.mjs var import_components6 = __toESM(require_components(), 1); var import_compose = __toESM(require_compose(), 1); -var import_element24 = __toESM(require_element(), 1); -var import_jsx_runtime33 = __toESM(require_jsx_runtime(), 1); +var import_element26 = __toESM(require_element(), 1); +var import_jsx_runtime35 = __toESM(require_jsx_runtime(), 1); var normalizedWidth = 248; var normalizedHeight = 152; var THROTTLE_OPTIONS = { @@ -11721,21 +12179,21 @@ function PreviewWrapper({ const [backgroundColor = "white"] = useStyle("color.background"); const [gradientValue] = useStyle("color.gradient"); const disableMotion = (0, import_compose.useReducedMotion)(); - const [isHovered, setIsHovered] = (0, import_element24.useState)(false); + const [isHovered, setIsHovered] = (0, import_element26.useState)(false); const [containerResizeListener, { width }] = (0, import_compose.useResizeObserver)(); - const [throttledWidth, setThrottledWidthState] = (0, import_element24.useState)(width); - const [ratioState, setRatioState] = (0, import_element24.useState)(); + const [throttledWidth, setThrottledWidthState] = (0, import_element26.useState)(width); + const [ratioState, setRatioState] = (0, import_element26.useState)(); const setThrottledWidth = (0, import_compose.useThrottle)( setThrottledWidthState, 250, THROTTLE_OPTIONS ); - (0, import_element24.useLayoutEffect)(() => { + (0, import_element26.useLayoutEffect)(() => { if (width) { setThrottledWidth(width); } }, [width, setThrottledWidth]); - (0, import_element24.useLayoutEffect)(() => { + (0, import_element26.useLayoutEffect)(() => { const newRatio = throttledWidth ? throttledWidth / normalizedWidth : 1; const ratioDiff = newRatio - (ratioState || 0); const isRatioDiffBigEnough = Math.abs(ratioDiff) > 0.1; @@ -11746,10 +12204,10 @@ function PreviewWrapper({ const fallbackRatio = width ? width / normalizedWidth : 1; const ratio = ratioState ? ratioState : fallbackRatio; const isReady = !!width; - return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [ - /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { style: { position: "relative" }, children: containerResizeListener }), + return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [ + /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { style: { position: "relative" }, children: containerResizeListener }), !isReady && // Match the preview aspect ratio so layout doesn't jump once width is measured. - /* @__PURE__ */ (0, import_jsx_runtime33.jsx)( + /* @__PURE__ */ (0, import_jsx_runtime35.jsx)( Skeleton, { className: "global-styles-ui-preview__wrapper", @@ -11758,7 +12216,7 @@ function PreviewWrapper({ } } ), - isReady && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)( + isReady && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)( "div", { className: clsx_default("global-styles-ui-preview__wrapper", { @@ -11770,7 +12228,7 @@ function PreviewWrapper({ onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), tabIndex: -1, - children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)( + children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)( import_components6.__unstableMotion.div, { style: { @@ -11792,7 +12250,7 @@ function PreviewWrapper({ var preview_wrapper_default = PreviewWrapper; // packages/global-styles-ui/build-module/preview-styles.mjs -var import_jsx_runtime34 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime36 = __toESM(require_jsx_runtime(), 1); var firstFrameVariants = { start: { scale: 1, @@ -11842,14 +12300,14 @@ function PreviewStyles({ "elements.h1.color.text" ); const { paletteColors } = useStylesPreviewColors(); - return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)( + return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)( preview_wrapper_default, { label, isFocused, withHoverView, children: [ - ({ ratio, key }) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)( + ({ ratio, key }) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)( import_components7.__unstableMotion.div, { variants: firstFrameVariants, @@ -11857,7 +12315,7 @@ function PreviewStyles({ height: "100%", overflow: "hidden" }, - children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)( + children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)( import_components7.__experimentalHStack, { spacing: 10 * ratio, @@ -11867,14 +12325,14 @@ function PreviewStyles({ overflow: "hidden" }, children: [ - /* @__PURE__ */ (0, import_jsx_runtime34.jsx)( + /* @__PURE__ */ (0, import_jsx_runtime36.jsx)( PreviewTypography, { fontSize: 65 * ratio, variation } ), - /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_components7.__experimentalVStack, { spacing: 4 * ratio, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)( + /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_components7.__experimentalVStack, { spacing: 4 * ratio, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)( HighlightedColors, { normalizedColorSwatchSize: 32, @@ -11887,7 +12345,7 @@ function PreviewStyles({ }, key ), - ({ key }) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)( + ({ key }) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)( import_components7.__unstableMotion.div, { variants: withHoverView ? midFrameVariants : void 0, @@ -11900,7 +12358,7 @@ function PreviewStyles({ filter: "blur(60px)", opacity: 0.1 }, - children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)( + children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)( import_components7.__experimentalHStack, { spacing: 0, @@ -11909,7 +12367,7 @@ function PreviewStyles({ height: "100%", overflow: "hidden" }, - children: paletteColors.slice(0, 4).map(({ color }, index2) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)( + children: paletteColors.slice(0, 4).map(({ color }, index2) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)( "div", { style: { @@ -11925,7 +12383,7 @@ function PreviewStyles({ }, key ), - ({ ratio, key }) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)( + ({ ratio, key }) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)( import_components7.__unstableMotion.div, { variants: secondFrameVariants, @@ -11936,7 +12394,7 @@ function PreviewStyles({ position: "absolute", top: 0 }, - children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)( + children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)( import_components7.__experimentalVStack, { spacing: 3 * ratio, @@ -11947,7 +12405,7 @@ function PreviewStyles({ padding: 10 * ratio, boxSizing: "border-box" }, - children: label && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)( + children: label && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)( "div", { style: { @@ -11973,14 +12431,14 @@ function PreviewStyles({ var preview_styles_default = PreviewStyles; // packages/global-styles-ui/build-module/screen-root.mjs -var import_jsx_runtime35 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime37 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/screen-block-list.mjs var import_blocks2 = __toESM(require_blocks(), 1); -var import_i18n8 = __toESM(require_i18n(), 1); +var import_i18n10 = __toESM(require_i18n(), 1); var import_components11 = __toESM(require_components(), 1); var import_data4 = __toESM(require_data(), 1); -var import_element25 = __toESM(require_element(), 1); +var import_element27 = __toESM(require_element(), 1); var import_block_editor3 = __toESM(require_block_editor(), 1); var import_compose2 = __toESM(require_compose(), 1); import { speak } from "@wordpress/a11y"; @@ -11989,7 +12447,7 @@ import { speak } from "@wordpress/a11y"; var import_blocks = __toESM(require_blocks(), 1); var import_data3 = __toESM(require_data(), 1); var import_components9 = __toESM(require_components(), 1); -var import_jsx_runtime36 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime38 = __toESM(require_jsx_runtime(), 1); function getFilteredBlockStyles(blockStyles, variations) { return blockStyles?.filter( (style) => style.source === "block" || variations.includes(style.name) @@ -12010,13 +12468,13 @@ function useBlockVariations(name2) { // packages/global-styles-ui/build-module/screen-header.mjs var import_components10 = __toESM(require_components(), 1); -var import_i18n7 = __toESM(require_i18n(), 1); +var import_i18n9 = __toESM(require_i18n(), 1); var import_block_editor2 = __toESM(require_block_editor(), 1); -var import_jsx_runtime37 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime39 = __toESM(require_jsx_runtime(), 1); var { StateControl, StateControlBadges } = unlock3(import_block_editor2.privateApis); // packages/global-styles-ui/build-module/screen-block-list.mjs -var import_jsx_runtime38 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime40 = __toESM(require_jsx_runtime(), 1); var { useHasDimensionsPanel: useHasDimensionsPanel2, useHasTypographyPanel: useHasTypographyPanel2, @@ -12025,6 +12483,22 @@ var { useHasColorPanel: useHasColorPanel2, useHasBackgroundPanel: useHasBackgroundPanel2 } = unlock3(import_block_editor3.privateApis); +var { Menu } = unlock3(import_components11.privateApis); +function hasAnyValue(value) { + if (value === void 0 || value === null) { + return false; + } + if (Array.isArray(value)) { + return value.length > 0; + } + if (typeof value === "object") { + return Object.values(value).some(hasAnyValue); + } + return true; +} +function hasUserStylesForBlock(user, blockName) { + return hasAnyValue(user?.styles?.blocks?.[blockName]) || hasAnyValue(user?.settings?.blocks?.[blockName]); +} function useSortedBlockTypes() { const blockItems = (0, import_data4.useSelect)( (select) => select(import_blocks2.store).getBlockTypes(), @@ -12055,88 +12529,144 @@ function useBlockHasGlobalStyles(blockName) { const hasGlobalStyles = hasTypographyPanel || hasColorPanel || hasBackgroundPanel || hasLayoutPanel || hasVariationsPanel; return hasGlobalStyles; } -function BlockMenuItem({ block }) { +function BlockMenuItem({ block, isCustomized }) { const hasBlockMenuItem = useBlockHasGlobalStyles(block.name); if (!hasBlockMenuItem) { return null; } - return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)( + return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)( NavigationButtonAsItem, { path: "/blocks/" + encodeURIComponent(block.name), - children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_components11.__experimentalHStack, { justify: "flex-start", children: [ - /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_block_editor3.BlockIcon, { icon: block.icon }), - /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_components11.FlexItem, { children: block.title }) + children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_components11.__experimentalHStack, { justify: "flex-start", spacing: 2, children: [ + /* @__PURE__ */ (0, import_jsx_runtime40.jsx)( + import_block_editor3.BlockIcon, + { + className: "global-styles-ui-block-types-item__icon", + icon: block.icon + } + ), + /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_components11.FlexItem, { children: block.title }), + isCustomized && /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_jsx_runtime40.Fragment, { children: [ + /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(VisuallyHidden, { children: (0, import_i18n10.__)("Has custom styles") }), + /* @__PURE__ */ (0, import_jsx_runtime40.jsx)( + "span", + { + "aria-hidden": "true", + className: "global-styles-ui-block-types-item__indicator" + } + ) + ] }) ] }) } ); } -function BlockList({ filterValue }) { +function EmptyBlockList({ + filterValue, + styleFilter +}) { + const label = "customized" === styleFilter && !filterValue ? (0, import_i18n10.__)("You haven't customized any blocks yet.") : (0, import_i18n10.__)("No blocks found."); + return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)( + import_components11.__experimentalText, + { + align: "center", + as: "p", + className: "global-styles-ui-block-types-item-list__no-results", + children: label + } + ); +} +function BlockList({ filterValue, styleFilter }) { const sortedBlockTypes = useSortedBlockTypes(); const debouncedSpeak = (0, import_compose2.useDebounce)(speak, 500); const { isMatchingSearchTerm } = (0, import_data4.useSelect)(import_blocks2.store); - const filteredBlockTypes = !filterValue ? sortedBlockTypes : sortedBlockTypes.filter( + const { user } = (0, import_element27.useContext)(GlobalStylesContext); + const customizedBlockNames = (0, import_element27.useMemo)(() => { + const names = /* @__PURE__ */ new Set(); + const blockNames = [ + ...Object.keys(user?.styles?.blocks ?? {}), + ...Object.keys(user?.settings?.blocks ?? {}) + ]; + blockNames.forEach((blockName) => { + if (hasUserStylesForBlock(user, blockName)) { + names.add(blockName); + } + }); + return names; + }, [user]); + const searchedBlockTypes = !filterValue ? sortedBlockTypes : sortedBlockTypes.filter( (blockType) => isMatchingSearchTerm(blockType, filterValue) ); - const blockTypesListRef = (0, import_element25.useRef)(null); - (0, import_element25.useEffect)(() => { - if (!filterValue) { + const filteredBlockTypes = styleFilter === "customized" ? searchedBlockTypes.filter( + (blockType) => customizedBlockNames.has(blockType.name) + ) : searchedBlockTypes; + const blockTypesListRef = (0, import_element27.useRef)(null); + const hasResults = filteredBlockTypes.length > 0; + (0, import_element27.useEffect)(() => { + if (!filterValue && styleFilter === "all") { return; } - const count = blockTypesListRef.current?.childElementCount || 0; - const resultsFoundMessage = (0, import_i18n8.sprintf)( + const count = hasResults ? blockTypesListRef.current?.childElementCount || 0 : 0; + const resultsFoundMessage = (0, import_i18n10.sprintf)( /* translators: %d: number of results. */ - (0, import_i18n8._n)("%d result found.", "%d results found.", count), + (0, import_i18n10._n)("%d result found.", "%d results found.", count), count ); debouncedSpeak(resultsFoundMessage, "polite"); - }, [filterValue, debouncedSpeak]); - return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)( + }, [filterValue, styleFilter, hasResults, debouncedSpeak]); + return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)( "div", { ref: blockTypesListRef, className: "global-styles-ui-block-types-item-list", role: "list", - children: filteredBlockTypes.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_components11.__experimentalText, { align: "center", as: "p", children: (0, import_i18n8.__)("No blocks found.") }) : filteredBlockTypes.map((block) => /* @__PURE__ */ (0, import_jsx_runtime38.jsx)( + children: filteredBlockTypes.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)( + EmptyBlockList, + { + filterValue, + styleFilter + } + ) : filteredBlockTypes.map((block) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)( BlockMenuItem, { - block + block, + isCustomized: customizedBlockNames.has(block.name) }, "menu-itemblock-" + block.name )) } ); } -var MemoizedBlockList = (0, import_element25.memo)(BlockList); +var MemoizedBlockList = (0, import_element27.memo)(BlockList); // packages/global-styles-ui/build-module/screen-block.mjs var import_blocks4 = __toESM(require_blocks(), 1); var import_block_editor5 = __toESM(require_block_editor(), 1); -var import_element27 = __toESM(require_element(), 1); +var import_element29 = __toESM(require_element(), 1); var import_data5 = __toESM(require_data(), 1); var import_core_data3 = __toESM(require_core_data(), 1); var import_components14 = __toESM(require_components(), 1); -var import_i18n9 = __toESM(require_i18n(), 1); +var import_i18n11 = __toESM(require_i18n(), 1); // packages/global-styles-ui/build-module/block-preview-panel.mjs var import_block_editor4 = __toESM(require_block_editor(), 1); var import_blocks3 = __toESM(require_blocks(), 1); var import_components12 = __toESM(require_components(), 1); -var import_element26 = __toESM(require_element(), 1); -var import_jsx_runtime39 = __toESM(require_jsx_runtime(), 1); +var import_element28 = __toESM(require_element(), 1); +var import_jsx_runtime41 = __toESM(require_jsx_runtime(), 1); var { getViewportBreakpoints: getViewportBreakpoints3, getViewportBreakpointValueInPixels: getViewportBreakpointValueInPixels2 } = unlock3( privateApis ); // packages/global-styles-ui/build-module/subtitle.mjs var import_components13 = __toESM(require_components(), 1); -var import_jsx_runtime40 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime42 = __toESM(require_jsx_runtime(), 1); function Subtitle({ children, level = 2 }) { - return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_components13.__experimentalHeading, { className: "global-styles-ui-subtitle", level, children }); + return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_components13.__experimentalHeading, { className: "global-styles-ui-subtitle", level, children }); } // packages/global-styles-ui/build-module/screen-block.mjs -var import_jsx_runtime41 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime43 = __toESM(require_jsx_runtime(), 1); var { useHasDimensionsPanel: useHasDimensionsPanel3, useHasTypographyPanel: useHasTypographyPanel3, @@ -12157,37 +12687,37 @@ var { } = unlock3(import_block_editor5.privateApis); // packages/global-styles-ui/build-module/screen-typography.mjs -var import_i18n23 = __toESM(require_i18n(), 1); -var import_components31 = __toESM(require_components(), 1); -var import_element39 = __toESM(require_element(), 1); +var import_i18n25 = __toESM(require_i18n(), 1); +var import_components30 = __toESM(require_components(), 1); +var import_element41 = __toESM(require_element(), 1); // packages/global-styles-ui/build-module/screen-body.mjs var import_components15 = __toESM(require_components(), 1); -var import_jsx_runtime42 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime44 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/typography-elements.mjs -var import_i18n10 = __toESM(require_i18n(), 1); +var import_i18n12 = __toESM(require_i18n(), 1); var import_components16 = __toESM(require_components(), 1); -var import_jsx_runtime43 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime45 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/variations/variations-typography.mjs var import_components18 = __toESM(require_components(), 1); // packages/global-styles-ui/build-module/preview-typography.mjs var import_components17 = __toESM(require_components(), 1); -var import_jsx_runtime44 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime46 = __toESM(require_jsx_runtime(), 1); var StylesPreviewTypography = ({ variation, isFocused, withHoverView }) => { - return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)( + return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)( preview_wrapper_default, { label: variation.title, isFocused, withHoverView, - children: ({ ratio, key }) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)( + children: ({ ratio, key }) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)( import_components17.__experimentalHStack, { spacing: 10 * ratio, @@ -12196,7 +12726,7 @@ var StylesPreviewTypography = ({ height: "100%", overflow: "hidden" }, - children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)( + children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)( PreviewTypography, { variation, @@ -12212,10 +12742,10 @@ var StylesPreviewTypography = ({ var preview_typography_default = StylesPreviewTypography; // packages/global-styles-ui/build-module/variations/variation.mjs -var import_element28 = __toESM(require_element(), 1); +var import_element30 = __toESM(require_element(), 1); var import_keycodes = __toESM(require_keycodes(), 1); -var import_i18n11 = __toESM(require_i18n(), 1); -var import_jsx_runtime45 = __toESM(require_jsx_runtime(), 1); +var import_i18n13 = __toESM(require_i18n(), 1); +var import_jsx_runtime47 = __toESM(require_jsx_runtime(), 1); function Variation({ variation, children, @@ -12223,13 +12753,13 @@ function Variation({ properties, showTooltip = false }) { - const [isFocused, setIsFocused] = (0, import_element28.useState)(false); + const [isFocused, setIsFocused] = (0, import_element30.useState)(false); const { base, user, onChange: setUserConfig - } = (0, import_element28.useContext)(GlobalStylesContext); - const context = (0, import_element28.useMemo)(() => { + } = (0, import_element30.useContext)(GlobalStylesContext); + const context = (0, import_element30.useMemo)(() => { let merged = mergeGlobalStyles(base, variation); if (properties) { merged = filterObjectByProperties(merged, properties); @@ -12249,20 +12779,20 @@ function Variation({ selectVariation(); } }; - const isActive = (0, import_element28.useMemo)( + const isActive = (0, import_element30.useMemo)( () => areGlobalStylesEqual(user, variation), [user, variation] ); let label = variation?.title; if (variation?.description) { - label = (0, import_i18n11.sprintf)( + label = (0, import_i18n13.sprintf)( /* translators: 1: variation title. 2: variation description. */ - (0, import_i18n11._x)("%1$s (%2$s)", "variation label"), + (0, import_i18n13._x)("%1$s (%2$s)", "variation label"), variation?.title, variation?.description ); } - const content = /* @__PURE__ */ (0, import_jsx_runtime45.jsx)( + const content = /* @__PURE__ */ (0, import_jsx_runtime47.jsx)( "div", { className: clsx_default("global-styles-ui-variations_item", { @@ -12276,7 +12806,7 @@ function Variation({ "aria-current": isActive, onFocus: () => setIsFocused(true), onBlur: () => setIsFocused(false), - children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)( + children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)( "div", { className: clsx_default("global-styles-ui-variations_item-preview", { @@ -12287,14 +12817,14 @@ function Variation({ ) } ); - return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(GlobalStylesContext.Provider, { value: context, children: showTooltip ? /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(tooltip_exports.Root, { children: [ - /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(tooltip_exports.Trigger, { render: content }), - /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(tooltip_exports.Popup, { children: variation?.title }) + return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(GlobalStylesContext.Provider, { value: context, children: showTooltip ? /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(tooltip_exports.Root, { children: [ + /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(tooltip_exports.Trigger, { render: content }), + /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(tooltip_exports.Popup, { children: variation?.title }) ] }) : content }); } // packages/global-styles-ui/build-module/variations/variations-typography.mjs -var import_jsx_runtime46 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime48 = __toESM(require_jsx_runtime(), 1); var propertiesToFilter = ["typography"]; function TypographyVariations({ title, @@ -12304,9 +12834,9 @@ function TypographyVariations({ if (typographyVariations?.length <= 1) { return null; } - return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_components18.__experimentalVStack, { spacing: 3, children: [ - title && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Subtitle, { level: 3, children: title }), - /* @__PURE__ */ (0, import_jsx_runtime46.jsx)( + return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_components18.__experimentalVStack, { spacing: 3, children: [ + title && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Subtitle, { level: 3, children: title }), + /* @__PURE__ */ (0, import_jsx_runtime48.jsx)( import_components18.__experimentalGrid, { columns: 3, @@ -12314,13 +12844,13 @@ function TypographyVariations({ className: "global-styles-ui-style-variations-container", children: typographyVariations.map( (variation, index2) => { - return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)( + return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)( Variation, { variation, properties: propertiesToFilter, showTooltip: true, - children: () => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)( + children: () => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)( preview_typography_default, { variation @@ -12337,15 +12867,15 @@ function TypographyVariations({ } // packages/global-styles-ui/build-module/font-families.mjs -var import_i18n21 = __toESM(require_i18n(), 1); -var import_components29 = __toESM(require_components(), 1); -var import_element38 = __toESM(require_element(), 1); +var import_i18n23 = __toESM(require_i18n(), 1); +var import_components28 = __toESM(require_components(), 1); +var import_element40 = __toESM(require_element(), 1); // packages/global-styles-ui/build-module/font-library/context.mjs -var import_element29 = __toESM(require_element(), 1); +var import_element31 = __toESM(require_element(), 1); var import_data6 = __toESM(require_data(), 1); var import_core_data5 = __toESM(require_core_data(), 1); -var import_i18n13 = __toESM(require_i18n(), 1); +var import_i18n15 = __toESM(require_i18n(), 1); // packages/global-styles-ui/build-module/font-library/api.mjs var import_api_fetch = __toESM(require_api_fetch(), 1); @@ -12467,22 +12997,22 @@ function kebabCase(str) { } // packages/global-styles-ui/build-module/font-library/utils/constants.mjs -var import_i18n12 = __toESM(require_i18n(), 1); +var import_i18n14 = __toESM(require_i18n(), 1); var ALLOWED_FILE_EXTENSIONS = ["otf", "ttf", "woff", "woff2"]; var FONT_WEIGHTS = { - 100: (0, import_i18n12._x)("Thin", "font weight"), - 200: (0, import_i18n12._x)("Extra-light", "font weight"), - 300: (0, import_i18n12._x)("Light", "font weight"), - 400: (0, import_i18n12._x)("Normal", "font weight"), - 500: (0, import_i18n12._x)("Medium", "font weight"), - 600: (0, import_i18n12._x)("Semi-bold", "font weight"), - 700: (0, import_i18n12._x)("Bold", "font weight"), - 800: (0, import_i18n12._x)("Extra-bold", "font weight"), - 900: (0, import_i18n12._x)("Black", "font weight") + 100: (0, import_i18n14._x)("Thin", "font weight"), + 200: (0, import_i18n14._x)("Extra-light", "font weight"), + 300: (0, import_i18n14._x)("Light", "font weight"), + 400: (0, import_i18n14._x)("Normal", "font weight"), + 500: (0, import_i18n14._x)("Medium", "font weight"), + 600: (0, import_i18n14._x)("Semi-bold", "font weight"), + 700: (0, import_i18n14._x)("Bold", "font weight"), + 800: (0, import_i18n14._x)("Extra-bold", "font weight"), + 900: (0, import_i18n14._x)("Black", "font weight") }; var FONT_STYLES = { - normal: (0, import_i18n12._x)("Normal", "font style"), - italic: (0, import_i18n12._x)("Italic", "font style") + normal: (0, import_i18n14._x)("Normal", "font style"), + italic: (0, import_i18n14._x)("Italic", "font style") }; // packages/global-styles-ui/build-module/font-library/utils/index.mjs @@ -12760,8 +13290,8 @@ function toggleFont(font2, face, initialfonts = []) { } // packages/global-styles-ui/build-module/font-library/context.mjs -var import_jsx_runtime47 = __toESM(require_jsx_runtime(), 1); -var FontLibraryContext = (0, import_element29.createContext)( +var import_jsx_runtime49 = __toESM(require_jsx_runtime(), 1); +var FontLibraryContext = (0, import_element31.createContext)( {} ); FontLibraryContext.displayName = "FontLibraryContext"; @@ -12777,7 +13307,7 @@ function FontLibraryProvider({ children }) { "globalStyles", globalStylesId ); - const [isInstalling, setIsInstalling] = (0, import_element29.useState)(false); + const [isInstalling, setIsInstalling] = (0, import_element31.useState)(false); const { records: libraryPosts = [], isResolving: isResolvingLibrary } = (0, import_core_data5.useEntityRecords)( "postType", "wp_font_family", @@ -12807,12 +13337,12 @@ function FontLibraryProvider({ children }) { ); await saveEntityRecord("root", "globalStyles", finalGlobalStyles); }; - const [modalTabOpen, setModalTabOpen] = (0, import_element29.useState)(""); - const [libraryFontSelected, setLibraryFontSelected] = (0, import_element29.useState)(void 0); + const [modalTabOpen, setModalTabOpen] = (0, import_element31.useState)(""); + const [libraryFontSelected, setLibraryFontSelected] = (0, import_element31.useState)(void 0); const themeFonts = fontFamilies?.theme ? fontFamilies.theme.map((f2) => setUIValuesNeeded(f2, { source: "theme" })).sort((a2, b2) => a2.name.localeCompare(b2.name)) : []; const customFonts = fontFamilies?.custom ? fontFamilies.custom.map((f2) => setUIValuesNeeded(f2, { source: "custom" })).sort((a2, b2) => a2.name.localeCompare(b2.name)) : []; const baseCustomFonts = libraryFonts ? libraryFonts.map((f2) => setUIValuesNeeded(f2, { source: "custom" })).sort((a2, b2) => a2.name.localeCompare(b2.name)) : []; - (0, import_element29.useEffect)(() => { + (0, import_element31.useEffect)(() => { if (!modalTabOpen) { setLibraryFontSelected(void 0); } @@ -12829,7 +13359,7 @@ function FontLibraryProvider({ children }) { source: font2.source }); }; - const [loadedFontUrls] = (0, import_element29.useState)(/* @__PURE__ */ new Set()); + const [loadedFontUrls] = (0, import_element31.useState)(/* @__PURE__ */ new Set()); const getAvailableFontsOutline = (availableFontFamilies) => { const outline = availableFontFamilies.reduce( (acc, font2) => { @@ -12957,7 +13487,7 @@ function FontLibraryProvider({ children }) { await saveFontFamilies(activeFonts); } if (installationErrorMessages.length > 0) { - const installError = new Error((0, import_i18n13.__)("There was an error installing fonts.")); + const installError = new Error((0, import_i18n15.__)("There was an error installing fonts.")); installError.installationErrors = installationErrorMessages; throw installError; } @@ -12967,7 +13497,7 @@ function FontLibraryProvider({ children }) { } async function uninstallFontFamily(fontFamilyToUninstall) { if (!fontFamilyToUninstall?.id) { - throw new Error((0, import_i18n13.__)("Font family to uninstall is not defined.")); + throw new Error((0, import_i18n15.__)("Font family to uninstall is not defined.")); } try { await deleteEntityRecord( @@ -13072,7 +13602,7 @@ function FontLibraryProvider({ children }) { loadFontFaceInBrowser(fontFace, src, "document"); loadedFontUrls.add(src); }; - return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)( + return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)( FontLibraryContext.Provider, { value: { @@ -13100,27 +13630,27 @@ function FontLibraryProvider({ children }) { var context_default = FontLibraryProvider; // packages/global-styles-ui/build-module/font-library/modal.mjs -var import_i18n19 = __toESM(require_i18n(), 1); -var import_components27 = __toESM(require_components(), 1); +var import_i18n21 = __toESM(require_i18n(), 1); +var import_components26 = __toESM(require_components(), 1); var import_core_data8 = __toESM(require_core_data(), 1); var import_data8 = __toESM(require_data(), 1); // packages/global-styles-ui/build-module/font-library/installed-fonts.mjs -var import_components22 = __toESM(require_components(), 1); +var import_components21 = __toESM(require_components(), 1); var import_core_data6 = __toESM(require_core_data(), 1); var import_data7 = __toESM(require_data(), 1); -var import_element33 = __toESM(require_element(), 1); -var import_i18n15 = __toESM(require_i18n(), 1); +var import_element35 = __toESM(require_element(), 1); +var import_i18n17 = __toESM(require_i18n(), 1); // packages/global-styles-ui/build-module/font-library/font-card.mjs -var import_i18n14 = __toESM(require_i18n(), 1); -var import_element31 = __toESM(require_element(), 1); -var import_components20 = __toESM(require_components(), 1); +var import_i18n16 = __toESM(require_i18n(), 1); +var import_element33 = __toESM(require_element(), 1); +var import_components19 = __toESM(require_components(), 1); // packages/global-styles-ui/build-module/font-library/font-demo.mjs -var import_components19 = __toESM(require_components(), 1); -var import_element30 = __toESM(require_element(), 1); -var import_jsx_runtime48 = __toESM(require_jsx_runtime(), 1); +var import_element32 = __toESM(require_element(), 1); +var import_jsx_runtime50 = __toESM(require_jsx_runtime(), 1); +var loadedPreviews = /* @__PURE__ */ new Set(); function getPreviewUrl(fontFace) { if (fontFace.preview) { return fontFace.preview; @@ -13146,16 +13676,24 @@ function getDisplayFontFace(font2) { }; } function FontDemo({ font: font2, text }) { - const ref = (0, import_element30.useRef)(null); + const ref = (0, import_element32.useRef)(null); const fontFace = getDisplayFontFace(font2); const style = getFamilyPreviewStyle(font2); text = text || ("name" in font2 ? font2.name : ""); const customPreviewUrl = font2.preview; - const [isIntersecting, setIsIntersecting] = (0, import_element30.useState)(false); - const [isAssetLoaded, setIsAssetLoaded] = (0, import_element30.useState)(false); - const { loadFontFaceAsset } = (0, import_element30.useContext)(FontLibraryContext); const previewUrl = customPreviewUrl ?? getPreviewUrl(fontFace); - const isPreviewImage = previewUrl && previewUrl.match(/\.(png|jpg|jpeg|gif|svg)$/i); + const isPreviewImage = Boolean( + previewUrl && /\.(png|jpg|jpeg|gif|svg)$/i.test(previewUrl) + ); + const [isIntersecting, setIsIntersecting] = (0, import_element32.useState)(false); + const [isFontLoaded, setIsFontLoaded] = (0, import_element32.useState)(false); + const [resolvedUrl, setResolvedUrl] = (0, import_element32.useState)(); + const { loadFontFaceAsset } = (0, import_element32.useContext)(FontLibraryContext); + const isAssetLoaded = isPreviewImage ? !!previewUrl && (loadedPreviews.has(previewUrl) || resolvedUrl === previewUrl) : isFontLoaded; + const estimatedImageWidth = Math.min( + Math.max(text.length * 12, 48), + 300 + ); const faceStyles = getFacePreviewStyle(fontFace); const textDemoStyle = { fontSize: "18px", @@ -13164,7 +13702,10 @@ function FontDemo({ font: font2, text }) { ...style, ...faceStyles }; - (0, import_element30.useEffect)(() => { + (0, import_element32.useEffect)(() => { + if (isPreviewImage) { + return; + } const observer = new window.IntersectionObserver(([entry]) => { setIsIntersecting(entry.isIntersecting); }, {}); @@ -13172,28 +13713,47 @@ function FontDemo({ font: font2, text }) { observer.observe(ref.current); } return () => observer.disconnect(); - }, [ref]); - (0, import_element30.useEffect)(() => { + }, [isPreviewImage]); + (0, import_element32.useEffect)(() => { const loadAsset = async () => { - if (isIntersecting) { - if (!isPreviewImage && fontFace.src) { + if (isIntersecting && !isPreviewImage) { + if (fontFace.src) { await loadFontFaceAsset(fontFace); } - setIsAssetLoaded(true); + setIsFontLoaded(true); } }; loadAsset(); }, [fontFace, isIntersecting, loadFontFaceAsset, isPreviewImage]); - return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { ref, children: isPreviewImage ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)( - "img", - { - src: previewUrl, - loading: "lazy", - alt: text, - className: "font-library__font-variant_demo-image" - } - ) : /* @__PURE__ */ (0, import_jsx_runtime48.jsx)( - import_components19.__experimentalText, + return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { ref, className: "font-library__font-demo", children: isPreviewImage ? /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_jsx_runtime50.Fragment, { children: [ + !isAssetLoaded && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)( + Skeleton, + { + className: "font-library__font-variant-demo-skeleton", + style: { width: estimatedImageWidth } + } + ), + /* @__PURE__ */ (0, import_jsx_runtime50.jsx)( + "img", + { + src: previewUrl, + loading: "lazy", + alt: text, + onLoad: () => { + if (previewUrl) { + loadedPreviews.add(previewUrl); + } + setResolvedUrl(previewUrl); + }, + onError: () => setResolvedUrl(previewUrl), + className: clsx_default( + "font-library__font-variant_demo-image", + { "is-loading": !isAssetLoaded } + ) + } + ) + ] }) : /* @__PURE__ */ (0, import_jsx_runtime50.jsx)( + "span", { style: textDemoStyle, className: "font-library__font-variant_demo-text", @@ -13204,7 +13764,7 @@ function FontDemo({ font: font2, text }) { var font_demo_default = FontDemo; // packages/global-styles-ui/build-module/font-library/font-card.mjs -var import_jsx_runtime49 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime51 = __toESM(require_jsx_runtime(), 1); function FontCard({ font: font2, onClick, @@ -13216,15 +13776,15 @@ function FontCard({ const style = { cursor: !!onClick ? "pointer" : "default" }; - const navigator2 = (0, import_components20.useNavigator)(); - const ref = (0, import_element31.useRef)(null); - (0, import_element31.useEffect)(() => { + const navigator2 = (0, import_components19.useNavigator)(); + const ref = (0, import_element33.useRef)(null); + (0, import_element33.useEffect)(() => { if (shouldFocus) { ref.current?.focus(); } }, [shouldFocus]); - return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)( - import_components20.Button, + return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)( + import_components19.Button, { ref, __next40pxDefaultSize: true, @@ -13236,19 +13796,19 @@ function FontCard({ }, style, className: "font-library__font-card", - children: /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_components20.Flex, { justify: "space-between", wrap: false, children: [ - /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(font_demo_default, { font: font2 }), - /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_components20.Flex, { justify: "flex-end", children: [ - /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_components20.FlexItem, { children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_components20.__experimentalText, { className: "font-library__font-card__count", children: variantsText || (0, import_i18n14.sprintf)( + children: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_components19.Flex, { justify: "space-between", wrap: false, children: [ + /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(font_demo_default, { font: font2 }), + /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_components19.Flex, { justify: "flex-end", children: [ + /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_components19.FlexItem, { children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_components19.__experimentalText, { className: "font-library__font-card__count", children: variantsText || (0, import_i18n16.sprintf)( /* translators: %d: Number of font variants. */ - (0, import_i18n14._n)( + (0, import_i18n16._n)( "%d variant", "%d variants", variantsCount ), variantsCount ) }) }), - /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_components20.FlexItem, { children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(icon_default, { icon: (0, import_i18n14.isRTL)() ? chevron_left_default : chevron_right_default }) }) + /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_components19.FlexItem, { children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(icon_default, { icon: (0, import_i18n16.isRTL)() ? chevron_left_default : chevron_right_default }) }) ] }) ] }) } @@ -13257,14 +13817,14 @@ function FontCard({ var font_card_default = FontCard; // packages/global-styles-ui/build-module/font-library/library-font-variant.mjs -var import_element32 = __toESM(require_element(), 1); -var import_components21 = __toESM(require_components(), 1); -var import_jsx_runtime50 = __toESM(require_jsx_runtime(), 1); +var import_element34 = __toESM(require_element(), 1); +var import_components20 = __toESM(require_components(), 1); +var import_jsx_runtime52 = __toESM(require_jsx_runtime(), 1); function LibraryFontVariant({ face, font: font2 }) { - const { isFontActivated, toggleActivateFont } = (0, import_element32.useContext)(FontLibraryContext); + const { isFontActivated, toggleActivateFont } = (0, import_element34.useContext)(FontLibraryContext); const isInstalled = (font2?.fontFace?.length ?? 0) > 0 ? isFontActivated( font2.slug, face.fontStyle, @@ -13279,17 +13839,17 @@ function LibraryFontVariant({ toggleActivateFont(font2); }; const displayName = font2.name + " " + getFontFaceVariantName(face); - const checkboxId = (0, import_element32.useId)(); - return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "font-library__font-card", children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_components21.Flex, { justify: "flex-start", align: "center", gap: "1rem", children: [ - /* @__PURE__ */ (0, import_jsx_runtime50.jsx)( - import_components21.CheckboxControl, + const checkboxId = (0, import_element34.useId)(); + return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "font-library__font-card", children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_components20.Flex, { justify: "flex-start", align: "center", gap: "1rem", children: [ + /* @__PURE__ */ (0, import_jsx_runtime52.jsx)( + import_components20.CheckboxControl, { checked: isInstalled, onChange: handleToggleActivation, id: checkboxId } ), - /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("label", { htmlFor: checkboxId, children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)( + /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("label", { htmlFor: checkboxId, children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)( font_demo_default, { font: face, @@ -13335,7 +13895,7 @@ function sortFontFaces(faces) { } // packages/global-styles-ui/build-module/font-library/installed-fonts.mjs -var import_jsx_runtime51 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime53 = __toESM(require_jsx_runtime(), 1); function getFontFamiliesKey(fontFamilies) { if (!fontFamilies) { return ""; @@ -13361,11 +13921,11 @@ function InstalledFonts() { isInstalling, saveFontFamilies, getFontFacesActivated - } = (0, import_element33.useContext)(FontLibraryContext); + } = (0, import_element35.useContext)(FontLibraryContext); const [fontFamilies, setFontFamilies] = useSetting("typography.fontFamilies"); - const [lastSelectedFontSlug, setLastSelectedFontSlug] = (0, import_element33.useState)(void 0); - const [isConfirmDeleteOpen, setIsConfirmDeleteOpen] = (0, import_element33.useState)(false); - const [notice, setNotice] = (0, import_element33.useState)(null); + const [lastSelectedFontSlug, setLastSelectedFontSlug] = (0, import_element35.useState)(void 0); + const [isConfirmDeleteOpen, setIsConfirmDeleteOpen] = (0, import_element35.useState)(false); + const [notice, setNotice] = (0, import_element35.useState)(null); const [baseFontFamilies] = useSetting("typography.fontFamilies", void 0, "base"); const globalStylesId = (0, import_data7.useSelect)((select) => { const { __experimentalGetCurrentGlobalStylesId } = select(import_core_data6.store); @@ -13378,7 +13938,7 @@ function InstalledFonts() { ); const editedFontFamilies = globalStyles?.edits?.settings?.typography?.fontFamilies; const savedFontFamilies = globalStyles?.record?.settings?.typography?.fontFamilies; - const fontFamiliesHasChanges = (0, import_element33.useMemo)(() => { + const fontFamiliesHasChanges = (0, import_element35.useMemo)(() => { if (editedFontFamilies === void 0) { return false; } @@ -13411,14 +13971,14 @@ function InstalledFonts() { await saveFontFamilies(fontFamilies); setNotice({ type: "success", - message: (0, import_i18n15.__)("Font family updated successfully.") + message: (0, import_i18n17.__)("Font family updated successfully.") }); } catch (error) { setNotice({ type: "error", - message: (0, import_i18n15.sprintf)( + message: (0, import_i18n17.sprintf)( /* translators: %s: error message */ - (0, import_i18n15.__)("There was an error updating the font family. %s"), + (0, import_i18n17.__)("There was an error updating the font family. %s"), error.message ) }); @@ -13445,14 +14005,14 @@ function InstalledFonts() { font2.slug, font2.source ).length; - return (0, import_i18n15.sprintf)( + return (0, import_i18n17.sprintf)( /* translators: 1: Active font variants, 2: Total font variants. */ - (0, import_i18n15.__)("%1$d of %2$d active"), + (0, import_i18n17.__)("%1$d of %2$d active"), variantsActive, variantsInstalled ); }; - (0, import_element33.useEffect)(() => { + (0, import_element35.useEffect)(() => { handleSetLibraryFontSelected(libraryFontSelected); }, []); const activeFontsCount = libraryFontSelected ? getFontFacesActivated( @@ -13490,40 +14050,40 @@ function InstalledFonts() { } }; const hasFonts = baseThemeFonts.length > 0 || baseCustomFonts.length > 0; - return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "font-library__tabpanel-layout", children: [ - isResolvingLibrary && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "font-library__loading", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_components22.ProgressBar, {}) }), - !isResolvingLibrary && /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_jsx_runtime51.Fragment, { children: [ - /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)( - import_components22.Navigator, + return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "font-library__tabpanel-layout", children: [ + isResolvingLibrary && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "font-library__loading", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_components21.ProgressBar, {}) }), + !isResolvingLibrary && /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_jsx_runtime53.Fragment, { children: [ + /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)( + import_components21.Navigator, { initialPath: libraryFontSelected ? "/fontFamily" : "/", children: [ - /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_components22.Navigator.Screen, { path: "/", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_components22.__experimentalVStack, { spacing: "8", children: [ - notice && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)( - import_components22.Notice, + /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_components21.Navigator.Screen, { path: "/", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_components21.__experimentalVStack, { spacing: "8", children: [ + notice && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)( + import_components21.Notice, { status: notice.type, onRemove: () => setNotice(null), children: notice.message } ), - !hasFonts && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_components22.__experimentalText, { as: "p", children: (0, import_i18n15.__)("No fonts installed.") }), - baseThemeFonts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_components22.__experimentalVStack, { children: [ - /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("h2", { + !hasFonts && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_components21.__experimentalText, { as: "p", children: (0, import_i18n17.__)("No fonts installed.") }), + baseThemeFonts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_components21.__experimentalVStack, { children: [ + /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("h2", { className: "font-library__fonts-title", /* translators: Heading for a list of fonts provided by the theme. */ - children: (0, import_i18n15._x)("Theme", "font source") + children: (0, import_i18n17._x)("Theme", "font source") }), - /* @__PURE__ */ (0, import_jsx_runtime51.jsx)( + /* @__PURE__ */ (0, import_jsx_runtime53.jsx)( "ul", { role: "list", className: "font-library__fonts-list", - children: baseThemeFonts.map((font2) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)( + children: baseThemeFonts.map((font2) => /* @__PURE__ */ (0, import_jsx_runtime53.jsx)( "li", { className: "font-library__fonts-list-item", - children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)( + children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)( font_card_default, { font: font2, @@ -13546,22 +14106,22 @@ function InstalledFonts() { } ) ] }), - baseCustomFonts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_components22.__experimentalVStack, { children: [ - /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("h2", { + baseCustomFonts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_components21.__experimentalVStack, { children: [ + /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("h2", { className: "font-library__fonts-title", /* translators: Heading for a list of fonts installed by the user. */ - children: (0, import_i18n15._x)("Custom", "font source") + children: (0, import_i18n17._x)("Custom", "font source") }), - /* @__PURE__ */ (0, import_jsx_runtime51.jsx)( + /* @__PURE__ */ (0, import_jsx_runtime53.jsx)( "ul", { role: "list", className: "font-library__fonts-list", - children: baseCustomFonts.map((font2) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)( + children: baseCustomFonts.map((font2) => /* @__PURE__ */ (0, import_jsx_runtime53.jsx)( "li", { className: "font-library__fonts-list-item", - children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)( + children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)( font_card_default, { font: font2, @@ -13585,8 +14145,8 @@ function InstalledFonts() { ) ] }) ] }) }), - /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_components22.Navigator.Screen, { path: "/fontFamily", children: [ - libraryFontSelected && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)( + /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_components21.Navigator.Screen, { path: "/fontFamily", children: [ + libraryFontSelected && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)( ConfirmDeleteDialog, { font: libraryFontSelected, @@ -13597,11 +14157,11 @@ function InstalledFonts() { handleSetLibraryFontSelected } ), - /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_components22.Flex, { justify: "flex-start", children: [ - /* @__PURE__ */ (0, import_jsx_runtime51.jsx)( - import_components22.Navigator.BackButton, + /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_components21.Flex, { justify: "flex-start", children: [ + /* @__PURE__ */ (0, import_jsx_runtime53.jsx)( + import_components21.Navigator.BackButton, { - icon: (0, import_i18n15.isRTL)() ? chevron_right_default : chevron_left_default, + icon: (0, import_i18n17.isRTL)() ? chevron_right_default : chevron_left_default, size: "small", onClick: () => { setLastSelectedFontSlug( @@ -13612,11 +14172,11 @@ function InstalledFonts() { ); setNotice(null); }, - label: (0, import_i18n15.__)("Back") + label: (0, import_i18n17.__)("Back") } ), - /* @__PURE__ */ (0, import_jsx_runtime51.jsx)( - import_components22.__experimentalHeading, + /* @__PURE__ */ (0, import_jsx_runtime53.jsx)( + import_components21.__experimentalHeading, { level: 2, size: 13, @@ -13625,47 +14185,47 @@ function InstalledFonts() { } ) ] }), - notice && /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_jsx_runtime51.Fragment, { children: [ - /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_components22.__experimentalSpacer, { margin: 1 }), - /* @__PURE__ */ (0, import_jsx_runtime51.jsx)( - import_components22.Notice, + notice && /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_jsx_runtime53.Fragment, { children: [ + /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_components21.__experimentalSpacer, { margin: 1 }), + /* @__PURE__ */ (0, import_jsx_runtime53.jsx)( + import_components21.Notice, { status: notice.type, onRemove: () => setNotice(null), children: notice.message } ), - /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_components22.__experimentalSpacer, { margin: 1 }) + /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_components21.__experimentalSpacer, { margin: 1 }) ] }), - /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_components22.__experimentalSpacer, { margin: 4 }), - /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_components22.__experimentalText, { children: (0, import_i18n15.__)( + /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_components21.__experimentalSpacer, { margin: 4 }), + /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_components21.__experimentalText, { children: (0, import_i18n17.__)( "Choose font variants. Keep in mind that too many variants could make your site slower." ) }), - /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_components22.__experimentalSpacer, { margin: 4 }), - /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_components22.__experimentalVStack, { spacing: 0, children: [ - /* @__PURE__ */ (0, import_jsx_runtime51.jsx)( - import_components22.CheckboxControl, + /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_components21.__experimentalSpacer, { margin: 4 }), + /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_components21.__experimentalVStack, { spacing: 0, children: [ + /* @__PURE__ */ (0, import_jsx_runtime53.jsx)( + import_components21.CheckboxControl, { className: "font-library__select-all", - label: (0, import_i18n15.__)("Select all"), + label: (0, import_i18n17.__)("Select all"), checked: isSelectAllChecked, onChange: toggleSelectAll, indeterminate: isIndeterminate } ), - /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_components22.__experimentalSpacer, { margin: 8 }), - /* @__PURE__ */ (0, import_jsx_runtime51.jsx)( + /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_components21.__experimentalSpacer, { margin: 8 }), + /* @__PURE__ */ (0, import_jsx_runtime53.jsx)( "ul", { role: "list", className: "font-library__fonts-list", children: libraryFontSelected && getFontFacesToDisplay( libraryFontSelected - ).map((face, i2) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)( + ).map((face, i2) => /* @__PURE__ */ (0, import_jsx_runtime53.jsx)( "li", { className: "font-library__fonts-list-item", - children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)( + children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)( library_font_variant_default, { font: libraryFontSelected, @@ -13683,27 +14243,27 @@ function InstalledFonts() { ] } ), - /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_components22.__experimentalHStack, { justify: "flex-end", className: "font-library__footer", children: [ - isInstalling && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_components22.ProgressBar, {}), - shouldDisplayDeleteButton && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)( - import_components22.Button, + /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_components21.__experimentalHStack, { justify: "flex-end", className: "font-library__footer", children: [ + isInstalling && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_components21.ProgressBar, {}), + shouldDisplayDeleteButton && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)( + import_components21.Button, { __next40pxDefaultSize: true, isDestructive: true, variant: "tertiary", onClick: handleUninstallClick, - children: (0, import_i18n15.__)("Delete") + children: (0, import_i18n17.__)("Delete") } ), - /* @__PURE__ */ (0, import_jsx_runtime51.jsx)( - import_components22.Button, + /* @__PURE__ */ (0, import_jsx_runtime53.jsx)( + import_components21.Button, { __next40pxDefaultSize: true, variant: "primary", onClick: handleUpdate, disabled: !fontFamiliesHasChanges, accessibleWhenDisabled: true, - children: (0, import_i18n15.__)("Update") + children: (0, import_i18n17.__)("Update") } ) ] }) @@ -13718,7 +14278,7 @@ function ConfirmDeleteDialog({ uninstallFontFamily, handleSetLibraryFontSelected }) { - const navigator2 = (0, import_components22.useNavigator)(); + const navigator2 = (0, import_components21.useNavigator)(); const handleConfirmUninstall = async () => { setNotice(null); setIsOpen(false); @@ -13728,30 +14288,30 @@ function ConfirmDeleteDialog({ handleSetLibraryFontSelected(void 0); setNotice({ type: "success", - message: (0, import_i18n15.__)("Font family uninstalled successfully.") + message: (0, import_i18n17.__)("Font family uninstalled successfully.") }); } catch (error) { setNotice({ type: "error", - message: (0, import_i18n15.__)("There was an error uninstalling the font family.") + error.message + message: (0, import_i18n17.__)("There was an error uninstalling the font family.") + error.message }); } }; const handleCancelUninstall = () => { setIsOpen(false); }; - return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)( - import_components22.__experimentalConfirmDialog, + return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)( + import_components21.__experimentalConfirmDialog, { isOpen, - cancelButtonText: (0, import_i18n15.__)("Cancel"), - confirmButtonText: (0, import_i18n15.__)("Delete"), + cancelButtonText: (0, import_i18n17.__)("Cancel"), + confirmButtonText: (0, import_i18n17.__)("Delete"), onCancel: handleCancelUninstall, onConfirm: handleConfirmUninstall, size: "medium", - children: font2 && (0, import_i18n15.sprintf)( + children: font2 && (0, import_i18n17.sprintf)( /* translators: %s: Name of the font. */ - (0, import_i18n15.__)( + (0, import_i18n17.__)( 'Are you sure you want to delete "%s" font and all its variants and assets?' ), font2.name @@ -13762,10 +14322,10 @@ function ConfirmDeleteDialog({ var installed_fonts_default = InstalledFonts; // packages/global-styles-ui/build-module/font-library/font-collection.mjs -var import_element35 = __toESM(require_element(), 1); -var import_components25 = __toESM(require_components(), 1); +var import_element37 = __toESM(require_element(), 1); +var import_components24 = __toESM(require_components(), 1); var import_compose3 = __toESM(require_compose(), 1); -var import_i18n17 = __toESM(require_i18n(), 1); +var import_i18n19 = __toESM(require_i18n(), 1); var import_core_data7 = __toESM(require_core_data(), 1); // packages/global-styles-ui/build-module/font-library/utils/filter-fonts.mjs @@ -13809,9 +14369,9 @@ function isFontFontFaceInOutline(slug, face, outline) { } // packages/global-styles-ui/build-module/font-library/google-fonts-confirm-dialog.mjs -var import_i18n16 = __toESM(require_i18n(), 1); -var import_components23 = __toESM(require_components(), 1); -var import_jsx_runtime52 = __toESM(require_jsx_runtime(), 1); +var import_i18n18 = __toESM(require_i18n(), 1); +var import_components22 = __toESM(require_components(), 1); +var import_jsx_runtime54 = __toESM(require_jsx_runtime(), 1); function GoogleFontsConfirmDialog() { const handleConfirm = () => { window.localStorage.setItem( @@ -13820,24 +14380,24 @@ function GoogleFontsConfirmDialog() { ); window.dispatchEvent(new Event("storage")); }; - return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "font-library__google-fonts-confirm", children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_components23.Card, { children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_components23.CardBody, { children: [ - /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_components23.__experimentalHeading, { level: 2, children: (0, import_i18n16.__)("Connect to Google Fonts") }), - /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_components23.__experimentalSpacer, { margin: 6 }), - /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_components23.__experimentalText, { as: "p", children: (0, import_i18n16.__)( + return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "font-library__google-fonts-confirm", children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_components22.Card, { children: /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_components22.CardBody, { children: [ + /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_components22.__experimentalHeading, { level: 2, children: (0, import_i18n18.__)("Connect to Google Fonts") }), + /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_components22.__experimentalSpacer, { margin: 6 }), + /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_components22.__experimentalText, { as: "p", children: (0, import_i18n18.__)( "To install fonts from Google you must give permission to connect directly to Google servers. The fonts you install will be downloaded from Google and stored on your site. Your site will then use these locally-hosted fonts." ) }), - /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_components23.__experimentalSpacer, { margin: 3 }), - /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_components23.__experimentalText, { as: "p", children: (0, import_i18n16.__)( + /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_components22.__experimentalSpacer, { margin: 3 }), + /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_components22.__experimentalText, { as: "p", children: (0, import_i18n18.__)( "You can alternatively upload files directly on the Upload tab." ) }), - /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_components23.__experimentalSpacer, { margin: 6 }), - /* @__PURE__ */ (0, import_jsx_runtime52.jsx)( - import_components23.Button, + /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_components22.__experimentalSpacer, { margin: 6 }), + /* @__PURE__ */ (0, import_jsx_runtime54.jsx)( + import_components22.Button, { __next40pxDefaultSize: true, variant: "primary", onClick: handleConfirm, - children: (0, import_i18n16.__)("Allow access to Google Fonts") + children: (0, import_i18n18.__)("Allow access to Google Fonts") } ) ] }) }) }); @@ -13845,9 +14405,9 @@ function GoogleFontsConfirmDialog() { var google_fonts_confirm_dialog_default = GoogleFontsConfirmDialog; // packages/global-styles-ui/build-module/font-library/collection-font-variant.mjs -var import_element34 = __toESM(require_element(), 1); -var import_components24 = __toESM(require_components(), 1); -var import_jsx_runtime53 = __toESM(require_jsx_runtime(), 1); +var import_element36 = __toESM(require_element(), 1); +var import_components23 = __toESM(require_components(), 1); +var import_jsx_runtime55 = __toESM(require_jsx_runtime(), 1); function CollectionFontVariant({ face, font: font2, @@ -13862,17 +14422,17 @@ function CollectionFontVariant({ handleToggleVariant(font2); }; const displayName = font2.name + " " + getFontFaceVariantName(face); - const checkboxId = (0, import_element34.useId)(); - return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "font-library__font-card", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_components24.Flex, { justify: "flex-start", align: "center", gap: "1rem", children: [ - /* @__PURE__ */ (0, import_jsx_runtime53.jsx)( - import_components24.CheckboxControl, + const checkboxId = (0, import_element36.useId)(); + return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "font-library__font-card", children: /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_components23.Flex, { justify: "flex-start", align: "center", gap: "1rem", children: [ + /* @__PURE__ */ (0, import_jsx_runtime55.jsx)( + import_components23.CheckboxControl, { checked: selected, onChange: handleToggleActivation, id: checkboxId } ), - /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("label", { htmlFor: checkboxId, children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)( + /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("label", { htmlFor: checkboxId, children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)( font_demo_default, { font: face, @@ -13885,10 +14445,10 @@ function CollectionFontVariant({ var collection_font_variant_default = CollectionFontVariant; // packages/global-styles-ui/build-module/font-library/font-collection.mjs -var import_jsx_runtime54 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime56 = __toESM(require_jsx_runtime(), 1); var DEFAULT_CATEGORY = { slug: "all", - name: (0, import_i18n17._x)("All", "font categories") + name: (0, import_i18n19._x)("All", "font categories") }; var LOCAL_STORAGE_ITEM = "wp-font-library-google-fonts-permission"; var MIN_WINDOW_HEIGHT = 500; @@ -13897,22 +14457,22 @@ function FontCollection({ slug }) { const getGoogleFontsPermissionFromStorage = () => { return window.localStorage.getItem(LOCAL_STORAGE_ITEM) === "true"; }; - const [selectedFont, setSelectedFont] = (0, import_element35.useState)( + const [selectedFont, setSelectedFont] = (0, import_element37.useState)( null ); - const [lastSelectedFontSlug, setLastSelectedFontSlug] = (0, import_element35.useState)(void 0); - const [notice, setNotice] = (0, import_element35.useState)(null); - const [fontsToInstall, setFontsToInstall] = (0, import_element35.useState)( + const [lastSelectedFontSlug, setLastSelectedFontSlug] = (0, import_element37.useState)(void 0); + const [notice, setNotice] = (0, import_element37.useState)(null); + const [fontsToInstall, setFontsToInstall] = (0, import_element37.useState)( [] ); - const [page, setPage] = (0, import_element35.useState)(1); - const [filters, setFilters] = (0, import_element35.useState)({}); - const [renderConfirmDialog, setRenderConfirmDialog] = (0, import_element35.useState)( + const [page, setPage] = (0, import_element37.useState)(1); + const [filters, setFilters] = (0, import_element37.useState)({}); + const [renderConfirmDialog, setRenderConfirmDialog] = (0, import_element37.useState)( requiresPermission && !getGoogleFontsPermissionFromStorage() ); - const { installFonts, isInstalling } = (0, import_element35.useContext)(FontLibraryContext); + const { installFonts, isInstalling } = (0, import_element37.useContext)(FontLibraryContext); const { record: selectedCollection, isResolving: isLoading } = (0, import_core_data7.useEntityRecord)("root", "fontCollection", slug); - (0, import_element35.useEffect)(() => { + (0, import_element37.useEffect)(() => { const handleStorage = () => { setRenderConfirmDialog( requiresPermission && !getGoogleFontsPermissionFromStorage() @@ -13926,19 +14486,19 @@ function FontCollection({ slug }) { window.localStorage.setItem(LOCAL_STORAGE_ITEM, "false"); window.dispatchEvent(new Event("storage")); }; - (0, import_element35.useEffect)(() => { + (0, import_element37.useEffect)(() => { setSelectedFont(null); }, [slug]); - (0, import_element35.useEffect)(() => { + (0, import_element37.useEffect)(() => { setFontsToInstall([]); }, [selectedFont]); - const collectionFonts = (0, import_element35.useMemo)( + const collectionFonts = (0, import_element37.useMemo)( () => selectedCollection?.font_families ?? [], [selectedCollection] ); const collectionCategories = selectedCollection?.categories ?? []; const categories = [DEFAULT_CATEGORY, ...collectionCategories]; - const fonts = (0, import_element35.useMemo)( + const fonts = (0, import_element37.useMemo)( () => filterFonts(collectionFonts, filters), [collectionFonts, filters] ); @@ -13997,7 +14557,7 @@ function FontCollection({ slug }) { } catch { setNotice({ type: "error", - message: (0, import_i18n17.__)( + message: (0, import_i18n19.__)( "Error installing the fonts, could not be downloaded." ) }); @@ -14007,7 +14567,7 @@ function FontCollection({ slug }) { await installFonts([fontFamily]); setNotice({ type: "success", - message: (0, import_i18n17.__)("Fonts were installed successfully.") + message: (0, import_i18n19.__)("Fonts were installed successfully.") }); } catch (error) { setNotice({ @@ -14033,35 +14593,35 @@ function FontCollection({ slug }) { return sortFontFaces(fontFamily.fontFace); }; if (renderConfirmDialog) { - return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(google_fonts_confirm_dialog_default, {}); + return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(google_fonts_confirm_dialog_default, {}); } const showActions = slug === "google-fonts" && !renderConfirmDialog && !selectedFont; - return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "font-library__tabpanel-layout", children: [ - isLoading && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "font-library__loading", children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_components25.ProgressBar, {}) }), - !isLoading && selectedCollection && /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_jsx_runtime54.Fragment, { children: [ - /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)( - import_components25.Navigator, + return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "font-library__tabpanel-layout", children: [ + isLoading && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "font-library__loading", children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_components24.ProgressBar, {}) }), + !isLoading && selectedCollection && /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_jsx_runtime56.Fragment, { children: [ + /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)( + import_components24.Navigator, { initialPath: "/", className: "font-library__tabpanel-layout", children: [ - /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_components25.Navigator.Screen, { path: "/", children: [ - /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_components25.__experimentalHStack, { justify: "space-between", children: [ - /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_components25.__experimentalVStack, { children: [ - /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_components25.__experimentalHeading, { level: 2, size: 13, children: selectedCollection.name }), - /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_components25.__experimentalText, { children: selectedCollection.description }) + /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_components24.Navigator.Screen, { path: "/", children: [ + /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_components24.__experimentalHStack, { justify: "space-between", children: [ + /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_components24.__experimentalVStack, { children: [ + /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_components24.__experimentalHeading, { level: 2, size: 13, children: selectedCollection.name }), + /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_components24.__experimentalText, { children: selectedCollection.description }) ] }), - showActions && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)( - import_components25.DropdownMenu, + showActions && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)( + import_components24.DropdownMenu, { icon: more_vertical_default, - label: (0, import_i18n17.__)("Actions"), + label: (0, import_i18n19.__)("Actions"), popoverProps: { position: "bottom left" }, controls: [ { - title: (0, import_i18n17.__)( + title: (0, import_i18n19.__)( "Revoke access to Google Fonts" ), onClick: revokeAccess @@ -14070,26 +14630,26 @@ function FontCollection({ slug }) { } ) ] }), - /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_components25.__experimentalSpacer, { margin: 4 }), - /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_components25.__experimentalHStack, { spacing: 4, justify: "space-between", children: [ - /* @__PURE__ */ (0, import_jsx_runtime54.jsx)( - import_components25.SearchControl, + /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_components24.__experimentalSpacer, { margin: 4 }), + /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_components24.__experimentalHStack, { spacing: 4, justify: "space-between", children: [ + /* @__PURE__ */ (0, import_jsx_runtime56.jsx)( + import_components24.SearchControl, { className: "font-library__search", value: filters.search, - placeholder: (0, import_i18n17.__)("Font name\u2026"), - label: (0, import_i18n17.__)("Search"), + placeholder: (0, import_i18n19.__)("Font name\u2026"), + label: (0, import_i18n19.__)("Search"), onChange: debouncedUpdateSearchInput, hideLabelFromVision: false } ), - /* @__PURE__ */ (0, import_jsx_runtime54.jsx)( - import_components25.SelectControl, + /* @__PURE__ */ (0, import_jsx_runtime56.jsx)( + import_components24.SelectControl, { - label: (0, import_i18n17.__)("Category"), + label: (0, import_i18n19.__)("Category"), value: filters.category, onChange: handleCategoryFilter, - children: categories && categories.map((category) => /* @__PURE__ */ (0, import_jsx_runtime54.jsx)( + children: categories && categories.map((category) => /* @__PURE__ */ (0, import_jsx_runtime56.jsx)( "option", { value: category.slug, @@ -14100,20 +14660,20 @@ function FontCollection({ slug }) { } ) ] }), - /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_components25.__experimentalSpacer, { margin: 4 }), - !!selectedCollection?.font_families?.length && !fonts.length && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_components25.__experimentalText, { children: (0, import_i18n17.__)( + /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_components24.__experimentalSpacer, { margin: 4 }), + !!selectedCollection?.font_families?.length && !fonts.length && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_components24.__experimentalText, { children: (0, import_i18n19.__)( "No fonts found. Try with a different search term." ) }), - /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "font-library__fonts-grid__main", children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)( + /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "font-library__fonts-grid__main", children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)( "ul", { role: "list", className: "font-library__fonts-list", - children: items.map((font2) => /* @__PURE__ */ (0, import_jsx_runtime54.jsx)( + children: items.map((font2) => /* @__PURE__ */ (0, import_jsx_runtime56.jsx)( "li", { className: "font-library__fonts-list-item", - children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)( + children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)( font_card_default, { font: font2.font_family_settings, @@ -14132,12 +14692,12 @@ function FontCollection({ slug }) { } ) }) ] }), - /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_components25.Navigator.Screen, { path: "/fontFamily", children: [ - /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_components25.Flex, { justify: "flex-start", children: [ - /* @__PURE__ */ (0, import_jsx_runtime54.jsx)( - import_components25.Navigator.BackButton, + /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_components24.Navigator.Screen, { path: "/fontFamily", children: [ + /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_components24.Flex, { justify: "flex-start", children: [ + /* @__PURE__ */ (0, import_jsx_runtime56.jsx)( + import_components24.Navigator.BackButton, { - icon: (0, import_i18n17.isRTL)() ? chevron_right_default : chevron_left_default, + icon: (0, import_i18n19.isRTL)() ? chevron_right_default : chevron_left_default, size: "small", onClick: () => { setLastSelectedFontSlug( @@ -14146,11 +14706,11 @@ function FontCollection({ slug }) { setSelectedFont(null); setNotice(null); }, - label: (0, import_i18n17.__)("Back") + label: (0, import_i18n19.__)("Back") } ), - /* @__PURE__ */ (0, import_jsx_runtime54.jsx)( - import_components25.__experimentalHeading, + /* @__PURE__ */ (0, import_jsx_runtime56.jsx)( + import_components24.__experimentalHeading, { level: 2, size: 13, @@ -14159,42 +14719,42 @@ function FontCollection({ slug }) { } ) ] }), - notice && /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_jsx_runtime54.Fragment, { children: [ - /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_components25.__experimentalSpacer, { margin: 1 }), - /* @__PURE__ */ (0, import_jsx_runtime54.jsx)( - import_components25.Notice, + notice && /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_jsx_runtime56.Fragment, { children: [ + /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_components24.__experimentalSpacer, { margin: 1 }), + /* @__PURE__ */ (0, import_jsx_runtime56.jsx)( + import_components24.Notice, { status: notice.type, onRemove: () => setNotice(null), children: notice.message } ), - /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_components25.__experimentalSpacer, { margin: 1 }) + /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_components24.__experimentalSpacer, { margin: 1 }) ] }), - /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_components25.__experimentalSpacer, { margin: 4 }), - /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_components25.__experimentalText, { children: (0, import_i18n17.__)("Select font variants to install.") }), - /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_components25.__experimentalSpacer, { margin: 4 }), - /* @__PURE__ */ (0, import_jsx_runtime54.jsx)( - import_components25.CheckboxControl, + /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_components24.__experimentalSpacer, { margin: 4 }), + /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_components24.__experimentalText, { children: (0, import_i18n19.__)("Select font variants to install.") }), + /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_components24.__experimentalSpacer, { margin: 4 }), + /* @__PURE__ */ (0, import_jsx_runtime56.jsx)( + import_components24.CheckboxControl, { className: "font-library__select-all", - label: (0, import_i18n17.__)("Select all"), + label: (0, import_i18n19.__)("Select all"), checked: isSelectAllChecked, onChange: toggleSelectAll, indeterminate: isIndeterminate } ), - /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_components25.__experimentalVStack, { spacing: 0, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)( + /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_components24.__experimentalVStack, { spacing: 0, children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)( "ul", { role: "list", className: "font-library__fonts-list", children: selectedFont && getSortedFontFaces(selectedFont).map( - (face, i2) => /* @__PURE__ */ (0, import_jsx_runtime54.jsx)( + (face, i2) => /* @__PURE__ */ (0, import_jsx_runtime56.jsx)( "li", { className: "font-library__fonts-list-item", - children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)( + children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)( collection_font_variant_default, { font: selectedFont, @@ -14214,18 +14774,18 @@ function FontCollection({ slug }) { ) } ) }), - /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_components25.__experimentalSpacer, { margin: 16 }) + /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_components24.__experimentalSpacer, { margin: 16 }) ] }) ] } ), - selectedFont && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)( - import_components25.Flex, + selectedFont && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)( + import_components24.Flex, { justify: "flex-end", className: "font-library__footer", - children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)( - import_components25.Button, + children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)( + import_components24.Button, { __next40pxDefaultSize: true, variant: "primary", @@ -14233,30 +14793,30 @@ function FontCollection({ slug }) { isBusy: isInstalling, disabled: fontsToInstall.length === 0 || isInstalling, accessibleWhenDisabled: true, - children: (0, import_i18n17.__)("Install") + children: (0, import_i18n19.__)("Install") } ) } ), - !selectedFont && /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)( - import_components25.__experimentalHStack, + !selectedFont && /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)( + import_components24.__experimentalHStack, { expanded: false, className: "font-library__footer", justify: "end", spacing: 6, children: [ - /* @__PURE__ */ (0, import_jsx_runtime54.jsx)( - import_components25.__experimentalHStack, + /* @__PURE__ */ (0, import_jsx_runtime56.jsx)( + import_components24.__experimentalHStack, { justify: "flex-start", expanded: false, spacing: 1, className: "font-library__page-selection", - children: (0, import_element35.createInterpolateElement)( - (0, import_i18n17.sprintf)( + children: (0, import_element37.createInterpolateElement)( + (0, import_i18n19.sprintf)( // translators: 1: Current page number, 2: Total number of pages. - (0, import_i18n17._x)( + (0, import_i18n19._x)( "
Page
%1$s
of %2$d
", "paging" ), @@ -14264,12 +14824,12 @@ function FontCollection({ slug }) { totalPages ), { - div: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { "aria-hidden": true }), + div: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { "aria-hidden": true }), // @ts-expect-error — Tag injected via sprintf argument, not visible in format string. - CurrentPage: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)( - import_components25.SelectControl, + CurrentPage: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)( + import_components24.SelectControl, { - "aria-label": (0, import_i18n17.__)( + "aria-label": (0, import_i18n19.__)( "Current page" ), value: page.toString(), @@ -14292,28 +14852,28 @@ function FontCollection({ slug }) { ) } ), - /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_components25.__experimentalHStack, { expanded: false, spacing: 1, children: [ - /* @__PURE__ */ (0, import_jsx_runtime54.jsx)( - import_components25.Button, + /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_components24.__experimentalHStack, { expanded: false, spacing: 1, children: [ + /* @__PURE__ */ (0, import_jsx_runtime56.jsx)( + import_components24.Button, { onClick: () => setPage(page - 1), disabled: page === 1, accessibleWhenDisabled: true, - label: (0, import_i18n17.__)("Previous page"), - icon: (0, import_i18n17.isRTL)() ? next_default : previous_default, + label: (0, import_i18n19.__)("Previous page"), + icon: (0, import_i18n19.isRTL)() ? next_default : previous_default, showTooltip: true, size: "compact", tooltipPosition: "top" } ), - /* @__PURE__ */ (0, import_jsx_runtime54.jsx)( - import_components25.Button, + /* @__PURE__ */ (0, import_jsx_runtime56.jsx)( + import_components24.Button, { onClick: () => setPage(page + 1), disabled: page === totalPages, accessibleWhenDisabled: true, - label: (0, import_i18n17.__)("Next page"), - icon: (0, import_i18n17.isRTL)() ? previous_default : next_default, + label: (0, import_i18n19.__)("Next page"), + icon: (0, import_i18n19.isRTL)() ? previous_default : next_default, showTooltip: true, size: "compact", tooltipPosition: "top" @@ -14329,9 +14889,9 @@ function FontCollection({ slug }) { var font_collection_default = FontCollection; // packages/global-styles-ui/build-module/font-library/upload-fonts.mjs -var import_i18n18 = __toESM(require_i18n(), 1); -var import_components26 = __toESM(require_components(), 1); -var import_element36 = __toESM(require_element(), 1); +var import_i18n20 = __toESM(require_i18n(), 1); +var import_components25 = __toESM(require_components(), 1); +var import_element38 = __toESM(require_element(), 1); // packages/global-styles-ui/build-module/font-library/lib/unbrotli.mjs var __require2 = /* @__PURE__ */ ((x2) => typeof __require !== "undefined" ? __require : typeof Proxy !== "undefined" ? new Proxy(x2, { @@ -18149,12 +18709,12 @@ var inflate_default = (function() { var STR_APPLY_UIA_OK = true; try { String.fromCharCode.apply(null, [0]); - } catch (__42) { + } catch (__45) { STR_APPLY_OK = false; } try { String.fromCharCode.apply(null, new Uint8Array(1)); - } catch (__42) { + } catch (__45) { STR_APPLY_UIA_OK = false; } var _utf8len = new utils.Buf8(256); @@ -24386,11 +24946,11 @@ function makeFamiliesFromFaces(fontFaces) { } // packages/global-styles-ui/build-module/font-library/upload-fonts.mjs -var import_jsx_runtime55 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime57 = __toESM(require_jsx_runtime(), 1); function UploadFonts() { - const { installFonts } = (0, import_element36.useContext)(FontLibraryContext); - const [isUploading, setIsUploading] = (0, import_element36.useState)(false); - const [notice, setNotice] = (0, import_element36.useState)(null); + const { installFonts } = (0, import_element38.useContext)(FontLibraryContext); + const [isUploading, setIsUploading] = (0, import_element38.useState)(false); + const [notice, setNotice] = (0, import_element38.useState)(null); const handleDropZone = (files) => { handleFilesUpload(files); }; @@ -24426,7 +24986,7 @@ function UploadFonts() { if (allowedFiles.length > 0) { loadFiles(allowedFiles); } else { - const message = hasInvalidFiles ? (0, import_i18n18.__)("Sorry, you are not allowed to upload this file type.") : (0, import_i18n18.__)("No fonts found to install."); + const message = hasInvalidFiles ? (0, import_i18n20.__)("Sorry, you are not allowed to upload this file type.") : (0, import_i18n20.__)("No fonts found to install."); setNotice({ type: "error", message @@ -24496,7 +25056,7 @@ function UploadFonts() { await installFonts(fontFamilies); setNotice({ type: "success", - message: (0, import_i18n18.__)("Fonts were installed successfully.") + message: (0, import_i18n20.__)("Fonts were installed successfully.") }); } catch (error) { const typedError = error; @@ -24508,42 +25068,42 @@ function UploadFonts() { } setIsUploading(false); }; - return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "font-library__tabpanel-layout", children: [ - /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_components26.DropZone, { onFilesDrop: handleDropZone }), - /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_components26.__experimentalVStack, { className: "font-library__local-fonts", justify: "start", children: [ - notice && /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)( - import_components26.Notice, + return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "font-library__tabpanel-layout", children: [ + /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_components25.DropZone, { onFilesDrop: handleDropZone }), + /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(import_components25.__experimentalVStack, { className: "font-library__local-fonts", justify: "start", children: [ + notice && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)( + import_components25.Notice, { status: notice.type, __unstableHTML: true, onRemove: () => setNotice(null), children: [ notice.message, - notice.errors && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("ul", { children: notice.errors.map((error, index2) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("li", { children: error }, index2)) }) + notice.errors && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("ul", { children: notice.errors.map((error, index2) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("li", { children: error }, index2)) }) ] } ), - isUploading && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_components26.FlexItem, { children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "font-library__upload-area", children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_components26.ProgressBar, {}) }) }), - !isUploading && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)( - import_components26.FormFileUpload, + isUploading && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_components25.FlexItem, { children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "font-library__upload-area", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_components25.ProgressBar, {}) }) }), + !isUploading && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)( + import_components25.FormFileUpload, { accept: ALLOWED_FILE_EXTENSIONS.map( (ext) => `.${ext}` ).join(","), multiple: true, onChange: onFilesUpload, - render: ({ openFileDialog }) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)( - import_components26.Button, + render: ({ openFileDialog }) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)( + import_components25.Button, { __next40pxDefaultSize: true, className: "font-library__upload-area", onClick: openFileDialog, - children: (0, import_i18n18.__)("Upload font") + children: (0, import_i18n20.__)("Upload font") } ) } ), - /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_components26.__experimentalText, { className: "font-library__upload-area__text", children: (0, import_i18n18.__)( + /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_components25.__experimentalText, { className: "font-library__upload-area__text", children: (0, import_i18n20.__)( "Uploaded fonts appear in your library and can be used in your theme. Supported formats: .ttf, .otf, .woff, and .woff2." ) }) ] }) @@ -24552,114 +25112,131 @@ function UploadFonts() { var upload_fonts_default = UploadFonts; // packages/global-styles-ui/build-module/font-library/modal.mjs -var import_jsx_runtime56 = __toESM(require_jsx_runtime(), 1); -var { Tabs } = unlock3(import_components27.privateApis); +var import_jsx_runtime58 = __toESM(require_jsx_runtime(), 1); +var { Tabs } = unlock3(import_components26.privateApis); var DEFAULT_TAB = { id: "installed-fonts", - title: (0, import_i18n19._x)("Library", "Font library") + title: (0, import_i18n21._x)("Library", "Font library") }; var UPLOAD_TAB = { id: "upload-fonts", - title: (0, import_i18n19._x)("Upload", "noun") + title: (0, import_i18n21._x)("Upload", "noun") }; // packages/global-styles-ui/build-module/font-family-item.mjs -var import_i18n20 = __toESM(require_i18n(), 1); -var import_components28 = __toESM(require_components(), 1); -var import_element37 = __toESM(require_element(), 1); -var import_jsx_runtime57 = __toESM(require_jsx_runtime(), 1); +var import_i18n22 = __toESM(require_i18n(), 1); +var import_components27 = __toESM(require_components(), 1); +var import_element39 = __toESM(require_element(), 1); +var import_jsx_runtime59 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/font-families.mjs -var import_jsx_runtime58 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime60 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/font-sizes/font-sizes-count.mjs -var import_i18n22 = __toESM(require_i18n(), 1); -var import_components30 = __toESM(require_components(), 1); -var import_jsx_runtime59 = __toESM(require_jsx_runtime(), 1); +var import_i18n24 = __toESM(require_i18n(), 1); +var import_components29 = __toESM(require_components(), 1); +var import_jsx_runtime61 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/screen-typography.mjs -var import_jsx_runtime60 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime62 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/screen-typography-element.mjs -var import_i18n24 = __toESM(require_i18n(), 1); -var import_components32 = __toESM(require_components(), 1); -var import_element40 = __toESM(require_element(), 1); +var import_i18n26 = __toESM(require_i18n(), 1); +var import_components31 = __toESM(require_components(), 1); +var import_element42 = __toESM(require_element(), 1); // packages/global-styles-ui/build-module/typography-panel.mjs var import_block_editor6 = __toESM(require_block_editor(), 1); -var import_jsx_runtime61 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime63 = __toESM(require_jsx_runtime(), 1); var { useSettingsForBlockElement: useSettingsForBlockElement4, TypographyPanel: StylesTypographyPanel2 } = unlock3(import_block_editor6.privateApis); // packages/global-styles-ui/build-module/typography-preview.mjs -var import_jsx_runtime62 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime64 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/screen-typography-element.mjs -var import_jsx_runtime63 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime65 = __toESM(require_jsx_runtime(), 1); var elements = { text: { - description: (0, import_i18n24.__)("Manage the fonts used on the site."), - title: (0, import_i18n24.__)("Text") + description: (0, import_i18n26.__)("Manage the fonts used on the site."), + title: (0, import_i18n26.__)("Text") }, link: { - description: (0, import_i18n24.__)("Manage the fonts and typography used on the links."), - title: (0, import_i18n24.__)("Links") + description: (0, import_i18n26.__)("Manage the fonts and typography used on the links."), + title: (0, import_i18n26.__)("Links") }, heading: { - description: (0, import_i18n24.__)("Manage the fonts and typography used on headings."), - title: (0, import_i18n24.__)("Headings") + description: (0, import_i18n26.__)("Manage the fonts and typography used on headings."), + title: (0, import_i18n26.__)("Headings") }, caption: { - description: (0, import_i18n24.__)("Manage the fonts and typography used on captions."), - title: (0, import_i18n24.__)("Captions") + description: (0, import_i18n26.__)("Manage the fonts and typography used on captions."), + title: (0, import_i18n26.__)("Captions") + }, + cite: { + description: (0, import_i18n26.__)("Manage the fonts and typography used on citations."), + title: (0, import_i18n26.__)("Citations") }, button: { - description: (0, import_i18n24.__)("Manage the fonts and typography used on buttons."), - title: (0, import_i18n24.__)("Buttons") + description: (0, import_i18n26.__)("Manage the fonts and typography used on buttons."), + title: (0, import_i18n26.__)("Buttons") + }, + textInput: { + description: (0, import_i18n26.__)("Manage the fonts and typography used on inputs."), + title: (0, import_i18n26.__)("Inputs") + }, + select: { + description: (0, import_i18n26.__)("Manage the fonts and typography used on selects."), + title: (0, import_i18n26.__)("Selects") } }; // packages/global-styles-ui/build-module/screen-colors.mjs -var import_i18n26 = __toESM(require_i18n(), 1); -var import_components35 = __toESM(require_components(), 1); +var import_i18n28 = __toESM(require_i18n(), 1); +var import_components34 = __toESM(require_components(), 1); var import_block_editor7 = __toESM(require_block_editor(), 1); // packages/global-styles-ui/build-module/palette.mjs -var import_components34 = __toESM(require_components(), 1); -var import_i18n25 = __toESM(require_i18n(), 1); -var import_element41 = __toESM(require_element(), 1); +var import_components33 = __toESM(require_components(), 1); +var import_i18n27 = __toESM(require_i18n(), 1); +var import_element43 = __toESM(require_element(), 1); // packages/global-styles-ui/build-module/color-indicator-wrapper.mjs -var import_components33 = __toESM(require_components(), 1); -var import_jsx_runtime64 = __toESM(require_jsx_runtime(), 1); +var import_components32 = __toESM(require_components(), 1); +var import_jsx_runtime66 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/palette.mjs -var import_jsx_runtime65 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime67 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/screen-colors.mjs -var import_jsx_runtime66 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime68 = __toESM(require_jsx_runtime(), 1); var { useSettingsForBlockElement: useSettingsForBlockElement5, ColorPanel: StylesColorPanel2 } = unlock3( import_block_editor7.privateApis ); +var ADDITIONAL_ELEMENTS = [ + { name: "cite", label: (0, import_i18n28.__)("Citations") }, + { name: "textInput", label: (0, import_i18n28.__)("Inputs") }, + { name: "select", label: (0, import_i18n28.__)("Selects") } +]; // packages/global-styles-ui/build-module/screen-color-palette.mjs -var import_i18n29 = __toESM(require_i18n(), 1); +var import_i18n32 = __toESM(require_i18n(), 1); // packages/global-styles-ui/build-module/color-palette-panel.mjs var import_compose4 = __toESM(require_compose(), 1); -var import_components38 = __toESM(require_components(), 1); -var import_i18n27 = __toESM(require_i18n(), 1); +var import_components37 = __toESM(require_components(), 1); +var import_i18n29 = __toESM(require_i18n(), 1); // packages/global-styles-ui/build-module/variations/variations-color.mjs -var import_components37 = __toESM(require_components(), 1); +var import_components36 = __toESM(require_components(), 1); // packages/global-styles-ui/build-module/preview-colors.mjs -var import_components36 = __toESM(require_components(), 1); +var import_components35 = __toESM(require_components(), 1); // packages/global-styles-ui/build-module/preset-colors.mjs -var import_jsx_runtime67 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime69 = __toESM(require_jsx_runtime(), 1); function PresetColors() { const { paletteColors } = useStylesPreviewColors(); - return paletteColors.slice(0, 4).map(({ slug, color }, index2) => /* @__PURE__ */ (0, import_jsx_runtime67.jsx)( + return paletteColors.slice(0, 4).map(({ slug, color }, index2) => /* @__PURE__ */ (0, import_jsx_runtime69.jsx)( "div", { style: { @@ -24673,7 +25250,7 @@ function PresetColors() { } // packages/global-styles-ui/build-module/preview-colors.mjs -var import_jsx_runtime68 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime70 = __toESM(require_jsx_runtime(), 1); var firstFrameVariants2 = { start: { scale: 1, @@ -24689,22 +25266,22 @@ var StylesPreviewColors = ({ isFocused, withHoverView }) => { - return /* @__PURE__ */ (0, import_jsx_runtime68.jsx)( + return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)( preview_wrapper_default, { label, isFocused, withHoverView, - children: ({ key }) => /* @__PURE__ */ (0, import_jsx_runtime68.jsx)( - import_components36.__unstableMotion.div, + children: ({ key }) => /* @__PURE__ */ (0, import_jsx_runtime70.jsx)( + import_components35.__unstableMotion.div, { variants: firstFrameVariants2, style: { height: "100%", overflow: "hidden" }, - children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)( - import_components36.__experimentalHStack, + children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)( + import_components35.__experimentalHStack, { spacing: 0, justify: "center", @@ -24712,7 +25289,7 @@ var StylesPreviewColors = ({ height: "100%", overflow: "hidden" }, - children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(PresetColors, {}) + children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(PresetColors, {}) } ) }, @@ -24724,7 +25301,7 @@ var StylesPreviewColors = ({ var preview_colors_default = StylesPreviewColors; // packages/global-styles-ui/build-module/variations/variations-color.mjs -var import_jsx_runtime69 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime71 = __toESM(require_jsx_runtime(), 1); var propertiesToFilter2 = ["color"]; function ColorVariations({ title, @@ -24734,16 +25311,16 @@ function ColorVariations({ if (colorVariations?.length <= 1) { return null; } - return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(import_components37.__experimentalVStack, { spacing: 3, children: [ - title && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(Subtitle, { level: 3, children: title }), - /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_components37.__experimentalGrid, { gap, children: colorVariations.map((variation, index2) => /* @__PURE__ */ (0, import_jsx_runtime69.jsx)( + return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(import_components36.__experimentalVStack, { spacing: 3, children: [ + title && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(Subtitle, { level: 3, children: title }), + /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_components36.__experimentalGrid, { gap, children: colorVariations.map((variation, index2) => /* @__PURE__ */ (0, import_jsx_runtime71.jsx)( Variation, { variation, isPill: true, properties: propertiesToFilter2, showTooltip: true, - children: () => /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(preview_colors_default, {}) + children: () => /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(preview_colors_default, {}) }, index2 )) }) @@ -24751,115 +25328,122 @@ function ColorVariations({ } // packages/global-styles-ui/build-module/color-palette-panel.mjs -var import_jsx_runtime70 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime72 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/gradients-palette-panel.mjs var import_compose5 = __toESM(require_compose(), 1); +var import_components38 = __toESM(require_components(), 1); +var import_i18n30 = __toESM(require_i18n(), 1); +var import_jsx_runtime73 = __toESM(require_jsx_runtime(), 1); + +// packages/global-styles-ui/build-module/duotone-palette-panel.mjs +var import_compose6 = __toESM(require_compose(), 1); +var import_element44 = __toESM(require_element(), 1); var import_components39 = __toESM(require_components(), 1); -var import_i18n28 = __toESM(require_i18n(), 1); -var import_jsx_runtime71 = __toESM(require_jsx_runtime(), 1); +var import_i18n31 = __toESM(require_i18n(), 1); +var import_jsx_runtime74 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/screen-color-palette.mjs -var import_jsx_runtime72 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime75 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/screen-background.mjs -var import_i18n30 = __toESM(require_i18n(), 1); +var import_i18n33 = __toESM(require_i18n(), 1); var import_block_editor9 = __toESM(require_block_editor(), 1); var import_components40 = __toESM(require_components(), 1); // packages/global-styles-ui/build-module/background-panel.mjs var import_block_editor8 = __toESM(require_block_editor(), 1); -var import_jsx_runtime73 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime76 = __toESM(require_jsx_runtime(), 1); var { BackgroundPanel: StylesBackgroundPanel2 } = unlock3( import_block_editor8.privateApis ); // packages/global-styles-ui/build-module/screen-background.mjs -var import_jsx_runtime74 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime77 = __toESM(require_jsx_runtime(), 1); var { useHasBackgroundPanel: useHasBackgroundPanel4 } = unlock3(import_block_editor9.privateApis); // packages/global-styles-ui/build-module/shadows-panel.mjs -var import_i18n33 = __toESM(require_i18n(), 1); +var import_i18n36 = __toESM(require_i18n(), 1); // packages/global-styles-ui/build-module/presets/preset-group.mjs var import_components42 = __toESM(require_components(), 1); -var import_i18n32 = __toESM(require_i18n(), 1); -var import_element42 = __toESM(require_element(), 1); +var import_i18n35 = __toESM(require_i18n(), 1); +var import_element45 = __toESM(require_element(), 1); // packages/global-styles-ui/build-module/presets/dialogs/confirm-reset-dialog.mjs var import_components41 = __toESM(require_components(), 1); -var import_i18n31 = __toESM(require_i18n(), 1); -var import_jsx_runtime75 = __toESM(require_jsx_runtime(), 1); +var import_i18n34 = __toESM(require_i18n(), 1); +var import_jsx_runtime78 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/presets/preset-group.mjs -var import_jsx_runtime76 = __toESM(require_jsx_runtime(), 1); -var { Menu } = unlock3(import_components42.privateApis); +var import_jsx_runtime79 = __toESM(require_jsx_runtime(), 1); +var { Menu: Menu2 } = unlock3(import_components42.privateApis); // packages/global-styles-ui/build-module/shadows-panel.mjs -var import_jsx_runtime77 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime80 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/shadows-edit-panel.mjs var import_components46 = __toESM(require_components(), 1); -var import_i18n36 = __toESM(require_i18n(), 1); -var import_element44 = __toESM(require_element(), 1); +var import_i18n39 = __toESM(require_i18n(), 1); +var import_element47 = __toESM(require_element(), 1); // packages/global-styles-ui/build-module/presets/preset-edit-header.mjs var import_components43 = __toESM(require_components(), 1); -var import_jsx_runtime78 = __toESM(require_jsx_runtime(), 1); -var { Menu: Menu2 } = unlock3(import_components43.privateApis); +var import_jsx_runtime81 = __toESM(require_jsx_runtime(), 1); +var { Menu: Menu3 } = unlock3(import_components43.privateApis); // packages/global-styles-ui/build-module/presets/dialogs/confirm-delete-dialog.mjs var import_components44 = __toESM(require_components(), 1); -var import_i18n34 = __toESM(require_i18n(), 1); -var import_jsx_runtime79 = __toESM(require_jsx_runtime(), 1); +var import_i18n37 = __toESM(require_i18n(), 1); +var import_jsx_runtime82 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/presets/dialogs/rename-dialog.mjs var import_components45 = __toESM(require_components(), 1); -var import_i18n35 = __toESM(require_i18n(), 1); -var import_element43 = __toESM(require_element(), 1); -var import_jsx_runtime80 = __toESM(require_jsx_runtime(), 1); +var import_i18n38 = __toESM(require_i18n(), 1); +var import_element46 = __toESM(require_element(), 1); +var import_jsx_runtime83 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/shadows-edit-panel.mjs -var import_jsx_runtime81 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime84 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/screen-shadows.mjs -var import_jsx_runtime82 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime85 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/screen-layout.mjs -var import_i18n37 = __toESM(require_i18n(), 1); +var import_i18n40 = __toESM(require_i18n(), 1); var import_block_editor11 = __toESM(require_block_editor(), 1); // packages/global-styles-ui/build-module/dimensions-panel.mjs var import_block_editor10 = __toESM(require_block_editor(), 1); -var import_element45 = __toESM(require_element(), 1); -var import_jsx_runtime83 = __toESM(require_jsx_runtime(), 1); +var import_element48 = __toESM(require_element(), 1); +var import_jsx_runtime86 = __toESM(require_jsx_runtime(), 1); var { useSettingsForBlockElement: useSettingsForBlockElement6, DimensionsPanel: StylesDimensionsPanel2 } = unlock3(import_block_editor10.privateApis); // packages/global-styles-ui/build-module/screen-layout.mjs -var import_jsx_runtime84 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime87 = __toESM(require_jsx_runtime(), 1); var { useHasDimensionsPanel: useHasDimensionsPanel4, useSettingsForBlockElement: useSettingsForBlockElement7 } = unlock3( import_block_editor11.privateApis ); // packages/global-styles-ui/build-module/screen-style-variations.mjs var import_components49 = __toESM(require_components(), 1); -var import_i18n40 = __toESM(require_i18n(), 1); +var import_i18n43 = __toESM(require_i18n(), 1); // packages/global-styles-ui/build-module/style-variations-content.mjs -var import_i18n39 = __toESM(require_i18n(), 1); +var import_i18n42 = __toESM(require_i18n(), 1); var import_components48 = __toESM(require_components(), 1); // packages/global-styles-ui/build-module/style-variations-container.mjs var import_core_data9 = __toESM(require_core_data(), 1); var import_data9 = __toESM(require_data(), 1); -var import_element46 = __toESM(require_element(), 1); +var import_element49 = __toESM(require_element(), 1); var import_components47 = __toESM(require_components(), 1); -var import_i18n38 = __toESM(require_i18n(), 1); -var import_jsx_runtime85 = __toESM(require_jsx_runtime(), 1); +var import_i18n41 = __toESM(require_i18n(), 1); +var import_jsx_runtime88 = __toESM(require_jsx_runtime(), 1); function StyleVariationsContainer({ gap = 2 }) { - const { user } = (0, import_element46.useContext)(GlobalStylesContext); + const { user } = (0, import_element49.useContext)(GlobalStylesContext); const userStyles = user?.styles; const variations = (0, import_data9.useSelect)((select) => { const result = select( @@ -24875,10 +25459,10 @@ function StyleVariationsContainer({ ]); } ); - const themeVariations = (0, import_element46.useMemo)(() => { + const themeVariations = (0, import_element49.useMemo)(() => { const withEmptyVariation = [ { - title: (0, import_i18n38.__)("Default"), + title: (0, import_i18n41.__)("Default"), settings: {}, styles: {} }, @@ -24921,14 +25505,14 @@ function StyleVariationsContainer({ if (!fullStyleVariations || fullStyleVariations.length < 1) { return null; } - return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)( + return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)( import_components47.__experimentalGrid, { columns: 2, className: "global-styles-ui-style-variations-container", gap, children: themeVariations.map( - (variation, index2) => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(Variation, { variation, children: (isFocused) => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)( + (variation, index2) => /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(Variation, { variation, children: (isFocused) => /* @__PURE__ */ (0, import_jsx_runtime88.jsx)( preview_styles_default, { label: variation?.title, @@ -24944,74 +25528,74 @@ function StyleVariationsContainer({ var style_variations_container_default = StyleVariationsContainer; // packages/global-styles-ui/build-module/style-variations-content.mjs -var import_jsx_runtime86 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime89 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/screen-style-variations.mjs -var import_jsx_runtime87 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime90 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/screen-css.mjs -var import_i18n41 = __toESM(require_i18n(), 1); +var import_i18n44 = __toESM(require_i18n(), 1); var import_components50 = __toESM(require_components(), 1); var import_block_editor12 = __toESM(require_block_editor(), 1); -var import_jsx_runtime88 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime91 = __toESM(require_jsx_runtime(), 1); var { AdvancedPanel: StylesAdvancedPanel2 } = unlock3(import_block_editor12.privateApis); // packages/global-styles-ui/build-module/screen-revisions/index.mjs -var import_i18n44 = __toESM(require_i18n(), 1); +var import_i18n47 = __toESM(require_i18n(), 1); var import_components53 = __toESM(require_components(), 1); -var import_element48 = __toESM(require_element(), 1); +var import_element51 = __toESM(require_element(), 1); // packages/global-styles-ui/build-module/screen-revisions/use-global-styles-revisions.mjs var import_data10 = __toESM(require_data(), 1); var import_core_data10 = __toESM(require_core_data(), 1); -var import_element47 = __toESM(require_element(), 1); +var import_element50 = __toESM(require_element(), 1); // packages/global-styles-ui/build-module/screen-revisions/revisions-buttons.mjs -var import_i18n42 = __toESM(require_i18n(), 1); +var import_i18n45 = __toESM(require_i18n(), 1); var import_components51 = __toESM(require_components(), 1); var import_date = __toESM(require_date(), 1); var import_core_data11 = __toESM(require_core_data(), 1); var import_data11 = __toESM(require_data(), 1); var import_keycodes2 = __toESM(require_keycodes(), 1); -var import_jsx_runtime89 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime92 = __toESM(require_jsx_runtime(), 1); var { Badge: WCBadge } = unlock3(import_components51.privateApis); var DAY_IN_MILLISECONDS = 60 * 60 * 1e3 * 24; // packages/global-styles-ui/build-module/pagination/index.mjs var import_components52 = __toESM(require_components(), 1); -var import_i18n43 = __toESM(require_i18n(), 1); -var import_jsx_runtime90 = __toESM(require_jsx_runtime(), 1); +var import_i18n46 = __toESM(require_i18n(), 1); +var import_jsx_runtime93 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/screen-revisions/index.mjs -var import_jsx_runtime91 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime94 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/font-sizes/font-sizes.mjs -var import_i18n45 = __toESM(require_i18n(), 1); +var import_i18n48 = __toESM(require_i18n(), 1); var import_components54 = __toESM(require_components(), 1); -var import_jsx_runtime92 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime95 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/font-sizes/font-size.mjs -var import_i18n47 = __toESM(require_i18n(), 1); +var import_i18n50 = __toESM(require_i18n(), 1); var import_components56 = __toESM(require_components(), 1); -var import_element49 = __toESM(require_element(), 1); +var import_element52 = __toESM(require_element(), 1); // packages/global-styles-ui/build-module/font-sizes/font-size-preview.mjs var import_block_editor13 = __toESM(require_block_editor(), 1); -var import_i18n46 = __toESM(require_i18n(), 1); -var import_jsx_runtime93 = __toESM(require_jsx_runtime(), 1); +var import_i18n49 = __toESM(require_i18n(), 1); +var import_jsx_runtime96 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/size-control/index.mjs var import_components55 = __toESM(require_components(), 1); -var import_jsx_runtime94 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime97 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/font-sizes/font-size.mjs -var import_jsx_runtime95 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime98 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/global-styles-ui.mjs -var import_jsx_runtime96 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime99 = __toESM(require_jsx_runtime(), 1); // packages/global-styles-ui/build-module/with-global-styles-provider.mjs -var import_jsx_runtime97 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime100 = __toESM(require_jsx_runtime(), 1); function withGlobalStylesProvider(Component) { return function WrappedComponent({ value, @@ -25019,13 +25603,13 @@ function withGlobalStylesProvider(Component) { onChange, ...props }) { - return /* @__PURE__ */ (0, import_jsx_runtime97.jsx)( + return /* @__PURE__ */ (0, import_jsx_runtime100.jsx)( GlobalStylesProvider, { value, baseValue, onChange, - children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(Component, { ...props }) + children: /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Component, { ...props }) } ); }; @@ -25041,7 +25625,7 @@ var ColorVariations2 = withGlobalStylesProvider(ColorVariations); var TypographyVariations2 = withGlobalStylesProvider(TypographyVariations); // packages/global-styles-ui/build-module/font-library/font-library.mjs -var import_jsx_runtime98 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime101 = __toESM(require_jsx_runtime(), 1); function FontLibrary({ value, baseValue, @@ -25051,21 +25635,21 @@ function FontLibrary({ let content; switch (activeTab) { case "upload-fonts": - content = /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(upload_fonts_default, {}); + content = /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(upload_fonts_default, {}); break; case "installed-fonts": - content = /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(installed_fonts_default, {}); + content = /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(installed_fonts_default, {}); break; default: - content = /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(font_collection_default, { slug: activeTab }); + content = /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(font_collection_default, { slug: activeTab }); } - return /* @__PURE__ */ (0, import_jsx_runtime98.jsx)( + return /* @__PURE__ */ (0, import_jsx_runtime101.jsx)( GlobalStylesProvider, { value, baseValue, onChange, - children: /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(context_default, { children: content }) + children: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(context_default, { children: content }) } ); } @@ -25078,21 +25662,22 @@ var { unlock: unlock4 } = (0, import_private_apis5.__dangerousOptInToUnstableAPI ); // routes/font-list/style.scss -if (typeof document !== "undefined" && true && !document.head.querySelector("style[data-wp-hash='9553e553cd']")) { +if (typeof document !== "undefined" && true && !document.head.querySelector("style[data-wp-hash='8316bac515']")) { const style = document.createElement("style"); - style.setAttribute("data-wp-hash", "9553e553cd"); - style.appendChild(document.createTextNode('@media (min-width:782px){.font-library-modal.font-library-modal{width:65vw}}.font-library-modal .components-modal__header{border-bottom:none}.font-library-modal .components-modal__content{margin-bottom:90px;padding:0}.font-library-modal .font-library__subtitle{font-size:11px;font-weight:var(--wpds-typography-font-weight-emphasis,600);text-transform:uppercase}.font-library-modal__tab-panel{height:calc(100% - 50px)}.font-library__tabpanel-layout{display:flex;flex-direction:column;height:100%}.font-library__tabpanel-layout>div{flex-grow:1}.font-library__tabpanel-layout .font-library__loading{align-items:center;box-sizing:border-box;display:flex;height:100%;justify-content:center;left:0;padding-top:124px;position:absolute;top:0;width:100%}.font-library__footer,.font-library__tabpanel-layout .components-navigator-screen{padding:24px;width:100%}.font-library__footer{background-color:#fff;border-top:1px solid #ddd;bottom:0;box-sizing:border-box;flex-grow:0!important;flex-shrink:0;height:90px;position:absolute}.font-library__page-selection{font-size:11px;font-weight:var(--wpds-typography-font-weight-emphasis,600);text-transform:uppercase}@media (min-width:600px){.font-library__page-selection .components-select-control__input{font-size:11px!important;font-weight:var(--wpds-typography-font-weight-emphasis,600)}}.font-library__search{width:240px}.font-library__fonts-title{font-size:11px;font-weight:var(--wpds-typography-font-weight-emphasis,600);margin-bottom:0;margin-top:0;text-transform:uppercase}.font-library__fonts-list{list-style:none;margin-bottom:0;margin-top:0;padding:0}.font-library__fonts-list-item{margin-bottom:0}.font-library__font-card{border:1px solid #ddd;box-sizing:border-box;height:auto!important;margin-top:-1px;padding:16px;width:100%}.font-library__font-card:hover{background-color:#f0f0f0}.font-library__font-card:focus{position:relative}.font-library__font-card .font-library__font-card__name{font-weight:700}.font-library__font-card .font-library__font-card__count{color:#757575}.font-library__font-card .font-library__font-variant_demo-image{display:block;height:24px;width:auto}.font-library__font-card .font-library__font-variant_demo-text{flex-shrink:0;white-space:nowrap}@media not (prefers-reduced-motion){.font-library__font-card .font-library__font-variant_demo-text{transition:opacity .3s ease-in-out}}.font-library-modal__tablist-container{background:#fff;border-bottom:1px solid #ddd;position:sticky;top:0;z-index:1}.font-library__upload-area{align-items:center;display:flex;height:256px!important;justify-content:center;width:100%}button.font-library__upload-area{background-color:#f0f0f0}.font-library__local-fonts{margin:24px auto;width:80%}.font-library__local-fonts .font-library__upload-area__text{color:#757575}.font-library__google-fonts-confirm{align-items:center;display:flex;justify-content:center;margin-top:64px}.font-library__google-fonts-confirm p{line-height:1.4}.font-library__google-fonts-confirm h2{font-size:1.2rem;font-weight:400}.font-library__google-fonts-confirm .components-card{padding:16px;width:400px}.font-library__google-fonts-confirm .components-button{justify-content:center;width:100%}.font-library__select-all{padding:16px 16px 16px 17px}.font-library__select-all .components-checkbox-control__label{padding-left:16px}.global-styles-ui-pagination .components-button.is-tertiary{height:32px;justify-content:center;width:32px}.global-styles-ui-screen-revisions__revisions-list{flex-grow:1;list-style:none;margin:0 16px 16px}.global-styles-ui-screen-revisions__revisions-list li{margin-bottom:0}.global-styles-ui-screen-revisions__revision-item{cursor:var(--wpds-cursor-control,pointer);display:flex;flex-direction:column;position:relative}.global-styles-ui-screen-revisions__revision-item[role=option]:active,.global-styles-ui-screen-revisions__revision-item[role=option]:focus{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid transparent}.global-styles-ui-screen-revisions__revision-item:hover{background:rgba(var(--wp-admin-theme-color--rgb),.04)}.global-styles-ui-screen-revisions__revision-item:hover .global-styles-ui-screen-revisions__date{color:var(--wp-admin-theme-color)}.global-styles-ui-screen-revisions__revision-item:after,.global-styles-ui-screen-revisions__revision-item:before{content:"\\a";display:block;position:absolute}.global-styles-ui-screen-revisions__revision-item:before{background:#ddd;border:4px solid transparent;border-radius:50%;height:8px;left:17px;top:18px;transform:translate(-50%,-50%);width:8px;z-index:1}.global-styles-ui-screen-revisions__revision-item[aria-selected=true]{background:rgba(var(--wp-admin-theme-color--rgb),.04);border-radius:2px;color:var(--wp-admin-theme-color);outline:3px solid transparent;outline-offset:-2px}.global-styles-ui-screen-revisions__revision-item[aria-selected=true] .global-styles-ui-screen-revisions__date{color:var(--wp-admin-theme-color)}.global-styles-ui-screen-revisions__revision-item[aria-selected=true]:before{background:var(--wp-admin-theme-color)}.global-styles-ui-screen-revisions__revision-item[aria-selected=true] .global-styles-ui-screen-revisions__changes>li,.global-styles-ui-screen-revisions__revision-item[aria-selected=true] .global-styles-ui-screen-revisions__meta{color:#1e1e1e}.global-styles-ui-screen-revisions__revision-item:after{border:.5px solid #ddd;height:100%;left:16px;top:0;width:0}.global-styles-ui-screen-revisions__revision-item:first-child:after{top:18px}.global-styles-ui-screen-revisions__revision-item:last-child:after{height:18px}.global-styles-ui-screen-revisions__revision-item-wrapper{display:block;padding:12px 12px 4px 40px}.global-styles-ui-screen-revisions__active-badge,.global-styles-ui-screen-revisions__apply-button.is-primary{align-self:flex-start;margin:0 12px 12px 40px}.global-styles-ui-screen-revisions__changes,.global-styles-ui-screen-revisions__meta{color:#757575;font-size:12px}.global-styles-ui-screen-revisions__description{align-items:flex-start;display:flex;flex-direction:column;gap:8px}.global-styles-ui-screen-revisions__description .global-styles-ui-screen-revisions__date{font-size:12px;font-weight:var(--wpds-typography-font-weight-emphasis,600);text-transform:uppercase}.global-styles-ui-screen-revisions__meta{align-items:flex-start;display:flex;justify-content:start;margin-bottom:4px;text-align:left;width:100%}.global-styles-ui-screen-revisions__meta img{border-radius:100%;height:16px;margin-right:8px;width:16px}.global-styles-ui-screen-revisions__loading{margin:24px auto!important}.global-styles-ui-screen-revisions__changes{line-height:1.4;list-style:disc;margin-left:12px;text-align:left}.global-styles-ui-screen-revisions__changes li{margin-bottom:4px}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination{gap:2px;justify-content:space-between}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .edit-site-pagination__total{height:1px;left:-1000px;margin:-1px;overflow:hidden;position:absolute}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-text{font-size:12px;will-change:opacity}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-button.is-tertiary{color:#1e1e1e}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-button.is-tertiary:disabled,.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-button.is-tertiary[aria-disabled=true]{color:#949494}.global-styles-ui-screen-revisions__footer{background:#fff;border-top:1px solid #ddd;bottom:0;box-sizing:border-box;height:56px;min-width:100%;padding:12px;position:sticky;z-index:1}.global-styles-ui-variations_item{box-sizing:border-box;cursor:var(--wpds-cursor-control,pointer)}.global-styles-ui-variations_item .global-styles-ui-variations_item-preview{border-radius:2px;outline:1px solid rgba(0,0,0,.1);outline-offset:-1px;overflow:hidden;position:relative}@media not (prefers-reduced-motion){.global-styles-ui-variations_item .global-styles-ui-variations_item-preview{transition:outline .1s linear}}.global-styles-ui-variations_item .global-styles-ui-variations_item-preview.is-pill{height:32px}.global-styles-ui-variations_item .global-styles-ui-variations_item-preview.is-pill .block-editor-iframe__scale-container{overflow:hidden}.global-styles-ui-variations_item:not(.is-active):hover .global-styles-ui-variations_item-preview{outline-color:rgba(0,0,0,.3)}.global-styles-ui-variations_item.is-active .global-styles-ui-variations_item-preview,.global-styles-ui-variations_item:focus-visible .global-styles-ui-variations_item-preview{outline-color:#1e1e1e;outline-offset:1px;outline-width:var(--wp-admin-border-width-focus)}.global-styles-ui-variations_item:focus-visible .global-styles-ui-variations_item-preview{outline-color:var(--wp-admin-theme-color)}.global-styles-ui-preview__wrapper{display:block;max-width:100%;width:100%}.global-styles-ui-preview__wrapper.is-hoverable{cursor:var(--wpds-cursor-control,pointer)}.global-styles-ui-typography-preview{align-items:center;background:#f0f0f0;border-radius:2px;display:flex;justify-content:center;margin-bottom:20px;min-height:100px;overflow:hidden}.global-styles-ui-font-size__item{line-break:anywhere;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.global-styles-ui-font-size__item-value{color:#757575}.global-styles-ui-screen-typography__indicator{align-items:center;border-radius:2px;display:flex!important;font-size:14px;height:24px;justify-content:center;width:24px}.global-styles-ui-block-types-search{margin-bottom:10px;padding:0 16px}.global-styles-ui-screen-typography__font-variants-count{color:#757575}.global-styles-ui-font-families__manage-fonts{justify-content:center}.global-styles-ui-screen .color-block-support-panel{border-top:none;padding-left:0;padding-right:0;padding-top:0;row-gap:12px}.global-styles-ui-header{line-height:1.9!important;margin-bottom:0!important}.global-styles-ui-subtitle{font-size:11px!important;font-weight:var(--wpds-typography-font-weight-emphasis,600)!important;margin-bottom:0!important;text-transform:uppercase}.global-styles-ui-section-title{color:#2f2f2f;font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:1.2;margin:0;padding:16px 16px 0}.global-styles-ui-icon-with-current-color{fill:currentColor}.global-styles-ui__color-indicator-wrapper{flex-shrink:0;height:24px}.global-styles-ui__shadows-panel__options-container,.global-styles-ui__typography-panel__options-container{height:24px}.global-styles-ui__block-preview-panel{border:1px solid #ddd;border-radius:2px;overflow:hidden;position:relative;width:100%}.global-styles-ui__shadow-preview-panel{background-image:repeating-linear-gradient(45deg,#e0e0e0 25%,transparent 0,transparent 75%,#e0e0e0 0,#e0e0e0),repeating-linear-gradient(45deg,#e0e0e0 25%,transparent 0,transparent 75%,#e0e0e0 0,#e0e0e0);background-position:0 0,8px 8px;background-size:16px 16px;border:1px solid #ddd;border-radius:2px;height:144px;overflow:auto}.global-styles-ui__shadow-preview-panel .global-styles-ui__shadow-preview-block{background-color:#fff;border:1px solid #ddd;border-radius:2px;height:60px;width:60%}.global-styles-ui__shadow-editor__dropdown-content{width:280px}.global-styles-ui__shadow-editor-panel{margin-bottom:4px}.global-styles-ui__shadow-editor__dropdown{position:relative;width:100%}.global-styles-ui__shadow-editor__dropdown-toggle{border-radius:inherit;height:auto;padding-bottom:8px;padding-top:8px;text-align:left;width:100%}.global-styles-ui__shadow-editor__dropdown-toggle.is-open{background:#f0f0f0;color:var(--wp-admin-theme-color)}.global-styles-ui__shadow-editor__remove-button{opacity:0;position:absolute;right:8px;top:8px}.global-styles-ui__shadow-editor__remove-button.global-styles-ui__shadow-editor__remove-button{border:none}.global-styles-ui__shadow-editor__dropdown-toggle:hover+.global-styles-ui__shadow-editor__remove-button,.global-styles-ui__shadow-editor__remove-button:focus,.global-styles-ui__shadow-editor__remove-button:hover{opacity:1}@media (hover:none){.global-styles-ui__shadow-editor__remove-button{opacity:1}}.global-styles-ui-screen-css{display:flex;flex:1 1 auto;flex-direction:column;margin:16px}.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel{flex:1 1 auto}.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel__custom-css-input,.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel__custom-css-input .components-base-control__field{display:flex;flex:1 1 auto;flex-direction:column}.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel__custom-css-input textarea{flex:1 1 auto}.global-styles-ui-screen-css-help-link{display:inline-block;margin-top:8px}.global-styles-ui-screen-variations{border-top:1px solid #ddd;margin-top:16px}.global-styles-ui-screen-variations>*{margin:24px 16px}.global-styles-ui-sidebar__navigator-provider{height:100%}.global-styles-ui-sidebar__navigator-screen{display:flex;flex-direction:column;height:100%}.global-styles-ui-color-palette__tablist-container{border-bottom:1px solid #ddd}.global-styles-ui-color-palette__tablist{margin-bottom:-1px}.global-styles-ui-sidebar__navigator-screen .single-column{grid-column:span 1}.global-styles-ui-screen-root.global-styles-ui-screen-root,.global-styles-ui-screen-style-variations.global-styles-ui-screen-style-variations{background:unset;color:inherit}.global-styles-ui-sidebar__panel .block-editor-block-icon svg{fill:currentColor}.global-styles-ui-screen-root__active-style-tile.global-styles-ui-screen-root__active-style-tile,.global-styles-ui-screen-root__active-style-tile.global-styles-ui-screen-root__active-style-tile .global-styles-ui-screen-root__active-style-tile-preview{border-radius:2px}.global-styles-ui-screen-root__active-style-tile-preview{clip-path:border-box}.global-styles-ui-color-palette-panel,.global-styles-ui-gradient-palette-panel{padding:16px}.font-library-page__tablist{border-bottom:1px solid #f0f0f0;padding:0 24px}.font-library-page__tab-panel{flex-grow:1;max-height:calc(100% - 110px);overflow:auto}.font-library-page:has(.font-library__footer) .font-library-page__tab-panel{max-height:calc(100% - 198px)}')); + style.setAttribute("data-wp-hash", "8316bac515"); + style.appendChild(document.createTextNode('@media (min-width:782px){.font-library-modal.font-library-modal{width:65vw}}.font-library-modal .components-modal__header{border-bottom:none}.font-library-modal .components-modal__content{margin-bottom:90px;padding:0}.font-library-modal .font-library__subtitle{font-size:11px;font-weight:var(--wpds-typography-font-weight-emphasis,600);text-transform:uppercase}.font-library-modal__tab-panel{height:calc(100% - 50px)}.font-library__tabpanel-layout{display:flex;flex-direction:column;height:100%}.font-library__tabpanel-layout>div{flex-grow:1}.font-library__tabpanel-layout .font-library__loading{align-items:center;box-sizing:border-box;display:flex;height:100%;justify-content:center;left:0;padding-top:124px;position:absolute;top:0;width:100%}.font-library__footer,.font-library__tabpanel-layout .components-navigator-screen{padding:24px;width:100%}.font-library__footer{background-color:#fff;border-top:1px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);bottom:0;box-sizing:border-box;flex-grow:0!important;flex-shrink:0;height:90px;position:absolute}.font-library__page-selection{font-size:11px;font-weight:var(--wpds-typography-font-weight-emphasis,600);text-transform:uppercase}@media (min-width:600px){.font-library__page-selection .components-select-control__input{font-size:11px!important;font-weight:var(--wpds-typography-font-weight-emphasis,600)}}.font-library__search{width:240px}.font-library__fonts-title{font-size:11px;font-weight:var(--wpds-typography-font-weight-emphasis,600);margin-bottom:0;margin-top:0;text-transform:uppercase}.font-library__fonts-list{list-style:none;margin-bottom:0;margin-top:0;padding:0}.font-library__fonts-list-item{margin-bottom:0}.font-library__font-demo{position:relative}.font-library__font-card{border:1px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);box-sizing:border-box;height:auto!important;margin-top:-1px;padding:16px;width:100%}.font-library__font-card:hover{background-color:#f0f0f0}.font-library__font-card:focus{position:relative}.font-library__font-card .font-library__font-card__name{font-weight:700}.font-library__font-card .font-library__font-card__count{color:#757575}.font-library__font-card .font-library__font-variant_demo-image{display:block;height:24px;width:auto}@media not (prefers-reduced-motion){.font-library__font-card .font-library__font-variant_demo-image{transition:opacity var(--wpds-motion-duration-lg,.3s) var(--wpds-motion-easing-subtle,cubic-bezier(.15,0,.15,1))}}.font-library__font-card .font-library__font-variant_demo-image.is-loading{left:0;opacity:0;position:absolute;top:0}.font-library__font-card .font-library__font-variant-demo-skeleton{border-radius:var(--wpds-border-radius-sm,2px);height:24px}.font-library__font-card .font-library__font-variant_demo-text{flex-shrink:0;white-space:nowrap}@media not (prefers-reduced-motion){.font-library__font-card .font-library__font-variant_demo-text{transition:opacity .3s ease-in-out}}.font-library-modal__tablist-container{background:#fff;border-bottom:1px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);position:sticky;top:0;z-index:1}.font-library__upload-area{align-items:center;display:flex;height:256px!important;justify-content:center;width:100%}button.font-library__upload-area{background-color:#f0f0f0}.font-library__local-fonts{margin:24px auto;width:80%}.font-library__local-fonts .font-library__upload-area__text{color:#757575}.font-library__google-fonts-confirm{align-items:center;display:flex;justify-content:center;margin-top:64px}.font-library__google-fonts-confirm p{line-height:1.4}.font-library__google-fonts-confirm h2{font-size:1.2rem;font-weight:400}.font-library__google-fonts-confirm .components-card{padding:16px;width:400px}.font-library__google-fonts-confirm .components-button{justify-content:center;width:100%}.font-library__select-all{padding:16px 16px 16px 17px}.font-library__select-all .components-checkbox-control__label{padding-left:16px}.global-styles-ui-pagination .components-button.is-tertiary{height:32px;justify-content:center;width:32px}.global-styles-ui-screen-revisions__revisions-list{flex-grow:1;list-style:none;margin:0 16px 16px}.global-styles-ui-screen-revisions__revisions-list li{margin-bottom:0}.global-styles-ui-screen-revisions__revision-item{cursor:var(--wpds-cursor-control,pointer);display:flex;flex-direction:column;position:relative}.global-styles-ui-screen-revisions__revision-item[role=option]:active,.global-styles-ui-screen-revisions__revision-item[role=option]:focus{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid transparent}.global-styles-ui-screen-revisions__revision-item:hover{background:rgba(var(--wp-admin-theme-color--rgb),.04)}.global-styles-ui-screen-revisions__revision-item:hover .global-styles-ui-screen-revisions__date{color:var(--wp-admin-theme-color)}.global-styles-ui-screen-revisions__revision-item:after,.global-styles-ui-screen-revisions__revision-item:before{content:"\\a";display:block;position:absolute}.global-styles-ui-screen-revisions__revision-item:before{background:#ddd;border:4px solid transparent;border-radius:50%;height:8px;left:17px;top:18px;transform:translate(-50%,-50%);width:8px;z-index:1}.global-styles-ui-screen-revisions__revision-item[aria-selected=true]{background:rgba(var(--wp-admin-theme-color--rgb),.04);border-radius:2px;color:var(--wp-admin-theme-color);outline:3px solid transparent;outline-offset:-2px}.global-styles-ui-screen-revisions__revision-item[aria-selected=true] .global-styles-ui-screen-revisions__date{color:var(--wp-admin-theme-color)}.global-styles-ui-screen-revisions__revision-item[aria-selected=true]:before{background:var(--wp-admin-theme-color)}.global-styles-ui-screen-revisions__revision-item[aria-selected=true] .global-styles-ui-screen-revisions__changes>li,.global-styles-ui-screen-revisions__revision-item[aria-selected=true] .global-styles-ui-screen-revisions__meta{color:#1e1e1e}.global-styles-ui-screen-revisions__revision-item:after{border:.5px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);height:100%;left:16px;top:0;width:0}.global-styles-ui-screen-revisions__revision-item:first-child:after{top:18px}.global-styles-ui-screen-revisions__revision-item:last-child:after{height:18px}.global-styles-ui-screen-revisions__revision-item-wrapper{display:block;padding:12px 12px 4px 40px}.global-styles-ui-screen-revisions__active-badge,.global-styles-ui-screen-revisions__apply-button.is-primary{align-self:flex-start;margin:0 12px 12px 40px}.global-styles-ui-screen-revisions__changes,.global-styles-ui-screen-revisions__meta{color:#757575;font-size:12px}.global-styles-ui-screen-revisions__description{align-items:flex-start;display:flex;flex-direction:column;gap:8px}.global-styles-ui-screen-revisions__description .global-styles-ui-screen-revisions__date{font-size:12px;font-weight:var(--wpds-typography-font-weight-emphasis,600);text-transform:uppercase}.global-styles-ui-screen-revisions__meta{align-items:flex-start;display:flex;justify-content:start;margin-bottom:4px;text-align:left;width:100%}.global-styles-ui-screen-revisions__meta img{border-radius:100%;height:16px;margin-right:8px;width:16px}.global-styles-ui-screen-revisions__loading{margin:24px auto!important}.global-styles-ui-screen-revisions__changes{line-height:1.4;list-style:disc;margin-left:12px;text-align:left}.global-styles-ui-screen-revisions__changes li{margin-bottom:4px}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination{gap:2px;justify-content:space-between}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .edit-site-pagination__total{height:1px;left:-1000px;margin:-1px;overflow:hidden;position:absolute}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-text{font-size:12px;will-change:opacity}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-button.is-tertiary{color:#1e1e1e}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-button.is-tertiary:disabled,.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-button.is-tertiary[aria-disabled=true]{color:#949494}.global-styles-ui-screen-revisions__footer{background:#fff;border-top:1px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);bottom:0;box-sizing:border-box;height:56px;min-width:100%;padding:12px;position:sticky;z-index:1}.global-styles-ui-variations_item{box-sizing:border-box;cursor:var(--wpds-cursor-control,pointer)}.global-styles-ui-variations_item .global-styles-ui-variations_item-preview{border-radius:2px;outline:1px solid rgba(0,0,0,.1);outline-offset:-1px;overflow:hidden;position:relative}@media not (prefers-reduced-motion){.global-styles-ui-variations_item .global-styles-ui-variations_item-preview{transition:outline .1s linear}}.global-styles-ui-variations_item .global-styles-ui-variations_item-preview.is-pill{height:32px}.global-styles-ui-variations_item .global-styles-ui-variations_item-preview.is-pill .block-editor-iframe__scale-container{overflow:hidden}.global-styles-ui-variations_item:not(.is-active):hover .global-styles-ui-variations_item-preview{outline-color:rgba(0,0,0,.3)}.global-styles-ui-variations_item.is-active .global-styles-ui-variations_item-preview,.global-styles-ui-variations_item:focus-visible .global-styles-ui-variations_item-preview{outline-color:#1e1e1e;outline-offset:1px;outline-width:var(--wp-admin-border-width-focus)}.global-styles-ui-variations_item:focus-visible .global-styles-ui-variations_item-preview{outline-color:var(--wp-admin-theme-color)}.global-styles-ui-preview__wrapper{display:block;max-width:100%;width:100%}.global-styles-ui-preview__wrapper.is-hoverable{cursor:var(--wpds-cursor-control,pointer)}.global-styles-ui-typography-preview{align-items:center;background:#f0f0f0;border-radius:2px;display:flex;justify-content:center;margin-bottom:20px;min-height:100px;overflow:hidden}.global-styles-ui-font-size__item{line-break:anywhere;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.global-styles-ui-font-size__item-value{color:#757575}.global-styles-ui-screen-typography__indicator{align-items:center;border-radius:2px;display:flex!important;font-size:14px;height:24px;justify-content:center;width:24px}.global-styles-ui-block-types-filter{margin-bottom:12px;padding:0 16px}.global-styles-ui-block-types-search{flex-grow:1}.global-styles-ui-block-types-item-list .global-styles-ui-block-types-item__icon{min-width:24px}.global-styles-ui-block-types-item-list__no-results{padding-top:16px}.global-styles-ui-block-types-item__indicator{background:var(--wp-admin-theme-color);border-radius:50%;flex:none;height:6px;margin-left:auto;width:6px}.global-styles-ui-screen-typography__font-variants-count{color:#757575}.global-styles-ui-font-families__manage-fonts{justify-content:center}.global-styles-ui-screen .color-block-support-panel{border-top:none;padding-left:0;padding-right:0;padding-top:0;row-gap:12px}.global-styles-ui-header{line-height:1.9!important;margin-bottom:0!important}.global-styles-ui-subtitle{font-size:11px!important;font-weight:var(--wpds-typography-font-weight-emphasis,600)!important;margin-bottom:0!important;text-transform:uppercase}.global-styles-ui-section-title{color:#2f2f2f;font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:1.2;margin:0;padding:16px 16px 0}.global-styles-ui-icon-with-current-color{fill:currentColor}.global-styles-ui__color-indicator-wrapper{flex-shrink:0;height:24px}.global-styles-ui__shadows-panel__options-container,.global-styles-ui__typography-panel__options-container{height:24px}.global-styles-ui__block-preview-panel{border:1px solid #ddd;border-radius:2px;overflow:hidden;position:relative;width:100%}.global-styles-ui__shadow-preview-panel{background-image:repeating-linear-gradient(45deg,#e0e0e0 25%,transparent 0,transparent 75%,#e0e0e0 0,#e0e0e0),repeating-linear-gradient(45deg,#e0e0e0 25%,transparent 0,transparent 75%,#e0e0e0 0,#e0e0e0);background-position:0 0,8px 8px;background-size:16px 16px;border:1px solid #ddd;border-radius:2px;height:144px;overflow:auto}.global-styles-ui__shadow-preview-panel .global-styles-ui__shadow-preview-block{background-color:#fff;border:1px solid #ddd;border-radius:2px;height:60px;width:60%}.global-styles-ui__shadow-editor__dropdown-content{width:280px}.global-styles-ui__shadow-editor-panel{margin-bottom:4px}.global-styles-ui__shadow-editor__dropdown{position:relative;width:100%}.global-styles-ui__shadow-editor__dropdown-toggle{border-radius:inherit;height:auto;padding-bottom:8px;padding-top:8px;text-align:left;width:100%}.global-styles-ui__shadow-editor__dropdown-toggle.is-open{background:#f0f0f0;color:var(--wp-admin-theme-color)}.global-styles-ui__shadow-editor__remove-button{opacity:0;position:absolute;right:8px;top:8px}.global-styles-ui__shadow-editor__dropdown-toggle:hover+.global-styles-ui__shadow-editor__remove-button,.global-styles-ui__shadow-editor__remove-button:focus,.global-styles-ui__shadow-editor__remove-button:hover{opacity:1}@media (hover:none){.global-styles-ui__shadow-editor__remove-button{opacity:1}}.global-styles-ui-screen-css{display:flex;flex:1 1 auto;flex-direction:column;margin:16px}.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel{flex:1 1 auto}.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel__custom-css-input,.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel__custom-css-input .components-base-control__field{display:flex;flex:1 1 auto;flex-direction:column}.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel__custom-css-input textarea{flex:1 1 auto}.global-styles-ui-screen-css-help-link{display:inline-block;margin-top:8px}.global-styles-ui-screen-variations{border-top:1px solid #ddd;margin-top:16px}.global-styles-ui-screen-variations>*{margin:24px 16px}.global-styles-ui-sidebar__navigator-provider{height:100%}.global-styles-ui-sidebar__navigator-screen{display:flex;flex-direction:column;height:100%}.global-styles-ui-color-palette__tablist-container{border-bottom:1px solid #ddd}.global-styles-ui-color-palette__tablist{margin-bottom:-1px}.global-styles-ui-sidebar__navigator-screen .single-column{grid-column:span 1}.global-styles-ui-screen-root.global-styles-ui-screen-root,.global-styles-ui-screen-style-variations.global-styles-ui-screen-style-variations{background:unset;color:inherit}.global-styles-ui-sidebar__panel .block-editor-block-icon svg{fill:currentColor}.global-styles-ui-screen-root__active-style-tile.global-styles-ui-screen-root__active-style-tile,.global-styles-ui-screen-root__active-style-tile.global-styles-ui-screen-root__active-style-tile .global-styles-ui-screen-root__active-style-tile-preview{border-radius:2px}.global-styles-ui-screen-root__active-style-tile-preview{clip-path:border-box}.global-styles-ui-color-palette-panel,.global-styles-ui-duotone-palette-panel,.global-styles-ui-gradient-palette-panel{padding:16px}.font-library-page__tablist{border-bottom:1px solid #f0f0f0;padding:0 24px}.font-library-page__tab-panel{flex-grow:1;max-height:calc(100% - 110px);overflow:auto}.font-library-page:has(.font-library__footer) .font-library-page__tab-panel{max-height:calc(100% - 198px)}')); document.head.appendChild(style); } // routes/font-list/stage.tsx +var import_jsx_runtime102 = __toESM(require_jsx_runtime()); var { Tabs: Tabs2 } = unlock4(import_components58.privateApis); var { useGlobalStyles } = unlock4(import_editor.privateApis); function FontLibraryPage() { const { records: collections = [] } = (0, import_core_data12.useEntityRecords)("root", "fontCollection", { _fields: "slug,name,description" }); - const [activeTab, setActiveTab] = (0, import_element51.useState)("installed-fonts"); + const [activeTab, setActiveTab] = (0, import_element54.useState)("installed-fonts"); const { base, user, setUser, isReady } = useGlobalStyles(); const canUserCreate = (0, import_data13.useSelect)((select) => { return select(import_core_data12.store).canUser("create", { @@ -25106,50 +25691,52 @@ function FontLibraryPage() { const tabs = [ { id: "installed-fonts", - title: (0, import_i18n48._x)("Library", "Font library") + title: (0, import_i18n51._x)("Library", "Font library") } ]; if (canUserCreate) { tabs.push({ id: "upload-fonts", - title: (0, import_i18n48._x)("Upload", "noun") + title: (0, import_i18n51._x)("Upload", "noun") }); tabs.push( ...(collections || []).map(({ slug, name: name2 }) => ({ id: slug, - title: collections && collections.length === 1 && slug === "google-fonts" ? (0, import_i18n48.__)("Install Fonts") : name2 + title: collections && collections.length === 1 && slug === "google-fonts" ? (0, import_i18n51.__)("Install Fonts") : name2 })) ); } - return /* @__PURE__ */ React.createElement(page_default, { title: (0, import_i18n48.__)("Fonts"), className: "font-library-page" }, /* @__PURE__ */ React.createElement( + return /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(page_default, { title: (0, import_i18n51.__)("Fonts"), className: "font-library-page", children: /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)( Tabs2, { selectedTabId: activeTab, - onSelect: (tabId) => setActiveTab(tabId) - }, - /* @__PURE__ */ React.createElement("div", { className: "font-library-page__tablist" }, /* @__PURE__ */ React.createElement(Tabs2.TabList, null, tabs.map(({ id, title }) => /* @__PURE__ */ React.createElement(Tabs2.Tab, { key: id, tabId: id }, title)))), - tabs.map(({ id }) => /* @__PURE__ */ React.createElement( - Tabs2.TabPanel, - { - key: id, - tabId: id, - focusable: false, - className: "font-library-page__tab-panel" - }, - /* @__PURE__ */ React.createElement( - FontLibrary, - { - value: user, - baseValue: base, - onChange: setUser, - activeTab: id - } - ) - )) - )); + onSelect: (tabId) => setActiveTab(tabId), + children: [ + /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("div", { className: "font-library-page__tablist", children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(Tabs2.TabList, { children: tabs.map(({ id, title }) => /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(Tabs2.Tab, { tabId: id, children: title }, id)) }) }), + tabs.map(({ id }) => /* @__PURE__ */ (0, import_jsx_runtime102.jsx)( + Tabs2.TabPanel, + { + tabId: id, + focusable: false, + className: "font-library-page__tab-panel", + children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)( + FontLibrary, + { + value: user, + baseValue: base, + onChange: setUser, + activeTab: id + } + ) + }, + id + )) + ] + } + ) }); } function Stage() { - return /* @__PURE__ */ React.createElement(FontLibraryPage, null); + return /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(FontLibraryPage, {}); } var stage = Stage; export { diff --git a/src/wp-includes/build/routes/font-list/content.min.asset.php b/src/wp-includes/build/routes/font-list/content.min.asset.php index 93a78c7d9e473..a14c8d81d4ff1 100644 --- a/src/wp-includes/build/routes/font-list/content.min.asset.php +++ b/src/wp-includes/build/routes/font-list/content.min.asset.php @@ -1 +1 @@ - array('react', 'react-dom', 'react-jsx-runtime', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-date', 'wp-editor', 'wp-element', 'wp-i18n', 'wp-keycodes', 'wp-primitives', 'wp-private-apis', 'wp-style-engine', 'wp-theme'), 'module_dependencies' => array(array('id' => '@wordpress/a11y', 'import' => 'static'), array('id' => '@wordpress/route', 'import' => 'static')), 'version' => '43d7c20a365e66da5be0'); \ No newline at end of file + array('react', 'react-dom', 'react-jsx-runtime', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-date', 'wp-editor', 'wp-element', 'wp-i18n', 'wp-keycodes', 'wp-primitives', 'wp-private-apis', 'wp-style-engine', 'wp-theme', 'wp-warning'), 'module_dependencies' => array(array('id' => '@wordpress/a11y', 'import' => 'static'), array('id' => '@wordpress/route', 'import' => 'static')), 'version' => '104b97a0cdd454e16bdd'); \ No newline at end of file diff --git a/src/wp-includes/build/routes/font-list/content.min.js b/src/wp-includes/build/routes/font-list/content.min.js index 4b9b08be15c2d..9b907e95bf431 100644 --- a/src/wp-includes/build/routes/font-list/content.min.js +++ b/src/wp-includes/build/routes/font-list/content.min.js @@ -1,4 +1,4 @@ -var gv=Object.create;var Ra=Object.defineProperty;var yv=Object.getOwnPropertyDescriptor;var vv=Object.getOwnPropertyNames;var bv=Object.getPrototypeOf,wv=Object.prototype.hasOwnProperty;var zt=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof require<"u"?require:t)[r]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var tt=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),ro=(e,t)=>{for(var r in t)Ra(e,r,{get:t[r],enumerable:!0})},xv=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of vv(t))!wv.call(e,n)&&n!==r&&Ra(e,n,{get:()=>t[n],enumerable:!(o=yv(t,n))||o.enumerable});return e};var h=(e,t,r)=>(r=e!=null?gv(bv(e)):{},xv(t||!e||!e.__esModule?Ra(r,"default",{value:e,enumerable:!0}):r,e));var xe=tt((q2,Ou)=>{Ou.exports=window.wp.i18n});var ke=tt((X2,Fu)=>{Fu.exports=window.wp.element});var ge=tt((K2,Au)=>{Au.exports=window.React});var Y=tt((oT,Du)=>{Du.exports=window.ReactJSXRuntime});var io=tt((QT,af)=>{af.exports=window.ReactDOM});var md=tt(pd=>{"use strict";var ln=ge();function S0(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var C0=typeof Object.is=="function"?Object.is:S0,R0=ln.useState,E0=ln.useEffect,T0=ln.useLayoutEffect,_0=ln.useDebugValue;function P0(e,t){var r=t(),o=R0({inst:{value:r,getSnapshot:t}}),n=o[0].inst,s=o[1];return T0(function(){n.value=r,n.getSnapshot=t,ll(n)&&s({inst:n})},[e,r,t]),E0(function(){return ll(n)&&s({inst:n}),e(function(){ll(n)&&s({inst:n})})},[e]),_0(r),r}function ll(e){var t=e.getSnapshot;e=e.value;try{var r=t();return!C0(e,r)}catch{return!0}}function O0(e,t){return t()}var k0=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?O0:P0;pd.useSyncExternalStore=ln.useSyncExternalStore!==void 0?ln.useSyncExternalStore:k0});var cl=tt((jP,hd)=>{"use strict";hd.exports=md()});var yd=tt(gd=>{"use strict";var Qs=ge(),F0=cl();function A0(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var I0=typeof Object.is=="function"?Object.is:A0,L0=F0.useSyncExternalStore,N0=Qs.useRef,D0=Qs.useEffect,M0=Qs.useMemo,V0=Qs.useDebugValue;gd.useSyncExternalStoreWithSelector=function(e,t,r,o,n){var s=N0(null);if(s.current===null){var i={hasValue:!1,value:null};s.current=i}else i=s.current;s=M0(function(){function u(g){if(!l){if(l=!0,c=g,g=o(g),n!==void 0&&i.hasValue){var d=i.value;if(n(d,g))return f=d}return f=g}if(d=f,I0(c,g))return d;var v=o(g);return n!==void 0&&n(d,v)?(c=g,d):(c=g,f=v)}var l=!1,c,f,m=r===void 0?null:r;return[function(){return u(t())},m===null?void 0:function(){return u(m())}]},[t,r,o,n]);var a=L0(e,s[0],s[1]);return D0(function(){i.hasValue=!0,i.value=a},[a]),V0(a),a}});var bd=tt((UP,vd)=>{"use strict";vd.exports=yd()});var bn=tt((oA,jp)=>{jp.exports=window.wp.primitives});var No=tt((nA,zp)=>{zp.exports=window.wp.compose});var Wp=tt((xA,Hp)=>{Hp.exports=window.wp.theme});var as=tt((SA,Gp)=>{Gp.exports=window.wp.privateApis});var ce=tt((T4,_m)=>{_m.exports=window.wp.components});var Dm=tt((V4,Nm)=>{Nm.exports=window.wp.editor});var nr=tt((B4,Mm)=>{Mm.exports=window.wp.coreData});var Xt=tt((j4,Vm)=>{Vm.exports=window.wp.data});var Sn=tt((z4,Bm)=>{Bm.exports=window.wp.blocks});var Dt=tt((U4,jm)=>{jm.exports=window.wp.blockEditor});var Um=tt((Z4,zm)=>{zm.exports=window.wp.styleEngine});var Xm=tt((i5,Zm)=>{"use strict";Zm.exports=function e(t,r){if(t===r)return!0;if(t&&r&&typeof t=="object"&&typeof r=="object"){if(t.constructor!==r.constructor)return!1;var o,n,s;if(Array.isArray(t)){if(o=t.length,o!=r.length)return!1;for(n=o;n--!==0;)if(!e(t[n],r[n]))return!1;return!0}if(t instanceof Map&&r instanceof Map){if(t.size!==r.size)return!1;for(n of t.entries())if(!r.has(n[0]))return!1;for(n of t.entries())if(!e(n[1],r.get(n[0])))return!1;return!0}if(t instanceof Set&&r instanceof Set){if(t.size!==r.size)return!1;for(n of t.entries())if(!r.has(n[0]))return!1;return!0}if(ArrayBuffer.isView(t)&&ArrayBuffer.isView(r)){if(o=t.length,o!=r.length)return!1;for(n=o;n--!==0;)if(t[n]!==r[n])return!1;return!0}if(t.constructor===RegExp)return t.source===r.source&&t.flags===r.flags;if(t.valueOf!==Object.prototype.valueOf)return t.valueOf()===r.valueOf();if(t.toString!==Object.prototype.toString)return t.toString()===r.toString();if(s=Object.keys(t),o=s.length,o!==Object.keys(r).length)return!1;for(n=o;n--!==0;)if(!Object.prototype.hasOwnProperty.call(r,s[n]))return!1;for(n=o;n--!==0;){var i=s[n];if(!e(t[i],r[i]))return!1}return!0}return t!==t&&r!==r}});var $m=tt((l5,Qm)=>{"use strict";var i1=function(t){return a1(t)&&!l1(t)};function a1(e){return!!e&&typeof e=="object"}function l1(e){var t=Object.prototype.toString.call(e);return t==="[object RegExp]"||t==="[object Date]"||f1(e)}var c1=typeof Symbol=="function"&&Symbol.for,u1=c1?Symbol.for("react.element"):60103;function f1(e){return e.$$typeof===u1}function d1(e){return Array.isArray(e)?[]:{}}function ds(e,t){return t.clone!==!1&&t.isMergeableObject(e)?Rn(d1(e),e,t):e}function p1(e,t,r){return e.concat(t).map(function(o){return ds(o,r)})}function m1(e,t){if(!t.customMerge)return Rn;var r=t.customMerge(e);return typeof r=="function"?r:Rn}function h1(e){return Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(e).filter(function(t){return Object.propertyIsEnumerable.call(e,t)}):[]}function Km(e){return Object.keys(e).concat(h1(e))}function Jm(e,t){try{return t in e}catch{return!1}}function g1(e,t){return Jm(e,t)&&!(Object.hasOwnProperty.call(e,t)&&Object.propertyIsEnumerable.call(e,t))}function y1(e,t,r){var o={};return r.isMergeableObject(e)&&Km(e).forEach(function(n){o[n]=ds(e[n],r)}),Km(t).forEach(function(n){g1(e,n)||(Jm(e,n)&&r.isMergeableObject(t[n])?o[n]=m1(n,r)(e[n],t[n],r):o[n]=ds(t[n],r))}),o}function Rn(e,t,r){r=r||{},r.arrayMerge=r.arrayMerge||p1,r.isMergeableObject=r.isMergeableObject||i1,r.cloneUnlessOtherwiseSpecified=ds;var o=Array.isArray(t),n=Array.isArray(e),s=o===n;return s?o?r.arrayMerge(e,t,r):y1(e,t,r):ds(t,r)}Rn.all=function(t,r){if(!Array.isArray(t))throw new Error("first argument should be an array");return t.reduce(function(o,n){return Rn(o,n,r)},{})};var v1=Rn;Qm.exports=v1});var jc=tt((QL,ug)=>{ug.exports=window.wp.keycodes});var mg=tt((uN,pg)=>{pg.exports=window.wp.apiFetch});var Xy=tt((Qz,Zy)=>{Zy.exports=window.wp.date});function ku(e){var t,r,o="";if(typeof e=="string"||typeof e=="number")o+=e;else if(typeof e=="object")if(Array.isArray(e)){var n=e.length;for(t=0;te();function Te(e){let t=Rt(Ev).current;return t.next=e,Rv(t.effect),t.trampoline}function Ev(){let e={next:void 0,callback:Tv,trampoline:(...t)=>e.callback?.(...t),effect:()=>{e.callback=e.next}};return e}function Tv(){}var Nu=h(ge(),1),_v=()=>{},ye=typeof document<"u"?Nu.useLayoutEffect:_v;var ks=h(ge(),1),Ta=ks.createContext(void 0);function Qo(){return ks.useContext(Ta)?.direction??"ltr"}function Pv(e,t){return function(o,...n){let s=new URL(e);return s.searchParams.set("code",o.toString()),n.forEach(i=>s.searchParams.append("args[]",i)),`${t} error #${o}; visit ${s} for the full message.`}}var Ov=Pv("https://base-ui.com/production-error","Base UI"),Ut=Ov;var Eo=h(ge(),1);function _a(e,t,r,o){let n=Rt(Vu).current;return kv(n,e,t,r,o)&&Bu(n,[e,t,r,o]),n.callback}function Mu(e){let t=Rt(Vu).current;return Fv(t,e)&&Bu(t,e),t.callback}function Vu(){return{callback:null,cleanup:null,refs:[]}}function kv(e,t,r,o,n){return e.refs[0]!==t||e.refs[1]!==r||e.refs[2]!==o||e.refs[3]!==n}function Fv(e,t){return e.refs.length!==t.length||e.refs.some((r,o)=>r!==t[o])}function Bu(e,t){if(e.refs=t,t.every(r=>r==null)){e.callback=null;return}e.callback=r=>{if(e.cleanup&&(e.cleanup(),e.cleanup=null),r!=null){let o=Array(t.length).fill(null);for(let n=0;n{for(let n=0;n=e}function Pa(e){if(!zu.isValidElement(e))return null;let t=e,r=t.props;return($o(19)?r?.ref:t.ref)??null}function Gn(e,t){if(e&&!t)return e;if(!e&&t)return t;if(e||t)return{...e,...t}}function oo(){}var dT=Object.freeze([]),pt=Object.freeze({});function Uu(e,t){let r={};for(let o in e){let n=e[o];if(t?.hasOwnProperty(o)){let s=t[o](n);s!=null&&Object.assign(r,s);continue}n===!0?r[`data-${o.toLowerCase()}`]="":n&&(r[`data-${o.toLowerCase()}`]=n.toString())}return r}function Hu(e,t){return typeof e=="function"?e(t):e}function Wu(e,t){return typeof e=="function"?e(t):e}var Oa={};function er(e,t,r,o,n){if(!r&&!o&&!n&&!e)return Fs(t);let s=Fs(e);return t&&(s=Yn(s,t)),r&&(s=Yn(s,r)),o&&(s=Yn(s,o)),n&&(s=Yn(s,n)),s}function Gu(e){if(e.length===0)return Oa;if(e.length===1)return Fs(e[0]);let t=Fs(e[0]);for(let r=1;r=65&&n<=90&&(typeof t=="function"||typeof t>"u")}function ka(e){return typeof e=="function"}function qu(e,t){return ka(e)?e(t):e??Oa}function Nv(e,t){return t?e?(...r)=>{let o=r[0];if(Ku(o)){let s=o;Xu(s);let i=t(...r);return s.baseUIHandlerPrevented||e?.(...r),i}let n=t(...r);return e?.(...r),n}:Zu(t):e}function Zu(e){return e&&((...t)=>{let r=t[0];return Ku(r)&&Xu(r),e(...t)})}function Xu(e){return e.preventBaseUIHandler=()=>{e.baseUIHandlerPrevented=!0},e}function Fa(e,t){return t?e?t+" "+e:t:e}function Ku(e){return e!=null&&typeof e=="object"&&"nativeEvent"in e}var Aa=h(ge(),1);function Ht(e,t,r={}){let o=t.render,n=Dv(t,r);if(r.enabled===!1)return null;let s=r.state??pt;return Bv(e,o,n,s)}function Dv(e,t={}){let{className:r,style:o,render:n}=e,{state:s=pt,ref:i,props:a,stateAttributesMapping:u,enabled:l=!0}=t,c=l?Hu(r,s):void 0,f=l?Wu(o,s):void 0,m=l?Uu(s,u):pt,g=l&&a?Mv(a):void 0,d=l?Gn(m,g)??{}:pt;return typeof document<"u"&&(l?Array.isArray(i)?d.ref=Mu([d.ref,Pa(n),...i]):d.ref=_a(d.ref,Pa(n),i):_a(null,null)),l?(c!==void 0&&(d.className=Fa(d.className,c)),f!==void 0&&(d.style=Gn(d.style,f)),d):pt}function Mv(e){return Array.isArray(e)?Gu(e):er(void 0,e)}var Vv=Symbol.for("react.lazy");function Bv(e,t,r,o){if(t){if(typeof t=="function")return t(r,o);let n=er(r,t.props);n.ref=r.ref;let s=t;return s?.$$typeof===Vv&&(s=Eo.Children.toArray(t)[0]),Eo.cloneElement(s,n)}if(e&&typeof e=="string")return jv(e,r);throw new Error(Ut(8))}function jv(e,t){return e==="button"?(0,Aa.createElement)("button",{type:"button",...t,key:t.key}):e==="img"?(0,Aa.createElement)("img",{alt:"",...t,key:t.key}):Eo.createElement(e,t)}var As=h(ge(),1);var Ju=0;function zv(e,t="mui"){let[r,o]=As.useState(e),n=e||r;return As.useEffect(()=>{r==null&&(Ju+=1,o(`${t}-${Ju}`))},[r,t]),n}var Qu=Wn.useId;function no(e,t){if(Qu!==void 0){let r=Qu();return e??(t?`${t}-${r}`:r)}return zv(e,t)}function $u(e){return no(e,"base-ui")}var _e={};ro(_e,{cancelOpen:()=>hb,chipRemovePress:()=>Jv,clearPress:()=>Kv,closePress:()=>Zv,closeWatcher:()=>lb,decrementPress:()=>eb,disabled:()=>yb,drag:()=>db,escapeKey:()=>ab,focusOut:()=>ib,imperativeAction:()=>wb,incrementPress:()=>$v,initial:()=>bb,inputBlur:()=>ob,inputChange:()=>tb,inputClear:()=>rb,inputPaste:()=>nb,inputPress:()=>sb,itemPress:()=>qv,keyboard:()=>ub,linkPress:()=>Xv,listNavigation:()=>cb,missing:()=>vb,none:()=>Uv,outsidePress:()=>Yv,pointer:()=>fb,scrub:()=>mb,siblingOpen:()=>gb,swipe:()=>xb,trackPress:()=>Qv,triggerFocus:()=>Gv,triggerHover:()=>Wv,triggerPress:()=>Hv,wheel:()=>pb,windowResize:()=>Sb});var Uv="none",Hv="trigger-press",Wv="trigger-hover",Gv="trigger-focus",Yv="outside-press",qv="item-press",Zv="close-press",Xv="link-press",Kv="clear-press",Jv="chip-remove-press",Qv="track-press",$v="increment-press",eb="decrement-press",tb="input-change",rb="input-clear",ob="input-blur",nb="input-paste",sb="input-press",ib="focus-out",ab="escape-key",lb="close-watcher",cb="list-navigation",ub="keyboard",fb="pointer",db="drag",pb="wheel",mb="scrub",hb="cancel-open",gb="sibling-open",yb="disabled",vb="missing",bb="initial",wb="imperative-action",xb="swipe",Sb="window-resize";function je(e,t,r,o){let n=!1,s=!1,i=o??pt;return{reason:e,event:t??new Event("base-ui"),cancel(){n=!0},allowPropagation(){s=!0},get isCanceled(){return n},get isPropagationAllowed(){return s},trigger:r,...i}}var La=h(ge(),1);var ef=h(ge(),1),Cb=[];function en(e){ef.useEffect(e,Cb)}var Is=null,BT=globalThis.requestAnimationFrame,Ia=class{callbacks=[];callbacksCount=0;nextId=1;startId=1;isScheduled=!1;tick=t=>{this.isScheduled=!1;let r=this.callbacks,o=this.callbacksCount;if(this.callbacks=[],this.callbacksCount=0,this.startId=this.nextId,o>0)for(let n=0;n=this.callbacks.length||(this.callbacks[r]=null,this.callbacksCount-=1)}},Ls=new Ia,Er=class e{static create(){return new e}static request(t){return Ls.request(t)}static cancel(t){return Ls.cancel(t)}currentId=Is;request(t){this.cancel(),this.currentId=Ls.request(()=>{this.currentId=Is,t()})}cancel=()=>{this.currentId!==Is&&(Ls.cancel(this.currentId),this.currentId=Is)};disposeEffect=()=>this.cancel};function tn(){let e=Rt(Er.create).current;return en(e.disposeEffect),e}function tf(e,t=!1,r=!1){let[o,n]=La.useState(e&&t?"idle":void 0),[s,i]=La.useState(e);return e&&!s&&(i(!0),n("starting")),!e&&s&&o!=="ending"&&!r&&n("ending"),!e&&!s&&o==="ending"&&n(void 0),ye(()=>{if(!e&&s&&o!=="ending"&&r){let a=Er.request(()=>{n("ending")});return()=>{Er.cancel(a)}}},[e,s,o,r]),ye(()=>{if(!e||t)return;let a=Er.request(()=>{n(void 0)});return()=>{Er.cancel(a)}},[t,e]),ye(()=>{if(!e||!t)return;e&&s&&o!=="idle"&&n("starting");let a=Er.request(()=>{n("idle")});return()=>{Er.cancel(a)}},[t,e,s,o]),{mounted:s,setMounted:i,transitionStatus:o}}var To=(function(e){return e.startingStyle="data-starting-style",e.endingStyle="data-ending-style",e})({}),Rb={[To.startingStyle]:""},Eb={[To.endingStyle]:""},rf={transitionStatus(e){return e==="starting"?Rb:e==="ending"?Eb:null}};function Ns(){return typeof window<"u"}function Po(e){return Ds(e)?(e.nodeName||"").toLowerCase():"#document"}function it(e){var t;return(e==null||(t=e.ownerDocument)==null?void 0:t.defaultView)||window}function _r(e){var t;return(t=(Ds(e)?e.ownerDocument:e.document)||window.document)==null?void 0:t.documentElement}function Ds(e){return Ns()?e instanceof Node||e instanceof it(e).Node:!1}function Se(e){return Ns()?e instanceof Element||e instanceof it(e).Element:!1}function Et(e){return Ns()?e instanceof HTMLElement||e instanceof it(e).HTMLElement:!1}function rn(e){return!Ns()||typeof ShadowRoot>"u"?!1:e instanceof ShadowRoot||e instanceof it(e).ShadowRoot}function qn(e){let{overflow:t,overflowX:r,overflowY:o,display:n}=Lt(e);return/auto|scroll|overlay|hidden|clip/.test(t+o+r)&&n!=="inline"&&n!=="contents"}function of(e){return/^(table|td|th)$/.test(Po(e))}function Zn(e){try{if(e.matches(":popover-open"))return!0}catch{}try{return e.matches(":modal")}catch{return!1}}var Tb=/transform|translate|scale|rotate|perspective|filter/,_b=/paint|layout|strict|content/,_o=e=>!!e&&e!=="none",Na;function Ms(e){let t=Se(e)?Lt(e):e;return _o(t.transform)||_o(t.translate)||_o(t.scale)||_o(t.rotate)||_o(t.perspective)||!Vs()&&(_o(t.backdropFilter)||_o(t.filter))||Tb.test(t.willChange||"")||_b.test(t.contain||"")}function nf(e){let t=Tr(e);for(;Et(t)&&!Pr(t);){if(Ms(t))return t;if(Zn(t))return null;t=Tr(t)}return null}function Vs(){return Na==null&&(Na=typeof CSS<"u"&&CSS.supports&&CSS.supports("-webkit-backdrop-filter","none")),Na}function Pr(e){return/^(html|body|#document)$/.test(Po(e))}function Lt(e){return it(e).getComputedStyle(e)}function Xn(e){return Se(e)?{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}:{scrollLeft:e.scrollX,scrollTop:e.scrollY}}function Tr(e){if(Po(e)==="html")return e;let t=e.assignedSlot||e.parentNode||rn(e)&&e.host||_r(e);return rn(t)?t.host:t}function sf(e){let t=Tr(e);return Pr(t)?(e.ownerDocument||e).body:Et(t)&&qn(t)?t:sf(t)}function so(e,t,r){var o;t===void 0&&(t=[]),r===void 0&&(r=!0);let n=sf(e),s=n===((o=e.ownerDocument)==null?void 0:o.body),i=it(n);if(s){let a=Bs(i);return t.concat(i,i.visualViewport||[],qn(n)?n:[],a&&r?so(a):[])}else return t.concat(n,so(n,[],r))}function Bs(e){return e.parent&&Object.getPrototypeOf(e.parent)?e.frameElement:null}function Ye(e,t,r,o){return e.addEventListener(t,r,o),()=>{e.removeEventListener(t,r,o)}}function Wt(e){let t=Rt(Pb,e).current;return t.next=e,ye(t.effect),t}function Pb(e){let t={current:e,next:e,effect:()=>{t.current=t.next}};return t}function xt(e){return e?.ownerDocument||document}var uf=h(ge(),1);var cf=h(io(),1);function lf(e){return e==null?e:"current"in e?e.current:e}function on(e,t=!1,r=!0){let o=tn();return Te((n,s=null)=>{o.cancel();let i=lf(e);if(i==null)return;let a=i,u=()=>{cf.flushSync(n)};if(typeof a.getAnimations!="function"||globalThis.BASE_UI_ANIMATIONS_DISABLED){n();return}function l(){Promise.all(a.getAnimations().map(c=>c.finished)).then(()=>{s?.aborted||u()}).catch(()=>{if(r){s?.aborted||u();return}let c=a.getAnimations();!s?.aborted&&c.length>0&&c.some(f=>f.pending||f.playState!=="finished")&&l()})}if(t){let c=To.startingStyle;if(!a.hasAttribute(c)){o.request(l);return}let f=new MutationObserver(()=>{a.hasAttribute(c)||(f.disconnect(),l())});f.observe(a,{attributes:!0,attributeFilter:[c]}),s?.addEventListener("abort",()=>f.disconnect(),{once:!0});return}o.request(l)})}function js(e){let{enabled:t=!0,open:r,ref:o,onComplete:n}=e,s=Te(n),i=on(o,r,!1);uf.useEffect(()=>{if(!t)return;let a=new AbortController;return i(s,a.signal),()=>{a.abort()}},[t,r,s,i])}var ff=h(ge(),1);function df(e){let t=ff.useRef(!0);t.current&&(t.current=!1,e())}var Wr={};ro(Wr,{engine:()=>ja,env:()=>Ua,os:()=>Va,screenReader:()=>za});var Va={};ro(Va,{android:()=>hf,apple:()=>Ma,ios:()=>Da,linux:()=>Ib,mac:()=>gf,windows:()=>Ab});function Ob(){return typeof navigator>"u"?{userAgent:"",platform:"",maxTouchPoints:0}:{userAgent:navigator.userAgent,platform:navigator.platform??"",maxTouchPoints:navigator.maxTouchPoints??0}}var{userAgent:kb,platform:Fb,maxTouchPoints:pf}=Ob(),Oo=kb.toLowerCase(),ko=Fb.toLowerCase();var Da=/^i(os$|p)/.test(ko)||ko==="macintel"&&pf>1,mf="android",hf=ko===mf||Oo.includes(mf),gf=!Da&&ko.startsWith("mac"),Ab=ko.startsWith("win"),Ib=!hf&&/^(linux|chrome os)/.test(ko),Ma=gf||Da;var ja={};ro(ja,{blink:()=>Nb,gecko:()=>Lb,webkit:()=>Ba});var Ba=typeof CSS<"u"&&!!CSS.supports?.("-webkit-backdrop-filter:none"),Lb=!Ba&&Oo.includes("firefox"),Nb=!Ba&&Oo.includes("chrom");var za={};ro(za,{voiceOver:()=>Db});var Db=Ma;var Ua={};ro(Ua,{jsdom:()=>Mb});var Mb=/jsdom|happydom/.test(Oo);var Kn=0,tr=class e{static create(){return new e}currentId=Kn;start(t,r){this.clear(),this.currentId=setTimeout(()=>{this.currentId=Kn,r()},t)}isStarted(){return this.currentId!==Kn}clear=()=>{this.currentId!==Kn&&(clearTimeout(this.currentId),this.currentId=Kn)};disposeEffect=()=>this.clear};function vr(){let e=Rt(tr.create).current;return en(e.disposeEffect),e}var _t=h(ge(),1);function yf(e){return"nativeEvent"in e}function Gr(e,t){let r=["mouse","pen"];return t||r.push("",void 0),r.includes(e)}function vf(e){let t=e.type;return t==="click"||t==="mousedown"||t==="keydown"||t==="keyup"}var Ha="data-base-ui-focusable";var Wa="input:not([type='hidden']):not([disabled]),[contenteditable]:not([contenteditable='false']),textarea:not([disabled])";function zs(e){let t=e.activeElement;for(;t?.shadowRoot?.activeElement!=null;)t=t.shadowRoot.activeElement;return t}function Ze(e,t){if(!e||!t)return!1;let r=t.getRootNode?.();if(e.contains(t))return!0;if(r&&rn(r)){let o=t;for(;o;){if(e===o)return!0;o=o.parentNode||o.host}}return!1}function Nt(e){return"composedPath"in e?e.composedPath()[0]:e.target}function ao(e,t){if(!Se(e))return!1;let r=e;if(t.hasElement(r))return!r.hasAttribute("data-trigger-disabled");for(let[,o]of t.entries())if(Ze(o,r))return!o.hasAttribute("data-trigger-disabled");return!1}function Us(e,t){if(t==null)return!1;if("composedPath"in e)return e.composedPath().includes(t);let r=e;return r.target!=null&&t.contains(r.target)}function bf(e){return e.matches("html,body")}function wf(e){return Et(e)&&e.matches(Wa)}function Ga(e){return e?.closest(`button,a[href],[role="button"],select,[tabindex]:not([tabindex="-1"]),${Wa}`)!=null}function xf(e){if(!e||Wr.env.jsdom)return!0;try{return e.matches(":focus-visible")}catch{return!0}}function Vb(e,t){return t!=null&&!Gr(t)?0:typeof e=="function"?e():e}function Yr(e,t,r){let o=Vb(e,r);return typeof o=="number"?o:o?.[t]}function Ya(e){return typeof e=="function"?e():e}function Hs(e,t){return t||e==="click"||e==="mousedown"}function Sf(e){return e?.includes("mouse")&&e!=="mousedown"}var Cf=h(Y(),1),Rf=_t.createContext({hasProvider:!1,timeoutMs:0,delayRef:{current:0},initialDelayRef:{current:0},timeout:new tr,currentIdRef:{current:null},currentContextRef:{current:null}});function Bb(e,t){e.current=t.current}function qa(e){let{children:t,delay:r,timeoutMs:o=0}=e,n=_t.useRef(r),s=_t.useRef(r),i=_t.useRef(null),a=_t.useRef(null),u=vr();return ye(()=>{if(s.current=r,!i.current){n.current=r;return}n.current={open:Yr(n.current,"open"),close:Yr(r,"close")}},[r,i,n,s]),(0,Cf.jsx)(Rf.Provider,{value:_t.useMemo(()=>({hasProvider:!0,delayRef:n,initialDelayRef:s,currentIdRef:i,timeoutMs:o,currentContextRef:a,timeout:u}),[o,u]),children:t})}function Za(e,t={open:!1}){let{open:r}=t,o="rootStore"in e?e.rootStore:e,n=o.useState("floatingId"),s=_t.useContext(Rf),{currentIdRef:i,delayRef:a,timeoutMs:u,initialDelayRef:l,currentContextRef:c,hasProvider:f,timeout:m}=s,[g,d]=_t.useState(!1),v=_t.useRef(r),x=_t.useRef(!1);return ye(()=>{v.current=r},[r]),ye(()=>()=>{x.current=!0},[]),ye(()=>{function C(){x.current||d(!1),c.current?.setIsInstantPhase(!1),i.current=null,c.current=null,a.current=l.current,m.clear()}if(i.current&&!r&&i.current===n){if(d(!1),u){let w=n;return m.start(u,()=>{o.select("open")||i.current&&i.current!==w||C()}),()=>{(v.current||i.current!==w)&&m.clear()}}C()}},[r,n,i,a,u,l,c,m,o]),ye(()=>{if(!r)return;let C=c.current,w=i.current;m.clear(),c.current={onOpenChange:o.setOpen,setIsInstantPhase:d},i.current=n,a.current={open:0,close:Yr(l.current,"close")},w!==null&&w!==n?(d(!0),C?.setIsInstantPhase(!0),C?.onOpenChange(!1,je(_e.none))):(d(!1),C?.setIsInstantPhase(!1))},[r,n,o,i,a,l,c,m]),ye(()=>()=>{if(i.current===n){if(c.current=null,!v.current)return;i.current=null,Bb(a,l),m.clear()}},[c,i,a,n,l,m]),_t.useMemo(()=>({hasProvider:f,delayRef:a,isInstantPhase:g}),[f,a,g])}function br(...e){return()=>{for(let t=0;t({x:e,y:e}),jb={left:"right",right:"left",bottom:"top",top:"bottom"};function Gs(e,t,r){return wr(e,lo(t,r))}function xr(e,t){return typeof e=="function"?e(t):e}function Pt(e){return e.split("-")[0]}function Sr(e){return e.split("-")[1]}function Ys(e){return e==="x"?"y":"x"}function $n(e){return e==="y"?"height":"width"}function Gt(e){let t=e[0];return t==="t"||t==="b"?"y":"x"}function es(e){return Ys(Gt(e))}function Pf(e,t,r){r===void 0&&(r=!1);let o=Sr(e),n=es(e),s=$n(n),i=n==="x"?o===(r?"end":"start")?"right":"left":o==="start"?"bottom":"top";return t.reference[s]>t.floating[s]&&(i=Jn(i)),[i,Jn(i)]}function Of(e){let t=Jn(e);return[Ws(e),t,Ws(t)]}function Ws(e){return e.includes("start")?e.replace("start","end"):e.replace("end","start")}var Ef=["left","right"],Tf=["right","left"],zb=["top","bottom"],Ub=["bottom","top"];function Hb(e,t,r){switch(e){case"top":case"bottom":return r?t?Tf:Ef:t?Ef:Tf;case"left":case"right":return t?zb:Ub;default:return[]}}function kf(e,t,r,o){let n=Sr(e),s=Hb(Pt(e),r==="start",o);return n&&(s=s.map(i=>i+"-"+n),t&&(s=s.concat(s.map(Ws)))),s}function Jn(e){let t=Pt(e);return jb[t]+e.slice(t.length)}function Wb(e){var t,r,o,n;return{top:(t=e.top)!=null?t:0,right:(r=e.right)!=null?r:0,bottom:(o=e.bottom)!=null?o:0,left:(n=e.left)!=null?n:0}}function qs(e){return typeof e!="number"?Wb(e):{top:e,right:e,bottom:e,left:e}}function Fo(e){let{x:t,y:r,width:o,height:n}=e;return{width:o,height:n,top:r,left:t,right:t+o,bottom:r+n,x:t,y:r}}function qr(e,t,r=!0){return e.filter(n=>n.parentId===t).flatMap(n=>[...!r||n.context?.open?[n]:[],...qr(e,n.id,r)])}function nn(e){return`data-base-ui-${e}`}var rr=h(ge(),1),If=h(io(),1);var Ff={style:{transition:"none"}};var Gb="data-base-ui-swipe-ignore",Yb="data-swipe-ignore",j_=`[${Gb}]`,z_=`[${Yb}]`;var Af={fallbackAxisSide:"end"};var Lf=h(Y(),1),qb=rr.createContext(null),Zb=()=>rr.useContext(qb),Xb=nn("portal");function Xa(e={}){let{ref:t,container:r,componentProps:o=pt,elementProps:n}=e,s=no(),a=Zb()?.portalNode,[u,l]=rr.useState(null),[c,f]=rr.useState(null),m=Te(x=>{x!==null&&f(x)}),g=rr.useRef(null);ye(()=>{if(r===null){g.current&&(g.current=null,f(null),l(null));return}if(s==null)return;let x=(r&&(Ds(r)?r:r.current))??a??document.body;if(x==null){g.current&&(g.current=null,f(null),l(null));return}g.current!==x&&(g.current=x,f(null),l(x))},[r,a,s]);let d=Ht("div",o,{ref:[t,m],props:[{id:s,[Xb]:""},n]});return{portalNode:c,portalSubtree:u&&d?If.createPortal(d,u):null}}var Ao=h(ge(),1);function Nf(){let e=new Map;return{emit(t,r){e.get(t)?.forEach(o=>o(r))},on(t,r){e.has(t)||e.set(t,new Set),e.get(t).add(r)},off(t,r){e.get(t)?.delete(r)}}}var Kb=h(Y(),1),Jb=Ao.createContext(null),Qb=Ao.createContext(null),sn=()=>Ao.useContext(Jb)?.id||null,uo=e=>{let t=Ao.useContext(Qb);return e??t};var Yt=h(ge(),1);function $b(e,t){let r=null,o=null,n=!1;return{contextElement:e||void 0,getBoundingClientRect(){let s=e?.getBoundingClientRect()||{width:0,height:0,x:0,y:0},i=t.axis==="x"||t.axis==="both",a=t.axis==="y"||t.axis==="both",u=["mouseenter","mousemove"].includes(t.dataRef.current.openEvent?.type||"")&&t.pointerType!=="touch",l=s.width,c=s.height,f=s.x,m=s.y;return r==null&&t.x&&i&&(r=s.x-t.x),o==null&&t.y&&a&&(o=s.y-t.y),f-=r||0,m-=o||0,l=0,c=0,!n||u?(l=t.axis==="y"?s.width:0,c=t.axis==="x"?s.height:0,f=i&&t.x!=null?t.x:f,m=a&&t.y!=null?t.y:m):n&&!u&&(c=t.axis==="x"?s.height:c,l=t.axis==="y"?s.width:l),n=!0,{width:l,height:c,x:f,y:m,top:m,right:f+l,bottom:m+c,left:f}}}}function Df(e){return e!=null&&e.clientX!=null}function Ka(e,t={}){let{enabled:r=!0,axis:o="both"}=t,n="rootStore"in e?e.rootStore:e,s=n.useState("open"),i=n.useState("floatingElement"),a=n.useState("domReferenceElement"),u=n.context.dataRef,l=Yt.useRef(!1),c=Yt.useRef(null),[f,m]=Yt.useState(),[g,d]=Yt.useState([]),v=Te(R=>{n.set("positionReference",R)}),x=Te((R,A,T)=>{l.current||u.current.openEvent&&!Df(u.current.openEvent)||n.set("positionReference",$b(T??a,{x:R,y:A,axis:o,dataRef:u,pointerType:f}))}),C=Te(R=>{s?c.current||(x(R.clientX,R.clientY,R.currentTarget),d([])):x(R.clientX,R.clientY,R.currentTarget)}),w=Gr(f)?i:s;Yt.useEffect(()=>{if(!r){v(a);return}if(!w)return;function R(){c.current?.(),c.current=null}let A=it(i);function T(_){let P=Nt(_);Ze(i,P)?R():x(_.clientX,_.clientY)}return!u.current.openEvent||Df(u.current.openEvent)?c.current=Ye(A,"mousemove",T):v(a),R},[w,r,i,u,a,n,x,v,g]),Yt.useEffect(()=>()=>{n.set("positionReference",null)},[n]),Yt.useEffect(()=>{r&&!i&&(l.current=!1)},[r,i]),Yt.useEffect(()=>{!r&&s&&(l.current=!0)},[r,s]);let b=Yt.useMemo(()=>{function R(A){m(A.pointerType)}return{onPointerDown:R,onPointerEnter:R,onMouseMove:C,onMouseEnter:C}},[C]);return Yt.useMemo(()=>r?{reference:b,trigger:b}:{},[r,b])}var qt=h(ge(),1);function e0(){return!1}function t0(e){return{escapeKey:typeof e=="boolean"?e:e?.escapeKey??!1,outsidePress:typeof e=="boolean"?e:e?.outsidePress??!0}}function Ja(e,t={}){let{enabled:r=!0,escapeKey:o=!0,outsidePress:n=!0,outsidePressEvent:s="sloppy",referencePress:i=e0,bubbles:a,externalTree:u}=t,l="rootStore"in e?e.rootStore:e,c=l.useState("open"),f=l.useState("floatingElement"),{dataRef:m}=l.context,g=uo(u),d=Te(typeof n=="function"?n:()=>!1),v=typeof n=="function"?d:n,x=v!==!1,C=Te(()=>s),{escapeKey:w,outsidePress:b}=t0(a),R=qt.useRef(!1),A=qt.useRef(!1),T=qt.useRef(!1),_=qt.useRef(!1),P=qt.useRef(""),N=qt.useRef(null),q=vr(),H=vr(),S=Te(()=>{H.clear(),m.current.insideReactTree=!1}),I=Te(F=>{let Z=m.current.floatingContext?.nodeId;return(g?qr(g.nodesRef.current,Z):[]).some(we=>we.context?.open&&!we.context.dataRef.current[F])}),W=Te(F=>Us(F,l.select("floatingElement"))||Us(F,l.select("domReferenceElement"))),O=Te(F=>{i()&&l.setOpen(!1,je(_e.triggerPress,F.nativeEvent))}),D=Te(F=>{if(!c||!r||!o||F.key!=="Escape"||_.current||!w&&I("__escapeKeyBubbles"))return;let Z=yf(F)?F.nativeEvent:F,se=je(_e.escapeKey,Z);l.setOpen(!1,se),se.isCanceled||F.preventDefault(),!w&&!se.isPropagationAllowed&&F.stopPropagation()}),J=Te(()=>{m.current.insideReactTree=!0,H.start(0,S)}),M=Te(F=>{if(!c||!r||F.button!==0)return;let Z=Nt(F.nativeEvent);Ze(l.select("floatingElement"),Z)&&(R.current||(R.current=!0,A.current=!1))}),E=Te(F=>{!c||!r||(F.defaultPrevented||F.nativeEvent.defaultPrevented)&&R.current&&(A.current=!0)});qt.useEffect(()=>{if(!c||!r)return;m.current.__escapeKeyBubbles=w,m.current.__outsidePressBubbles=b;let F=new tr,Z=new tr;function se(){F.clear(),_.current=!0}function we(){F.start(Wr.engine.webkit?5:0,()=>{_.current=!1})}function ie(){T.current=!0,Z.start(0,()=>{T.current=!1})}function ve(){R.current=!1,A.current=!1}function Ee(){let V=P.current,re=V==="pen"||!V?"mouse":V,Ne=C(),He=typeof Ne=="function"?Ne():Ne;return typeof He=="string"?He:He[re]}function ee(V){let re=Ee();return re==="intentional"&&V.type!=="click"||re==="sloppy"&&V.type==="click"}function Fe(V){let re=m.current.floatingContext?.nodeId,Ne=g&&qr(g.nodesRef.current,re).some(He=>Us(V,He.context?.elements.floating));return W(V)||Ne}function Ae(V){if(ee(V)){V.type!=="click"&&!W(V)&&(Z.clear(),T.current=!1),S();return}if(m.current.insideReactTree){S();return}let re=Nt(V),Ne=`[${nn("inert")}]`,He=Se(re)?re.getRootNode():null,ot=Array.from((rn(He)?He:xt(l.select("floatingElement"))).querySelectorAll(Ne)),ut=l.context.triggerElements;if(re&&(ut.hasElement(re)||ut.hasMatchingElement(We=>Ze(We,re))))return;let ze=Se(re)?re:null;for(;ze&&!Pr(ze);){let We=Tr(ze);if(Pr(We)||!Se(We))break;ze=We}if(!(ot.length&&Se(re)&&!bf(re)&&!Ze(re,l.select("floatingElement"))&&ot.every(We=>!Ze(ze,We)))){if(Et(re)&&!("touches"in V)){let We=Pr(re),nt=Lt(re),be=/auto|scroll/,Rr=We||be.test(nt.overflowX),gr=We||be.test(nt.overflowY),$e=Rr&&re.clientWidth>0&&re.scrollWidth>re.clientWidth,jr=gr&&re.clientHeight>0&&re.scrollHeight>re.clientHeight,Ct=nt.direction==="rtl",Le=jr&&(Ct?V.offsetX<=re.offsetWidth-re.clientWidth:V.offsetX>re.clientWidth),qe=$e&&V.offsetY>re.clientHeight;if(Le||qe)return}if(!Fe(V)){if(Ee()==="intentional"&&T.current){Z.clear(),T.current=!1;return}typeof v=="function"&&!v(V)||I("__outsidePressBubbles")||(l.setOpen(!1,je(_e.outsidePress,V)),S())}}}function Oe(V){Ee()!=="sloppy"||V.pointerType==="touch"||!l.select("open")||!r||W(V)||Ae(V)}function Ue(V){if(Ee()!=="sloppy"||!l.select("open")||!r||W(V))return;let re=V.touches[0];re&&(N.current={startTime:Date.now(),startX:re.clientX,startY:re.clientY,dismissOnTouchEnd:!1,dismissOnMouseDown:!0},q.start(1e3,()=>{N.current&&(N.current.dismissOnTouchEnd=!1,N.current.dismissOnMouseDown=!1)}))}function G(V,re){let Ne=Nt(V);if(!Ne)return;let He=Ye(Ne,V.type,()=>{re(V),He()})}function z(V){P.current="touch",G(V,Ue)}function X(V){q.clear(),V.type==="pointerdown"&&(P.current=V.pointerType),!(V.type==="mousedown"&&N.current&&!N.current.dismissOnMouseDown)&&G(V,re=>{re.type==="pointerdown"?Oe(re):Ae(re)})}function U(V){if(!R.current)return;let re=A.current;if(ve(),Ee()==="intentional"){if(V.type==="pointercancel"){re&&ie();return}if(!Fe(V)){if(re){ie();return}typeof v=="function"&&!v(V)||(Z.clear(),T.current=!0,S())}}}function K(V){if(Ee()!=="sloppy"||!N.current||W(V))return;let re=V.touches[0];if(!re)return;let Ne=Math.abs(re.clientX-N.current.startX),He=Math.abs(re.clientY-N.current.startY),ot=Math.sqrt(Ne*Ne+He*He);ot>5&&(N.current.dismissOnTouchEnd=!0),ot>10&&(Ae(V),q.clear(),N.current=null)}function fe(V){G(V,K)}function ue(V){Ee()!=="sloppy"||!N.current||W(V)||(N.current.dismissOnTouchEnd&&Ae(V),q.clear(),N.current=null)}function de(V){G(V,ue)}let pe=xt(f),me=br(o&&br(Ye(pe,"keydown",D),Ye(pe,"compositionstart",se),Ye(pe,"compositionend",we)),x&&br(Ye(pe,"click",X,!0),Ye(pe,"pointerdown",X,!0),Ye(pe,"pointerup",U,!0),Ye(pe,"pointercancel",U,!0),Ye(pe,"mousedown",X,!0),Ye(pe,"mouseup",U,!0),Ye(pe,"touchstart",z,!0),Ye(pe,"touchmove",fe,!0),Ye(pe,"touchend",de,!0)));return()=>{me(),F.clear(),Z.clear(),ve(),T.current=!1}},[m,f,o,x,v,c,r,w,b,D,S,C,I,W,g,l,q]),qt.useEffect(S,[v,S]);let L=qt.useMemo(()=>({onKeyDown:D,onPointerDown:O,onClick:O}),[D,O]),$=qt.useMemo(()=>({onKeyDown:D,onPointerDown:E,onMouseDown:E,onClickCapture:J,onMouseDownCapture(F){J(),M(F)},onPointerDownCapture(F){J(),M(F)},onMouseUpCapture:J,onTouchEndCapture:J,onTouchMoveCapture:J}),[D,J,M,E]);return qt.useMemo(()=>r?{reference:L,floating:$,trigger:L}:{},[r,L,$])}var Ot=h(ge(),1);function Mf(e,t,r){let{reference:o,floating:n}=e,s=Gt(t),i=es(t),a=$n(i),u=Pt(t),l=s==="y",c=o.x+o.width/2-n.width/2,f=o.y+o.height/2-n.height/2,m=o[a]/2-n[a]/2,g;switch(u){case"top":g={x:c,y:o.y-n.height};break;case"bottom":g={x:c,y:o.y+o.height};break;case"right":g={x:o.x+o.width,y:f};break;case"left":g={x:o.x-n.width,y:f};break;default:g={x:o.x,y:o.y}}let d=Sr(t);return d&&(g[i]+=m*(d==="end"?1:-1)*(r&&l?-1:1)),g}async function jf(e,t){var r;t===void 0&&(t={});let{x:o,y:n,platform:s,rects:i,elements:a,strategy:u}=e,{boundary:l="clippingAncestors",rootBoundary:c="viewport",elementContext:f="floating",altBoundary:m=!1,padding:g=0}=xr(t,e),d=qs(g),x=a[m?f==="floating"?"reference":"floating":f],C=Fo(await s.getClippingRect({element:(r=await(s.isElement==null?void 0:s.isElement(x)))==null||r?x:x.contextElement||await(s.getDocumentElement==null?void 0:s.getDocumentElement(a.floating)),boundary:l,rootBoundary:c,strategy:u})),w=f==="floating"?{x:o,y:n,width:i.floating.width,height:i.floating.height}:i.reference,b=await(s.getOffsetParent==null?void 0:s.getOffsetParent(a.floating)),R=await(s.isElement==null?void 0:s.isElement(b))&&await(s.getScale==null?void 0:s.getScale(b))||{x:1,y:1},A=Fo(s.convertOffsetParentRelativeRectToViewportRelativeRect?await s.convertOffsetParentRelativeRectToViewportRelativeRect({elements:a,rect:w,offsetParent:b,strategy:u}):w);return{top:(C.top-A.top+d.top)/R.y,bottom:(A.bottom-C.bottom+d.bottom)/R.y,left:(C.left-A.left+d.left)/R.x,right:(A.right-C.right+d.right)/R.x}}var r0=50,zf=async(e,t,r)=>{let{placement:o="bottom",strategy:n="absolute",middleware:s=[],platform:i}=r,a=i.detectOverflow?i:{...i,detectOverflow:jf},u=await(i.isRTL==null?void 0:i.isRTL(t)),l=await i.getElementRects({reference:e,floating:t,strategy:n}),{x:c,y:f}=Mf(l,o,u),m=o,g=0,d={};for(let v=0;vW<=0)){var H,S;let W=(((H=s.flip)==null?void 0:H.index)||0)+1,O=_[W];if(O&&(!(f==="alignment"?w!==Gt(O):!1)||q.every(M=>Gt(M.placement)===w?M.overflows[0]>0:!0)))return{data:{index:W,overflows:q},reset:{placement:O}};let D=(S=q.filter(J=>J.overflows[0]<=0).sort((J,M)=>J.overflows[1]-M.overflows[1])[0])==null?void 0:S.placement;if(!D)switch(g){case"bestFit":{var I;let J=(I=q.filter(M=>{if(T){let E=Gt(M.placement);return E===w||E==="y"}return!0}).map(M=>[M.placement,M.overflows.filter(E=>E>0).reduce((E,L)=>E+L,0)]).sort((M,E)=>M[1]-E[1])[0])==null?void 0:I[0];J&&(D=J);break}case"initialPlacement":D=a;break}if(n!==D)return{reset:{placement:D}}}return{}}}};function Vf(e,t){return{top:e.top-t.height,right:e.right-t.width,bottom:e.bottom-t.height,left:e.left-t.width}}function Bf(e){return _f.some(t=>e[t]>=0)}var Hf=function(e){return e===void 0&&(e={}),{name:"hide",options:e,async fn(t){let{rects:r,platform:o}=t,{strategy:n="referenceHidden",...s}=xr(e,t);switch(n){case"referenceHidden":{let i=await o.detectOverflow(t,{...s,elementContext:"reference"}),a=Vf(i,r.reference);return{data:{referenceHiddenOffsets:a,referenceHidden:Bf(a)}}}case"escaped":{let i=await o.detectOverflow(t,{...s,altBoundary:!0}),a=Vf(i,r.floating);return{data:{escapedOffsets:a,escaped:Bf(a)}}}default:return{}}}}};var Wf=new Set(["left","top"]);async function o0(e,t){let{placement:r,platform:o,elements:n}=e,s=await(o.isRTL==null?void 0:o.isRTL(n.floating)),i=Pt(r),a=Sr(r),u=Gt(r)==="y",l=Wf.has(i)?-1:1,c=s&&u?-1:1,f=xr(t,e),{mainAxis:m,crossAxis:g,alignmentAxis:d}=typeof f=="number"?{mainAxis:f,crossAxis:0,alignmentAxis:null}:{mainAxis:f.mainAxis||0,crossAxis:f.crossAxis||0,alignmentAxis:f.alignmentAxis};return a&&typeof d=="number"&&(g=a==="end"?d*-1:d),u?{x:g*c,y:m*l}:{x:m*l,y:g*c}}var Gf=function(e){return e===void 0&&(e=0),{name:"offset",options:e,async fn(t){var r,o;let{x:n,y:s,placement:i,middlewareData:a}=t,u=await o0(t,e);return i===((r=a.offset)==null?void 0:r.placement)&&(o=a.arrow)!=null&&o.alignmentOffset?{}:{x:n+u.x,y:s+u.y,data:{...u,placement:i}}}}},Yf=function(e){return e===void 0&&(e={}),{name:"shift",options:e,async fn(t){let{x:r,y:o,placement:n,platform:s}=t,{mainAxis:i=!0,crossAxis:a=!1,limiter:u={fn:w=>{let{x:b,y:R}=w;return{x:b,y:R}}},...l}=xr(e,t),c={x:r,y:o},f=await s.detectOverflow(t,l),m=Gt(n),g=Ys(m),d=c[g],v=c[m],x=(w,b)=>Gs(b+f[w==="y"?"top":"left"],b,b-f[w==="y"?"bottom":"right"]);i&&(d=x(g,d)),a&&(v=x(m,v));let C=u.fn({...t,[g]:d,[m]:v});return{...C,data:{x:C.x-r,y:C.y-o,enabled:{[g]:i,[m]:a}}}}}},qf=function(e){return e===void 0&&(e={}),{options:e,fn(t){var r,o;let{x:n,y:s,placement:i,rects:a,middlewareData:u}=t,{offset:l=0,mainAxis:c=!0,crossAxis:f=!0}=xr(e,t),m={x:n,y:s},g=Gt(i),d=Ys(g),v=m[d],x=m[g],C=xr(l,t),w=typeof C=="number"?{mainAxis:C,crossAxis:0}:{mainAxis:(r=C.mainAxis)!=null?r:0,crossAxis:(o=C.crossAxis)!=null?o:0};if(c){let A=d==="y"?"height":"width",T=a.reference[d]-a.floating[A]+w.mainAxis,_=a.reference[d]+a.reference[A]-w.mainAxis;v_&&(v=_)}if(f){var b,R;let A=d==="y"?"width":"height",T=Wf.has(Pt(i)),_=a.reference[g]-a.floating[A]+(T&&((b=u.offset)==null?void 0:b[g])||0)+(T?0:w.crossAxis),P=a.reference[g]+a.reference[A]+(T?0:((R=u.offset)==null?void 0:R[g])||0)-(T?w.crossAxis:0);x<_?x=_:x>P&&(x=P)}return{[d]:v,[g]:x}}}},Zf=function(e){return e===void 0&&(e={}),{name:"size",options:e,async fn(t){let{placement:r,rects:o,platform:n,elements:s}=t,{apply:i=()=>{},...a}=xr(e,t),u=await n.detectOverflow(t,a),l=Pt(r),c=Sr(r),f=Gt(r)==="y",{width:m,height:g}=o.floating,d,v;l==="top"||l==="bottom"?(d=l,v=c===(await(n.isRTL==null?void 0:n.isRTL(s.floating))?"start":"end")?"left":"right"):(v=l,d=c==="end"?"top":"bottom");let x=g-u.top-u.bottom,C=m-u.left-u.right,w=lo(g-u[d],x),b=lo(m-u[v],C),R=t.middlewareData.shift,A=!R,T=w,_=b;R!=null&&R.enabled.x&&(_=C),R!=null&&R.enabled.y&&(T=x),A&&!c&&(f?_=m-2*wr(u.left,u.right):T=g-2*wr(u.top,u.bottom)),await i({...t,availableWidth:_,availableHeight:T});let P=await n.getDimensions(s.floating);return m!==P.width||g!==P.height?{reset:{rects:!0}}:{}}}};function Jf(e){let t=Lt(e),r=parseFloat(t.width)||0,o=parseFloat(t.height)||0,n=Et(e),s=n?e.offsetWidth:r,i=n?e.offsetHeight:o,a=co(r)!==s||co(o)!==i;return a&&(r=s,o=i),{width:r,height:o,$:a}}function $a(e){return Se(e)?e:e.contextElement}function an(e){let t=$a(e);if(!Et(t))return Or(1);let r=t.getBoundingClientRect(),{width:o,height:n,$:s}=Jf(t),i=(s?co(r.width):r.width)/o,a=(s?co(r.height):r.height)/n;return(!i||!Number.isFinite(i))&&(i=1),(!a||!Number.isFinite(a))&&(a=1),{x:i,y:a}}var n0=Or(0);function Qf(e){let t=it(e);return!Vs()||!t.visualViewport?n0:{x:t.visualViewport.offsetLeft,y:t.visualViewport.offsetTop}}function s0(e,t,r){return t===void 0&&(t=!1),!!r&&t&&r===it(e)}function Io(e,t,r,o){t===void 0&&(t=!1),r===void 0&&(r=!1);let n=e.getBoundingClientRect(),s=$a(e),i=Or(1);t&&(o?Se(o)&&(i=an(o)):i=an(e));let a=s0(s,r,o)?Qf(s):Or(0),u=(n.left+a.x)/i.x,l=(n.top+a.y)/i.y,c=n.width/i.x,f=n.height/i.y;if(s&&o){let m=it(s),g=Se(o)?it(o):o,d=m,v=Bs(d);for(;v&&g!==d;){let x=an(v),C=v.getBoundingClientRect(),w=Lt(v),b=C.left+(v.clientLeft+parseFloat(w.paddingLeft))*x.x,R=C.top+(v.clientTop+parseFloat(w.paddingTop))*x.y;u*=x.x,l*=x.y,c*=x.x,f*=x.y,u+=b,l+=R,d=it(v),v=Bs(d)}}return Fo({width:c,height:f,x:u,y:l})}function Zs(e,t){let r=Xn(e).scrollLeft;return t?t.left+r:Io(_r(e)).left+r}function $f(e,t){let r=e.getBoundingClientRect(),o=r.left+t.scrollLeft-Zs(e,r),n=r.top+t.scrollTop;return{x:o,y:n}}function i0(e){let{elements:t,rect:r,offsetParent:o,strategy:n}=e,s=n==="fixed",i=_r(o),a=t?Zn(t.floating):!1;if(o===i||a&&s)return r;let u={scrollLeft:0,scrollTop:0},l=Or(1),c=Or(0),f=Et(o);if((f||!s)&&((Po(o)!=="body"||qn(i))&&(u=Xn(o)),f)){let g=Io(o);l=an(o),c.x=g.x+o.clientLeft,c.y=g.y+o.clientTop}let m=i&&!f&&!s?$f(i,u):Or(0);return{width:r.width*l.x,height:r.height*l.y,x:r.x*l.x-u.scrollLeft*l.x+c.x+m.x,y:r.y*l.y-u.scrollTop*l.y+c.y+m.y}}function a0(e){return e.getClientRects?Array.from(e.getClientRects()):[]}function l0(e){let t=Xn(e),r=e.ownerDocument.body,o=wr(e.scrollWidth,e.clientWidth,r.scrollWidth,r.clientWidth),n=wr(e.scrollHeight,e.clientHeight,r.scrollHeight,r.clientHeight),s=-t.scrollLeft+Zs(e),i=-t.scrollTop;return Lt(r).direction==="rtl"&&(s+=wr(e.clientWidth,r.clientWidth)-o),{width:o,height:n,x:s,y:i}}var c0=25;function u0(e,t,r){r===void 0&&(r="viewport");let o=r==="layoutViewport",n=it(e),s=_r(e),i=n.visualViewport,a=s.clientWidth,u=s.clientHeight,l=0,c=0;if(i){let m=!Vs()||t==="fixed";o?m||(l=-i.offsetLeft,c=-i.offsetTop):(a=i.width,u=i.height,m&&(l=i.offsetLeft,c=i.offsetTop))}if(Zs(s)<=0){let m=s.ownerDocument,g=m.body,d=getComputedStyle(g),v=m.compatMode==="CSS1Compat"&&parseFloat(d.marginLeft)+parseFloat(d.marginRight)||0,x=Math.abs(s.clientWidth-g.clientWidth-v),C=getComputedStyle(s).scrollbarGutter==="stable both-edges"?x/2:x;C<=c0&&(a-=C)}return{width:a,height:u,x:l,y:c}}function f0(e,t){let r=Io(e,!0,t==="fixed"),o=r.top+e.clientTop,n=r.left+e.clientLeft,s=an(e),i=e.clientWidth*s.x,a=e.clientHeight*s.y,u=n*s.x,l=o*s.y;return{width:i,height:a,x:u,y:l}}function Xf(e,t,r){let o;if(t==="viewport"||t==="layoutViewport")o=u0(e,r,t);else if(t==="document")o=l0(_r(e));else if(Se(t))o=f0(t,r);else{let n=Qf(e);o={x:t.x-n.x,y:t.y-n.y,width:t.width,height:t.height}}return Fo(o)}function d0(e,t){let r=t.get(e);if(r)return r;let o=so(e,[],!1).filter(a=>Se(a)&&Po(a)!=="body"),n=null,s=Lt(e).position==="fixed",i=s?Tr(e):e;for(;Se(i)&&!Pr(i);){let a=Lt(i),u=Ms(i),l=n?n.position:s?"fixed":"";!u&&(l==="fixed"||l==="absolute"&&a.position==="static")?o=o.filter(f=>f!==i):n=a,i=Tr(i)}return t.set(e,o),o}function p0(e){let{element:t,boundary:r,rootBoundary:o,strategy:n}=e,i=[...r==="clippingAncestors"?Zn(t)?[]:d0(t,this._c):[].concat(r),o],a=Xf(t,i[0],n),u=a.top,l=a.right,c=a.bottom,f=a.left;for(let m=1;m{a(!1,1e-7)},1e3)}_=!1}try{o=new IntersectionObserver(P,{...T,root:s.ownerDocument})}catch{o=new IntersectionObserver(P,T)}o.observe(e)}let u=it(e),l=()=>a(r);return u.addEventListener("resize",l),a(!0),()=>{u.removeEventListener("resize",l),i()}}function ts(e,t,r,o){o===void 0&&(o={});let{ancestorScroll:n=!0,ancestorResize:s=!0,elementResize:i=typeof ResizeObserver=="function",layoutShift:a=typeof IntersectionObserver=="function",animationFrame:u=!1}=o,l=$a(e),c=n||s?[...l?so(l):[],...t?so(t):[]]:[];c.forEach(C=>{n&&C.addEventListener("scroll",r),s&&C.addEventListener("resize",r)});let f=l&&a?v0(l,r,s):null,m=-1,g=null;i&&(g=new ResizeObserver(C=>{let[w]=C;w&&w.target===l&&g&&t&&(g.unobserve(t),cancelAnimationFrame(m),m=requestAnimationFrame(()=>{var b;(b=g)==null||b.observe(t)})),r()}),l&&!u&&g.observe(l),t&&g.observe(t));let d,v=u?Io(e):null;u&&x();function x(){let C=Io(e);v&&!td(v,C)&&r(),v=C,d=requestAnimationFrame(x)}return r(),()=>{var C;c.forEach(w=>{n&&w.removeEventListener("scroll",r),s&&w.removeEventListener("resize",r)}),f?.(),(C=g)==null||C.disconnect(),g=null,u&&cancelAnimationFrame(d)}}var rd=Gf;var od=Yf,nd=Uf,sd=Zf,id=Hf;var ad=qf,Xs=(e,t,r)=>{let o=new Map,n=r??{},s={...el,...n.platform,_c:o};return zf(e,t,{...n,platform:s})};var yt=h(ge(),1),cd=h(ge(),1),ud=h(io(),1),w0=typeof document<"u",x0=function(){},Ks=w0?cd.useLayoutEffect:x0;function Js(e,t){if(e===t)return!0;if(typeof e!=typeof t)return!1;if(typeof e=="function"&&e.toString()===t.toString())return!0;let r,o,n;if(e&&t&&typeof e=="object"){if(Array.isArray(e)){if(r=e.length,r!==t.length)return!1;for(o=r;o--!==0;)if(!Js(e[o],t[o]))return!1;return!0}if(n=Object.keys(e),r=n.length,r!==Object.keys(t).length)return!1;for(o=r;o--!==0;)if(!{}.hasOwnProperty.call(t,n[o]))return!1;for(o=r;o--!==0;){let s=n[o];if(!(s==="_owner"&&e.$$typeof)&&!Js(e[s],t[s]))return!1}return!0}return e!==e&&t!==t}function fd(e){return typeof window>"u"?1:(e.ownerDocument.defaultView||window).devicePixelRatio||1}function ld(e,t){let r=fd(e);return Math.round(t*r)/r}function tl(e){let t=yt.useRef(e);return Ks(()=>{t.current=e}),t}function dd(e){e===void 0&&(e={});let{placement:t="bottom",strategy:r="absolute",middleware:o=[],platform:n,elements:{reference:s,floating:i}={},transform:a=!0,whileElementsMounted:u,open:l}=e,[c,f]=yt.useState({x:0,y:0,strategy:r,placement:t,middlewareData:{},isPositioned:!1}),[m,g]=yt.useState(o);Js(m,o)||g(o);let[d,v]=yt.useState(null),[x,C]=yt.useState(null),w=yt.useCallback(M=>{M!==T.current&&(T.current=M,v(M))},[]),b=yt.useCallback(M=>{M!==_.current&&(_.current=M,C(M))},[]),R=s||d,A=i||x,T=yt.useRef(null),_=yt.useRef(null),P=yt.useRef(c),N=u!=null,q=tl(u),H=tl(n),S=tl(l),I=yt.useCallback(()=>{if(!T.current||!_.current)return;let M={placement:t,strategy:r,middleware:m};H.current&&(M.platform=H.current),Xs(T.current,_.current,M).then(E=>{let L={...E,isPositioned:S.current!==!1};W.current&&!Js(P.current,L)&&(P.current=L,ud.flushSync(()=>{f(L)}))})},[m,t,r,H,S]);Ks(()=>{l===!1&&P.current.isPositioned&&(P.current.isPositioned=!1,f(M=>({...M,isPositioned:!1})))},[l]);let W=yt.useRef(!1);Ks(()=>(W.current=!0,()=>{W.current=!1}),[]),Ks(()=>{if(R&&(T.current=R),A&&(_.current=A),R&&A){if(q.current)return q.current(R,A,I);I()}},[R,A,I,q,N]);let O=yt.useMemo(()=>({reference:T,floating:_,setReference:w,setFloating:b}),[w,b]),D=yt.useMemo(()=>({reference:R,floating:A}),[R,A]),J=yt.useMemo(()=>{let M={position:r,left:0,top:0};if(!D.floating)return M;let E=ld(D.floating,c.x),L=ld(D.floating,c.y);return a?{...M,transform:"translate("+E+"px, "+L+"px)",...fd(D.floating)>=1.5&&{willChange:"transform"}}:{position:r,left:E,top:L}},[r,a,D.floating,c.x,c.y]);return yt.useMemo(()=>({...c,update:I,refs:O,elements:D,floatingStyles:J}),[c,I,O,D,J])}var rl=(e,t)=>{let r=rd(e);return{name:r.name,fn:r.fn,options:[e,t]}},ol=(e,t)=>{let r=od(e);return{name:r.name,fn:r.fn,options:[e,t]}},nl=(e,t)=>({fn:ad(e).fn,options:[e,t]}),sl=(e,t)=>{let r=nd(e);return{name:r.name,fn:r.fn,options:[e,t]}},il=(e,t)=>{let r=sd(e);return{name:r.name,fn:r.fn,options:[e,t]}};var al=(e,t)=>{let r=id(e);return{name:r.name,fn:r.fn,options:[e,t]}};var un=h(ge(),1),Pd=h(io(),1);var Td=h(ge(),1);var De=(e,t,r,o,n,s,...i)=>{if(i.length>0)throw new Error(Ut(1));let a;if(e&&t&&r&&o&&n&&s)a=(u,l,c,f)=>{let m=e(u,l,c,f),g=t(u,l,c,f),d=r(u,l,c,f),v=o(u,l,c,f),x=n(u,l,c,f);return s(m,g,d,v,x,l,c,f)};else if(e&&t&&r&&o&&n)a=(u,l,c,f)=>{let m=e(u,l,c,f),g=t(u,l,c,f),d=r(u,l,c,f),v=o(u,l,c,f);return n(m,g,d,v,l,c,f)};else if(e&&t&&r&&o)a=(u,l,c,f)=>{let m=e(u,l,c,f),g=t(u,l,c,f),d=r(u,l,c,f);return o(m,g,d,l,c,f)};else if(e&&t&&r)a=(u,l,c,f)=>{let m=e(u,l,c,f),g=t(u,l,c,f);return r(m,g,l,c,f)};else if(e&&t)a=(u,l,c,f)=>{let m=e(u,l,c,f);return t(m,l,c,f)};else if(e)a=e;else throw new Error("Missing arguments");return a};var Rd=h(ge(),1),pl=h(cl(),1),Ed=h(bd(),1);var wd=h(ge(),1);var ul=[],fl;function xd(){return fl}function Sd(e){ul.push(e)}function dl(e){let t=(r,o)=>{let n=Rt(B0).current,s;try{fl=n;for(let i of ul)i.before(n);s=e(r,o);for(let i of ul)i.after(n);n.didInitialize=!0}finally{fl=void 0}return s};return t.displayName=e.displayName||e.name,t}function Cd(e){return wd.forwardRef(dl(e))}function B0(){return{didInitialize:!1}}var j0=$o(19),z0=j0?H0:W0;function $s(e,t,r,o,n){return z0(e,t,r,o,n)}function U0(e,t,r,o,n){let s=Rd.useCallback(()=>t(e.getSnapshot(),r,o,n),[e,t,r,o,n]);return(0,pl.useSyncExternalStore)(e.subscribe,s,s)}Sd({before(e){e.syncIndex=0,e.didInitialize||(e.syncTick=1,e.syncHooks=[],e.didChangeStore=!0,e.getSnapshot=()=>{let t=!1;for(let r=0;r0&&(e.didChangeStore&&(e.didChangeStore=!1,e.subscribe=t=>{let r=new Set;for(let n of e.syncHooks)r.add(n.store);let o=[];for(let n of r)o.push(n.subscribe(t));return()=>{for(let n of o)n()}}),(0,pl.useSyncExternalStore)(e.subscribe,e.getSnapshot,e.getSnapshot))}});function H0(e,t,r,o,n){let s=xd();if(!s)return U0(e,t,r,o,n);let i=s.syncIndex;s.syncIndex+=1;let a;return s.didInitialize?(a=s.syncHooks[i],(a.store!==e||a.selector!==t||!Object.is(a.a1,r)||!Object.is(a.a2,o)||!Object.is(a.a3,n))&&(a.store!==e&&(s.didChangeStore=!0),a.store=e,a.selector=t,a.a1=r,a.a2=o,a.a3=n,a.value=t(e.getSnapshot(),r,o,n))):(a={store:e,selector:t,a1:r,a2:o,a3:n,value:t(e.getSnapshot(),r,o,n)},s.syncHooks.push(a)),a.value}function W0(e,t,r,o,n){return(0,Ed.useSyncExternalStoreWithSelector)(e.subscribe,e.getSnapshot,e.getSnapshot,s=>t(s,r,o,n))}var ei=class{constructor(t){this.state=t,this.listeners=new Set,this.updateTick=0}subscribe=t=>(this.listeners.add(t),()=>{this.listeners.delete(t)});getSnapshot=()=>this.state;setState(t){if(this.state===t)return;this.state=t,this.updateTick+=1;let r=this.updateTick;for(let o of this.listeners){if(r!==this.updateTick)return;o(t)}}update(t){for(let r in t)if(!Object.is(this.state[r],t[r])){this.setState({...this.state,...t});return}}set(t,r){Object.is(this.state[t],r)||this.setState({...this.state,[t]:r})}notifyAll(){let t={...this.state};this.setState(t)}use(t,r,o,n){return $s(this,t,r,o,n)}};var Lo=h(ge(),1);var cn=class extends ei{constructor(t,r={},o){super(t),this.context=r,this.selectors=o}useSyncedValue(t,r){Lo.useDebugValue(t);let o=this;ye(()=>{o.state[t]!==r&&o.set(t,r)},[o,t,r])}useSyncedValueWithCleanup(t,r){let o=this;ye(()=>(o.state[t]!==r&&o.set(t,r),()=>{o.set(t,void 0)}),[o,t,r])}useSyncedValues(t){let r=this,o=Object.values(t);ye(()=>{r.update(t)},[r,...o])}useControlledProp(t,r){Lo.useDebugValue(t);let o=this,n=r!==void 0;ye(()=>{n&&!Object.is(o.state[t],r)&&o.setState({...o.state,[t]:r})},[o,t,r,n])}select(t,r,o,n){let s=this.selectors[t];return s(this.state,r,o,n)}useState(t,r,o,n){return Lo.useDebugValue(t),$s(this,this.selectors[t],r,o,n)}useContextCallback(t,r){Lo.useDebugValue(t);let o=Te(r??oo);this.context[t]=o}useStateSetter(t){let r=Lo.useRef(void 0);return r.current===void 0&&(r.current=o=>{this.set(t,o)}),r.current}observe(t,r){let o;typeof t=="function"?o=t:o=this.selectors[t];let n=o(this.state);return r(n,n,this),this.subscribe(s=>{let i=o(s);if(!Object.is(n,i)){let a=n;n=i,r(i,a,this)}})}};var G0={open:De(e=>e.open),transitionStatus:De(e=>e.transitionStatus),domReferenceElement:De(e=>e.domReferenceElement),referenceElement:De(e=>e.positionReference??e.referenceElement),floatingElement:De(e=>e.floatingElement),floatingId:De(e=>e.floatingId)},kr=class extends cn{constructor(t){let{syncOnly:r,nested:o,onOpenChange:n,triggerElements:s,...i}=t;super({...i,positionReference:i.referenceElement,domReferenceElement:i.referenceElement},{onOpenChange:n,dataRef:{current:{}},events:Nf(),nested:o,triggerElements:s},G0),this.syncOnly=r}syncOpenEvent=(t,r)=>{(!t||!this.state.open||r!=null&&vf(r))&&(this.context.dataRef.current.openEvent=t?r:void 0)};dispatchOpenChange=(t,r)=>{this.syncOpenEvent(t,r.event);let o={open:t,reason:r.reason,nativeEvent:r.event,nested:this.context.nested,triggerElement:r.trigger};this.context.events.emit("openchange",o)};setOpen=(t,r)=>{if(this.syncOnly){this.context.onOpenChange?.(t,r);return}this.dispatchOpenChange(t,r),this.context.onOpenChange?.(t,r)}};function _d(e){let{popupStore:t,treatPopupAsFloatingElement:r=!1,floatingRootContext:o,floatingId:n,nested:s,onOpenChange:i}=e,a=t.useState("open"),u=t.useState("activeTriggerElement"),l=t.useState(r?"popupElement":"positionerElement"),c=t.context.triggerElements,f=i,m=Td.useRef(null);o===void 0&&m.current===null&&(m.current=new kr({open:a,transitionStatus:void 0,referenceElement:u,floatingElement:l,triggerElements:c,onOpenChange:f,floatingId:n,syncOnly:!0,nested:s}));let g=o??m.current;return t.useSyncedValue("floatingId",n),ye(()=>{let d={open:a,floatingId:n,referenceElement:u,floatingElement:l};Se(u)&&(d.domReferenceElement=u),g.state.positionReference===g.state.referenceElement&&(d.positionReference=u),g.update(d)},[a,n,u,l,g]),g.context.onOpenChange=f,g.context.nested=s,g}var Od={tabIndex:-1,[Ha]:""};function kd(e,t,r=!1){let o=no(),n=sn()!=null,s=un.useRef(null);e===void 0&&s.current===null&&(s.current=t(o,n));let i=e??s.current;return _d({popupStore:i,treatPopupAsFloatingElement:r,floatingRootContext:i.state.floatingRootContext,floatingId:o,nested:n,onOpenChange:i.setOpen}),{store:i,internalStore:s.current}}function Y0(e,t){let r=un.useRef(null),o=un.useRef(null);return un.useCallback(n=>{if(e===void 0)return;let s=!1;if(r.current!==null){let i=r.current,a=o.current,u=t.context.triggerElements.getById(i);a&&u===a&&(t.context.triggerElements.delete(i),s=!0),r.current=null,o.current=null}if(n!==null&&(r.current=e,o.current=n,t.context.triggerElements.add(e,n),s=!0),s){let i=t.context.triggerElements.size;t.select("open")&&t.state.triggerCount!==i&&t.set("triggerCount",i)}},[t,e])}function q0(e,t,r,o=!1){t?e.preventUnmountingOnClose=!1:o&&(e.preventUnmountingOnClose=!0);let n=r?.id??null;(n||t)&&(e.activeTriggerId=n,e.activeTriggerElement=r??null)}function Z0(e){let t=!1;return e.preventUnmountOnClose=()=>{t=!0},()=>t}function Fd(e,t,r,o={}){let n=r.reason,s=n===_e.triggerHover,i=t&&n===_e.triggerFocus,a=!t&&(n===_e.triggerPress||n===_e.escapeKey),u=Z0(r);if(e.context.onOpenChange?.(t,r),r.isCanceled)return;o.onBeforeDispatch?.(),e.state.floatingRootContext.dispatchOpenChange(t,r);let l=()=>{let c={...o.extraState,open:t};i?c.instantType="focus":a?c.instantType="dismiss":s&&(c.instantType=void 0),q0(c,t,r.trigger,u()),e.update(c)};s?Pd.flushSync(l):l()}function Ad(e,t,r,o){df(()=>{t===void 0&&e.state.open===!1&&r&&(e.state={...e.state,open:!0,activeTriggerId:o,preventUnmountingOnClose:!1})})}function Id(e,t,r,o){let n=r.useState("isMountedByTrigger",e),s=Y0(e,r),i=Te(a=>{if(s(a),!a)return;let u=r.select("open"),l=r.select("activeTriggerId");if(l===e){r.update({activeTriggerElement:a,...u?o:null});return}l==null&&u&&r.update({activeTriggerId:e,activeTriggerElement:a,...o})});return ye(()=>{n&&r.update({activeTriggerElement:t.current,...o})},[n,r,t,...Object.values(o)]),{registerTrigger:i,isMountedByThisTrigger:n}}function Ld(e,t={}){let{closeOnActiveTriggerUnmount:r=!1}=t,o=e.useState("open"),n=e.useState("triggerCount");ye(()=>{if(!o){e.state.triggerCount!==0&&e.set("triggerCount",0);return}let s=e.context.triggerElements.size,i={};e.state.triggerCount!==s&&(i.triggerCount=s);let a=e.select("activeTriggerId"),u=null;if(a){let l=e.context.triggerElements.getById(a);l?l!==e.state.activeTriggerElement&&(i.activeTriggerElement=l):u=a}if(!u&&!a&&s===1){let l=e.context.triggerElements.entries().next();if(!l.done){let[c,f]=l.value;i.activeTriggerId=c,i.activeTriggerElement=f}}(i.triggerCount!==void 0||i.activeTriggerId!==void 0||i.activeTriggerElement!==void 0)&&e.update(i),u&&r&&queueMicrotask(()=>{if(e.select("open")&&e.select("activeTriggerId")===u&&!e.context.triggerElements.getById(u)){let l=je(_e.none);e.setOpen(!1,l),l.isCanceled||e.update({activeTriggerId:null,activeTriggerElement:null})}})},[o,e,n,r])}function Nd(e,t,r){let{mounted:o,setMounted:n,transitionStatus:s}=tf(e),i=t.useState("preventUnmountingOnClose"),a=e?!1:i;t.useSyncedValues({mounted:o,transitionStatus:s,preventUnmountingOnClose:a});let u=Te(()=>{n(!1),t.update({activeTriggerId:null,activeTriggerElement:null,mounted:!1,preventUnmountingOnClose:!1}),r?.(),t.context.onOpenChangeComplete?.(!1)});return js({enabled:o&&!e&&!a,open:e,ref:t.context.popupRef,onComplete(){e||u()}}),{forceUnmount:u,transitionStatus:s}}function Dd(e,t){e.useSyncedValues(t),ye(()=>()=>{e.update({activeTriggerProps:pt,inactiveTriggerProps:pt,popupProps:pt})},[e])}var fo=class{constructor(){this.elementsSet=new Set,this.idMap=new Map}add(t,r){let o=this.idMap.get(t);o!==r&&(o!==void 0&&this.elementsSet.delete(o),this.elementsSet.add(r),this.idMap.set(t,r))}delete(t){let r=this.idMap.get(t);r&&(this.elementsSet.delete(r),this.idMap.delete(t))}hasElement(t){return this.elementsSet.has(t)}hasMatchingElement(t){for(let r of this.elementsSet)if(t(r))return!0;return!1}getById(t){return this.idMap.get(t)}entries(){return this.idMap.entries()}elements(){return this.elementsSet.values()}get size(){return this.idMap.size}};function Md(){return new kr({open:!1,transitionStatus:void 0,floatingElement:null,referenceElement:null,triggerElements:new fo,floatingId:void 0,syncOnly:!1,nested:!1,onOpenChange:void 0})}function Bd(){return{open:!1,openProp:void 0,mounted:!1,transitionStatus:void 0,floatingRootContext:Md(),floatingId:void 0,triggerCount:0,preventUnmountingOnClose:!1,payload:void 0,activeTriggerId:null,activeTriggerElement:null,triggerIdProp:void 0,popupElement:null,positionerElement:null,activeTriggerProps:pt,inactiveTriggerProps:pt,popupProps:pt}}function jd(e,t,r=!1){return new kr({open:!1,transitionStatus:void 0,floatingElement:null,referenceElement:null,triggerElements:e,floatingId:t,syncOnly:!0,nested:r,onOpenChange:void 0})}var rs=De(e=>e.triggerIdProp??e.activeTriggerId),ml=De(e=>e.openProp??e.open),Vd=De(e=>(e.popupElement?.id??e.floatingId)||void 0);function zd(e,t){return t!==void 0&&ml(e)&&rs(e)===t}function X0(e,t){return zd(e,t)?!0:t!==void 0&&ml(e)&&rs(e)==null&&e.triggerCount===1}var Ud={open:ml,mounted:De(e=>e.mounted),transitionStatus:De(e=>e.transitionStatus),floatingRootContext:De(e=>e.floatingRootContext),triggerCount:De(e=>e.triggerCount),preventUnmountingOnClose:De(e=>e.preventUnmountingOnClose),payload:De(e=>e.payload),activeTriggerId:rs,activeTriggerElement:De(e=>e.mounted?e.activeTriggerElement:null),popupId:Vd,isTriggerActive:De((e,t)=>t!==void 0&&rs(e)===t),isOpenedByTrigger:De((e,t)=>zd(e,t)),isMountedByTrigger:De((e,t)=>t!==void 0&&rs(e)===t&&e.mounted),triggerProps:De((e,t)=>t?e.activeTriggerProps:e.inactiveTriggerProps),triggerPopupId:De((e,t)=>X0(e,t)?Vd(e):void 0),popupProps:De(e=>e.popupProps),popupElement:De(e=>e.popupElement),positionerElement:De(e=>e.positionerElement)};function Hd(e){let{open:t=!1,onOpenChange:r,elements:o={}}=e,n=no(),s=sn()!=null,i=Rt(()=>new kr({open:t,transitionStatus:void 0,onOpenChange:r,referenceElement:o.reference??null,floatingElement:o.floating??null,triggerElements:new fo,floatingId:n,syncOnly:!1,nested:s})).current;return ye(()=>{let a={open:t,floatingId:n};o.reference!==void 0&&(a.referenceElement=o.reference,a.domReferenceElement=Se(o.reference)?o.reference:null),o.floating!==void 0&&(a.floatingElement=o.floating),i.update(a)},[t,n,o.reference,o.floating,i]),i.context.onOpenChange=r,i.context.nested=s,i}function hl(e={}){let{nodeId:t,externalTree:r}=e,o=Hd(e),n=e.rootContext||o,s=n.useState("referenceElement"),i=n.useState("floatingElement"),a=n.useState("domReferenceElement"),u=n.useState("open"),l=n.useState("floatingId"),[c,f]=Ot.useState(null),[m,g]=Ot.useState(void 0),[d,v]=Ot.useState(void 0),x=Ot.useRef(null),C=uo(r),w=Ot.useMemo(()=>({reference:s,floating:i,domReference:a}),[s,i,a]),b=dd({...e,elements:{...w,...c&&{reference:c}}}),R=Se(m)?m:null,A=d===void 0?n.state.floatingElement:d;n.useSyncedValue("referenceElement",m??null),n.useSyncedValue("domReferenceElement",m===void 0?a:R),n.useSyncedValue("floatingElement",A);let T=Ot.useCallback(S=>{let I=Se(S)?{getBoundingClientRect:()=>S.getBoundingClientRect(),getClientRects:()=>S.getClientRects(),contextElement:S}:S;f(I),b.refs.setReference(I)},[b.refs]),_=Ot.useCallback(S=>{(Se(S)||S===null)&&(x.current=S,g(S)),(Se(b.refs.reference.current)||b.refs.reference.current===null||S!==null&&!Se(S))&&b.refs.setReference(S)},[b.refs,g]),P=Ot.useCallback(S=>{v(S),b.refs.setFloating(S)},[b.refs]),N=Ot.useMemo(()=>({...b.refs,setReference:_,setFloating:P,setPositionReference:T,domReference:x}),[b.refs,_,P,T]),q=Ot.useMemo(()=>({...b.elements,domReference:a}),[b.elements,a]),H=Ot.useMemo(()=>({...b,dataRef:n.context.dataRef,open:u,onOpenChange:n.setOpen,events:n.context.events,floatingId:l,refs:N,elements:q,nodeId:t,rootStore:n}),[b,N,q,t,n,u,l]);return ye(()=>{a&&(x.current=a)},[a]),ye(()=>{n.context.dataRef.current.floatingContext=H;let S=C?.nodesRef.current.find(I=>I.id===t);S&&(S.context=H)}),Ot.useMemo(()=>({...b,context:H,refs:N,elements:q,rootStore:n}),[b,N,q,H,n])}var Fr=h(ge(),1);var gl=Wr.os.mac&&Wr.engine.webkit;function yl(e,t={}){let{enabled:r=!0,delay:o}=t,n="rootStore"in e?e.rootStore:e,{events:s,dataRef:i}=n.context,a=Fr.useRef(!1),u=Fr.useRef(null),l=Fr.useRef(!0),c=vr();Fr.useEffect(()=>{let m=n.select("domReferenceElement");if(!r)return;let g=it(m);function d(){let C=n.select("domReferenceElement");!n.select("open")&&Et(C)&&C===zs(xt(C))&&(a.current=!0)}function v(){l.current=!0}function x(){l.current=!1}return br(Ye(g,"blur",d),gl&&Ye(g,"keydown",v,!0),gl&&Ye(g,"pointerdown",x,!0))},[n,r]),Fr.useEffect(()=>{if(!r)return;function m(g){if(g.reason===_e.triggerPress||g.reason===_e.escapeKey){let d=n.select("domReferenceElement");Se(d)&&(u.current=d,a.current=!0)}}return s.on("openchange",m),()=>{s.off("openchange",m)}},[s,r,n]);let f=Fr.useMemo(()=>{function m(){a.current=!1,u.current=null}return{onMouseLeave(){m()},onFocus(g){let d=g.currentTarget;if(a.current){if(u.current===d)return;m()}let v=Nt(g.nativeEvent);if(Se(v)){if(gl&&!g.relatedTarget){if(!l.current&&!wf(v))return}else if(!xf(v))return}let x=ao(g.relatedTarget,n.context.triggerElements),{nativeEvent:C,currentTarget:w}=g,b=typeof o=="function"?o():o;if(n.select("open")&&x||b===0||b===void 0){n.setOpen(!0,je(_e.triggerFocus,C,w));return}c.start(b,()=>{a.current||n.setOpen(!0,je(_e.triggerFocus,C,w))})},onBlur(g){m();let d=g.relatedTarget,v=g.nativeEvent,x=Se(d)&&d.hasAttribute(nn("focus-guard"))&&d.getAttribute("data-type")==="outside";c.start(0,()=>{let C=n.select("domReferenceElement"),w=zs(xt(C));!d&&w===C||Ze(i.current.floatingContext?.refs.floating.current,w)||Ze(C,w)||x||ao(d??w,n.context.triggerElements)||n.setOpen(!1,je(_e.triggerFocus,v))})}}},[i,o,n,c]);return Fr.useMemo(()=>r?{reference:f,trigger:f}:{},[r,f])}var bl=h(ge(),1);var vl=class e{constructor(){this.pointerType=void 0,this.interactedInside=!1,this.handler=void 0,this.blockMouseMove=!0,this.performedPointerEventsMutation=!1,this.pointerEventsScopeElement=null,this.pointerEventsReferenceElement=null,this.pointerEventsFloatingElement=null,this.restTimeoutPending=!1,this.openChangeTimeout=new tr,this.restTimeout=new tr,this.handleCloseOptions=void 0}static create(){return new e}dispose=()=>{this.openChangeTimeout.clear(),this.restTimeout.clear()};disposeEffect=()=>this.dispose},ti=new WeakMap;function fn(e){if(!e.performedPointerEventsMutation)return;let t=e.pointerEventsScopeElement;t&&ti.get(t)===e&&(e.pointerEventsScopeElement?.style.removeProperty("pointer-events"),e.pointerEventsReferenceElement?.style.removeProperty("pointer-events"),e.pointerEventsFloatingElement?.style.removeProperty("pointer-events"),ti.delete(t)),e.performedPointerEventsMutation=!1,e.pointerEventsScopeElement=null,e.pointerEventsReferenceElement=null,e.pointerEventsFloatingElement=null}function ri(e,t){let{scopeElement:r,referenceElement:o,floatingElement:n}=t,s=ti.get(r);s&&s!==e&&fn(s),fn(e),e.performedPointerEventsMutation=!0,e.pointerEventsScopeElement=r,e.pointerEventsReferenceElement=o,e.pointerEventsFloatingElement=n,ti.set(r,e),r.style.pointerEvents="none",o.style.pointerEvents="auto",n.style.pointerEvents="auto"}function dn(e){let t=e.context.dataRef.current,r=Rt(()=>t.hoverInteractionState??vl.create()).current;return t.hoverInteractionState||(t.hoverInteractionState=r),en(t.hoverInteractionState.disposeEffect),t.hoverInteractionState}function wl(e,t={}){let{enabled:r=!0,closeDelay:o=0,nodeId:n}=t,s="rootStore"in e?e.rootStore:e,i=s.useState("open"),a=s.useState("floatingElement"),u=s.useState("domReferenceElement"),{dataRef:l}=s.context,c=uo(),f=sn(),m=dn(s),g=vr(),d=Te(()=>Hs(l.current.openEvent?.type,m.interactedInside)),v=Te(()=>Sf(l.current.openEvent?.type)),x=Te(()=>{fn(m)});ye(()=>{i||(m.pointerType=void 0,m.restTimeoutPending=!1,m.interactedInside=!1,x())},[i,m,x]),bl.useEffect(()=>x,[x]),ye(()=>{if(r&&i&&m.handleCloseOptions?.blockPointerEvents&&v()&&Se(u)&&a){let C=u,w=a,b=xt(a),R=c?.nodesRef.current.find(P=>P.id===f)?.context?.elements.floating;R&&(R.style.pointerEvents="");let A=m.pointerEventsScopeElement!==w?m.pointerEventsScopeElement:null,T=R!==w?R:null,_=m.handleCloseOptions?.getScope?.()??A??T??C.closest("[data-rootownerid]")??b.body;return ri(m,{scopeElement:_,referenceElement:C,floatingElement:w}),()=>{x()}}},[r,i,u,a,m,v,c,f,x]),bl.useEffect(()=>{if(!r)return;function C(){return!!(c&&f&&qr(c.nodesRef.current,f).length>0)}function w(P){let N=Yr(o,"close",m.pointerType),q=()=>{s.setOpen(!1,je(_e.triggerHover,P)),c?.events.emit("floating.closed",P)};N?m.openChangeTimeout.start(N,q):(m.openChangeTimeout.clear(),q())}function b(P){let N=Nt(P);if(!Ga(N)){m.interactedInside=!1;return}m.interactedInside=N?.closest("[aria-haspopup]")!=null}function R(){m.openChangeTimeout.clear(),g.clear(),c?.events.off("floating.closed",T),x()}function A(P){if(C()&&c){c.events.on("floating.closed",T);return}if(ao(P.relatedTarget,s.context.triggerElements))return;let N=l.current.floatingContext?.nodeId??n,q=P.relatedTarget;if(!(c&&N&&Se(q)&&qr(c.nodesRef.current,N,!1).some(S=>Ze(S.context?.elements.floating,q)))){if(m.handler){m.handler(P);return}x(),v()&&!d()&&w(P)}}function T(P){!c||!f||C()||g.start(0,()=>{c.events.off("floating.closed",T),s.setOpen(!1,je(_e.triggerHover,P)),c.events.emit("floating.closed",P)})}let _=a;return br(_&&Ye(_,"mouseenter",R),_&&Ye(_,"mouseleave",A),_&&Ye(_,"pointerdown",b,!0),()=>{c?.events.off("floating.closed",T)})},[r,a,s,l,o,n,v,d,x,m,c,f,g])}var po=h(ge(),1),Wd=h(io(),1);var K0={current:null};function xl(e,t={}){let{enabled:r=!0,delay:o=0,handleClose:n=null,mouseOnly:s=!1,restMs:i=0,move:a=!0,triggerElementRef:u=K0,externalTree:l,isActiveTrigger:c=!0,getHandleCloseContext:f,isClosing:m,shouldOpen:g}=t,d="rootStore"in e?e.rootStore:e,{dataRef:v,events:x}=d.context,C=uo(l),w=dn(d),b=po.useRef(!1),R=Wt(n),A=Wt(o),T=Wt(i),_=Wt(r),P=Wt(g),N=Wt(m),q=Te(()=>Hs(v.current.openEvent?.type,w.interactedInside)),H=Te(()=>P.current?.()!==!1),S=Te((O,D,J)=>{let M=d.context.triggerElements;if(M.hasElement(D))return!O||!Ze(O,D);if(!Se(J))return!1;let E=J;return M.hasMatchingElement(L=>Ze(L,E))&&(!O||!Ze(O,E))}),I=Te(()=>{if(!w.handler)return;xt(d.select("domReferenceElement")).removeEventListener("mousemove",w.handler),w.handler=void 0}),W=Te(()=>{fn(w)});return c&&(w.handleCloseOptions=R.current?.__options),po.useEffect(()=>I,[I]),po.useEffect(()=>{if(!r)return;function O(D){D.open?b.current=!1:(b.current=D.reason===_e.triggerHover,I(),w.openChangeTimeout.clear(),w.restTimeout.clear(),w.blockMouseMove=!0,w.restTimeoutPending=!1)}return x.on("openchange",O),()=>{x.off("openchange",O)}},[r,x,w,I]),po.useEffect(()=>{if(!r)return;function O(E,L=!0){let $=Yr(A.current,"close",w.pointerType);$?w.openChangeTimeout.start($,()=>{d.setOpen(!1,je(_e.triggerHover,E)),C?.events.emit("floating.closed",E)}):L&&(w.openChangeTimeout.clear(),d.setOpen(!1,je(_e.triggerHover,E)),C?.events.emit("floating.closed",E))}let D=u.current??(c?d.select("domReferenceElement"):null);if(!Se(D))return;function J(E){if(w.openChangeTimeout.clear(),w.blockMouseMove=!1,s&&!Gr(w.pointerType))return;let L=Ya(T.current),$=Yr(A.current,"open",w.pointerType),F=Nt(E),Z=E.currentTarget??null,se=d.select("domReferenceElement"),we=Z;if(Se(F)&&!d.context.triggerElements.hasElement(F)){for(let G of d.context.triggerElements.elements())if(Ze(G,F)){we=G;break}}Se(Z)&&Se(se)&&!d.context.triggerElements.hasElement(Z)&&Ze(Z,se)&&(we=se);let ie=we==null?!1:S(se,we,F),ve=d.select("open"),Ee=N.current?.()??d.select("transitionStatus")==="ending",ee=!ve&&Ee&&b.current,Fe=!ie&&Se(we)&&Se(se)&&Ze(se,we)&&ee,Ae=L>0&&!$,Oe=ie&&(ve||ee)||Fe,Ue=!ve||ie;if(Oe){H()&&d.setOpen(!0,je(_e.triggerHover,E,we));return}Ae||($?w.openChangeTimeout.start($,()=>{Ue&&H()&&d.setOpen(!0,je(_e.triggerHover,E,we))}):Ue&&H()&&d.setOpen(!0,je(_e.triggerHover,E,we)))}function M(E){if(q()){W();return}I();let L=d.select("domReferenceElement"),$=xt(L);w.restTimeout.clear(),w.restTimeoutPending=!1;let F=v.current.floatingContext??f?.();if(ao(E.relatedTarget,d.context.triggerElements))return;if(R.current&&F){d.select("open")||w.openChangeTimeout.clear();let se=u.current;w.handler=R.current({...F,tree:C,x:E.clientX,y:E.clientY,onClose(){W(),I(),_.current&&!q()&&se===d.select("domReferenceElement")&&O(E,!0)}}),$.addEventListener("mousemove",w.handler),w.handler(E);return}(w.pointerType!=="touch"||!Ze(d.select("floatingElement"),E.relatedTarget))&&O(E)}return a?br(Ye(D,"mousemove",J,{once:!0}),Ye(D,"mouseenter",J),Ye(D,"mouseleave",M)):br(Ye(D,"mouseenter",J),Ye(D,"mouseleave",M))},[I,W,v,A,d,r,R,w,c,S,q,s,a,T,u,C,_,f,N,H]),po.useMemo(()=>{if(!r)return;function O(D){w.pointerType=D.pointerType}return{onPointerDown:O,onPointerEnter:O,onMouseMove(D){let{nativeEvent:J}=D,M=D.currentTarget,E=d.select("domReferenceElement"),L=d.select("open"),$=S(E,M,D.target);if(s&&!Gr(w.pointerType))return;if(L&&$&&w.handleCloseOptions?.blockPointerEvents){let se=d.select("floatingElement");if(se){let we=w.handleCloseOptions?.getScope?.()??M.ownerDocument.body;ri(w,{scopeElement:we,referenceElement:M,floatingElement:se})}}let F=Ya(T.current);if(L&&!$||F===0||!$&&w.restTimeoutPending&&D.movementX**2+D.movementY**2<2)return;w.restTimeout.clear();function Z(){if(w.restTimeoutPending=!1,q())return;let se=d.select("open");!w.blockMouseMove&&(!se||$)&&H()&&d.setOpen(!0,je(_e.triggerHover,J,M))}w.pointerType==="touch"?Wd.flushSync(()=>{Z()}):$&&L?Z():(w.restTimeoutPending=!0,w.restTimeout.start(F,Z))}}},[r,w,q,S,s,d,T,H])}var Gd=.1,J0=Gd*Gd,Ke=.5;function oi(e,t,r,o,n,s){return o>=t!=s>=t&&e<=(n-r)*(t-o)/(s-o)+r}function ni(e,t,r,o,n,s,i,a,u,l){let c=!1;return oi(e,t,r,o,n,s)&&(c=!c),oi(e,t,n,s,i,a)&&(c=!c),oi(e,t,i,a,u,l)&&(c=!c),oi(e,t,u,l,r,o)&&(c=!c),c}function Q0(e,t,r){return e>=r.x&&e<=r.x+r.width&&t>=r.y&&t<=r.y+r.height}function si(e,t,r,o,n,s){let i=Math.min(r,n),a=Math.max(r,n),u=Math.min(o,s),l=Math.max(o,s);return e>=i&&e<=a&&t>=u&&t<=l}function Sl(e={}){let{blockPointerEvents:t=!1}=e,r=new tr,o=({x:n,y:s,placement:i,elements:a,onClose:u,nodeId:l,tree:c})=>{let f=i?.split("-")[0],m=!1,g=null,d=null,v=typeof performance<"u"?performance.now():0;function x(w,b){let R=performance.now(),A=R-v;if(g===null||d===null||A===0)return g=w,d=b,v=R,!1;let T=w-g,_=b-d,P=T*T+_*_,N=A*A*J0;return g=w,d=b,v=R,P0)}function I(){S()||C()}if(S())return;let W=R.getBoundingClientRect(),O=A.getBoundingClientRect(),D=n>O.right-O.width/2,J=s>O.bottom-O.height/2,M=O.width>W.width,E=O.height>W.height,L=(M?W:O).left,$=(M?W:O).right,F=(E?W:O).top,Z=(E?W:O).bottom;if(f==="top"&&s>=W.bottom-1||f==="bottom"&&s<=W.top+1||f==="left"&&n>=W.right-1||f==="right"&&n<=W.left+1){I();return}let se=!1;switch(f){case"top":se=si(T,_,L,W.top+1,$,O.bottom-1);break;case"bottom":se=si(T,_,L,O.top+1,$,W.bottom-1);break;case"left":se=si(T,_,O.right-1,Z,W.left+1,F);break;case"right":se=si(T,_,W.right-1,Z,O.left+1,F);break;default:}if(se)return;if(m&&!Q0(T,_,W)){I();return}if(!N&&x(T,_)){I();return}let we=!1;switch(f){case"top":{let ie=M?Ke/2:Ke*4,ve=M||D?n+ie:n-ie,Ee=M?n-ie:D?n+ie:n-ie,ee=s+Ke+1,Fe=D||M?O.bottom-Ke:O.top,Ae=D?M?O.bottom-Ke:O.top:O.bottom-Ke;we=ni(T,_,ve,ee,Ee,ee,O.left,Fe,O.right,Ae);break}case"bottom":{let ie=M?Ke/2:Ke*4,ve=M||D?n+ie:n-ie,Ee=M?n-ie:D?n+ie:n-ie,ee=s-Ke,Fe=D||M?O.top+Ke:O.bottom,Ae=D?M?O.top+Ke:O.bottom:O.top+Ke;we=ni(T,_,ve,ee,Ee,ee,O.left,Fe,O.right,Ae);break}case"left":{let ie=E?Ke/2:Ke*4,ve=E||J?s+ie:s-ie,Ee=E?s-ie:J?s+ie:s-ie,ee=n+Ke+1,Fe=J||E?O.right-Ke:O.left,Ae=J?E?O.right-Ke:O.left:O.right-Ke;we=ni(T,_,Fe,O.top,Ae,O.bottom,ee,ve,ee,Ee);break}case"right":{let ie=E?Ke/2:Ke*4,ve=E||J?s+ie:s-ie,Ee=E?s-ie:J?s+ie:s-ie,ee=n-Ke,Fe=J||E?O.left+Ke:O.right,Ae=J?E?O.left+Ke:O.right:O.left+Ke;we=ni(T,_,ee,ve,ee,Ee,Fe,O.top,Ae,O.bottom);break}default:}we?m||r.start(40,I):I()}};return o.__options={...e,blockPointerEvents:t},o}var Cl=(function(e){return e.open="data-open",e.closed="data-closed",e[e.startingStyle=To.startingStyle]="startingStyle",e[e.endingStyle=To.endingStyle]="endingStyle",e.anchorHidden="data-anchor-hidden",e.side="data-side",e.align="data-align",e})({}),os=(function(e){return e.popupOpen="data-popup-open",e.pressed="data-pressed",e})({}),$0={[os.popupOpen]:""},nk={[os.popupOpen]:"",[os.pressed]:""},ew={[Cl.open]:""},tw={[Cl.closed]:""},rw={[Cl.anchorHidden]:""},Yd={open(e){return e?$0:null}};var pn={open(e){return e?ew:tw},anchorHidden(e){return e?rw:null}};function qd(e){return $o(19)?e:e?"true":void 0}var or=h(ge(),1);var ow=e=>({name:"arrow",options:e,async fn(t){let{x:r,y:o,placement:n,rects:s,platform:i,elements:a,middlewareData:u}=t,{element:l,padding:c=0,offsetParent:f="real"}=xr(e,t)||{};if(l==null)return{};let m=qs(c),g={x:r,y:o},d=es(n),v=$n(d),x=await i.getDimensions(l),C=d==="y",w=C?"top":"left",b=C?"bottom":"right",R=C?"clientHeight":"clientWidth",A=s.reference[v]+s.reference[d]-g[d]-s.floating[v],T=g[d]-s.reference[d],_=f==="real"?await i.getOffsetParent?.(l):a.floating,P=a.floating[R]||s.floating[v];(!P||!await i.isElement?.(_))&&(P=a.floating[R]||s.floating[v]);let N=A/2-T/2,q=P/2-x[v]/2-1,H=Math.min(m[w],q),S=Math.min(m[b],q),I=H,W=P-x[v]-S,O=P/2-x[v]/2+N,D=Gs(I,O,W),J=!u.arrow&&Sr(n)!=null&&O!==D&&s.reference[v]/2-(O({...ow(e),options:[e,t]});var nw=al().fn,Xd={name:"hide",async fn(e){let{width:t,height:r,x:o,y:n}=e.rects.reference,s=t===0&&r===0&&o===0&&n===0;return{data:{referenceHidden:(await nw(e)).data?.referenceHidden||s}}}};var ns={sideX:"left",sideY:"top"},Kd={name:"adaptiveOrigin",async fn(e){let{x:t,y:r,rects:{floating:o},elements:{floating:n},platform:s,strategy:i,placement:a}=e,u=it(n),l=u.getComputedStyle(n);if(!(l.transitionDuration!=="0s"&&l.transitionDuration!==""))return{x:t,y:r,data:ns};let f=await s.getOffsetParent?.(n),m={width:0,height:0};if(i==="fixed"&&u?.visualViewport)m={width:u.visualViewport.width,height:u.visualViewport.height};else if(f===u){let w=xt(n);m={width:w.documentElement.clientWidth,height:w.documentElement.clientHeight}}else await s.isElement?.(f)&&(m=await s.getDimensions(f));let g=Pt(a),d=t,v=r;g==="left"&&(d=m.width-(t+o.width)),g==="top"&&(v=m.height-(r+o.height));let x=g==="left"?"right":ns.sideX,C=g==="top"?"bottom":ns.sideY;return{x:d,y:v,data:{sideX:x,sideY:C}}}};function $d(e,t,r){let o=e==="inline-start"||e==="inline-end";return{top:"top",right:o?r?"inline-start":"inline-end":"right",bottom:"bottom",left:o?r?"inline-end":"inline-start":"left"}[t]}function Jd(e,t,r){let{rects:o,placement:n}=e;return{side:$d(t,Pt(n),r),align:Sr(n)||"center",anchor:{width:o.reference.width,height:o.reference.height},positioner:{width:o.floating.width,height:o.floating.height}}}function ep(e){let{anchor:t,positionMethod:r="absolute",side:o="bottom",sideOffset:n=0,align:s="center",alignOffset:i=0,collisionBoundary:a,collisionPadding:u=5,sticky:l=!1,arrowPadding:c=5,disableAnchorTracking:f=!1,inline:m,keepMounted:g=!1,floatingRootContext:d,mounted:v,collisionAvoidance:x,shiftCrossAxis:C=!1,nodeId:w,adaptiveOrigin:b,lazyFlip:R=!1,externalTree:A}=e,[T,_]=or.useState(null);!v&&T!==null&&_(null);let P=x.side||"flip",N=x.align||"flip",q=x.fallbackAxisSide||"end",H=typeof t=="function"?t:void 0,S=Te(H),I=H?S:t,W=Wt(t),O=Wt(v),J=Qo()==="rtl",M=T||{top:"top",right:"right",bottom:"bottom",left:"left","inline-end":J?"left":"right","inline-start":J?"right":"left"}[o],E=s==="center"?M:`${M}-${s}`,L=u,$=1,F=o==="bottom"?$:0,Z=o==="top"?$:0,se=o==="right"?$:0,we=o==="left"?$:0;typeof L=="number"?L={top:L+F,right:L+we,bottom:L+Z,left:L+se}:L&&(L={top:(L.top||0)+F,right:(L.right||0)+we,bottom:(L.bottom||0)+Z,left:(L.left||0)+se});let ie={boundary:a==="clipping-ancestors"?"clippingAncestors":a,padding:L},ve=or.useRef(null),Ee=Wt(n),ee=Wt(i),Fe=typeof n!="function"?n:0,Ae=typeof i!="function"?i:0,Oe=[];m&&Oe.push(m),Oe.push(rl(Le=>{let qe=Jd(Le,o,J),k=typeof Ee.current=="function"?Ee.current(qe):Ee.current,Q=typeof ee.current=="function"?ee.current(qe):ee.current;return{mainAxis:k,crossAxis:Q,alignmentAxis:Q}},[Fe,Ae,J,o]));let Ue=N==="none"&&P!=="shift",G=!Ue&&(l||C||P==="shift"),z=P==="none"?null:sl({...ie,padding:{top:L.top+$,right:L.right+$,bottom:L.bottom+$,left:L.left+$},mainAxis:!C&&P==="flip",crossAxis:N==="flip"?"alignment":!1,fallbackAxisSideDirection:q}),X=Ue?null:ol(Le=>{let qe=xt(Le.elements.floating).documentElement;return{...ie,rootBoundary:C?{x:0,y:0,width:qe.clientWidth,height:qe.clientHeight}:void 0,mainAxis:N!=="none",crossAxis:G,limiter:l||C?void 0:nl(k=>{if(!ve.current)return{};let{width:Q,height:y}=ve.current.getBoundingClientRect(),oe=Gt(Pt(k.placement)),Ve=oe==="y"?Q:y,te=oe==="y"?L.left+L.right:L.top+L.bottom;return{offset:Ve/2+te/2}})}},[ie,l,C,L,N]);P==="shift"||N==="shift"||s==="center"?Oe.push(X,z):Oe.push(z,X),Oe.push(il({...ie,apply({elements:{floating:Le},availableWidth:qe,availableHeight:k,rects:Q}){if(!O.current)return;let y=Le.style;y.setProperty("--available-width",`${qe}px`),y.setProperty("--available-height",`${k}px`);let oe=it(Le).devicePixelRatio||1,{x:Ve,y:te,width:ht,height:ne}=Q.reference,Qe=(Math.round((Ve+ht)*oe)-Math.round(Ve*oe))/oe,B=(Math.round((te+ne)*oe)-Math.round(te*oe))/oe;y.setProperty("--anchor-width",`${Qe}px`),y.setProperty("--anchor-height",`${B}px`)}}),Zd(Le=>({element:ve.current||xt(Le.elements.floating).createElement("div"),padding:c,offsetParent:"floating"}),[c]),{name:"transformOrigin",fn(Le){let{elements:qe,middlewareData:k,placement:Q,rects:y,y:oe}=Le,Ve=Pt(Q),te=Gt(Ve),ht=ve.current,ne=k.arrow?.x||0,Qe=k.arrow?.y||0,B=ht?.clientWidth||0,j=ht?.clientHeight||0,yr=ne+B/2,Ge=Qe+j/2,le=Math.abs(k.shift?.y||0),zr=y.reference.height/2,Qt=typeof n=="function"?n(Jd(Le,o,J)):n,et=le>Qt,Me={top:`${yr}px calc(100% + ${Qt}px)`,bottom:`${yr}px ${-Qt}px`,left:`calc(100% + ${Qt}px) ${Ge}px`,right:`${-Qt}px ${Ge}px`}[Ve],ft=`${yr}px ${y.reference.y+zr-oe}px`;return qe.floating.style.setProperty("--transform-origin",G&&te==="y"&&et?ft:Me),{}}},Xd,b),ye(()=>{!v&&d&&d.update({referenceElement:null,floatingElement:null,domReferenceElement:null,positionReference:null})},[v,d]);let U=or.useMemo(()=>({elementResize:!f&&typeof ResizeObserver<"u",layoutShift:!f&&typeof IntersectionObserver<"u"}),[f]),{refs:K,elements:fe,x:ue,y:de,middlewareData:pe,update:me,placement:V,context:re,isPositioned:Ne,floatingStyles:He}=hl({rootContext:d,open:g?v:void 0,placement:E,middleware:Oe,strategy:r,whileElementsMounted:g?void 0:(...Le)=>ts(...Le,U),nodeId:w,externalTree:A}),{sideX:ot,sideY:ut}=pe.adaptiveOrigin||ns,ze=Ne?r:"fixed",We=or.useMemo(()=>{let Le=b?{position:ze,[ot]:ue,[ut]:de}:{position:ze,...He};return Ne||(Le.opacity=0),Le},[b,ze,ot,ue,ut,de,He,Ne]),nt=or.useRef(null);ye(()=>{if(!v)return;let Le=W.current,qe=typeof Le=="function"?Le():Le,Q=(Qd(qe)?qe.current:qe)||null||null;Q!==nt.current&&(K.setPositionReference(Q),nt.current=Q)},[v,K,I,W]),or.useEffect(()=>{if(!v)return;let Le=W.current;typeof Le!="function"&&Qd(Le)&&Le.current!==nt.current&&(K.setPositionReference(Le.current),nt.current=Le.current)},[v,K,I,W]),or.useEffect(()=>{if(g&&v&&fe.reference&&fe.floating)return ts(fe.reference,fe.floating,me,U)},[g,v,fe,me,U]);let be=Pt(V),Rr=$d(o,be,J),gr=Sr(V)||"center",$e=!!pe.hide?.referenceHidden;ye(()=>{R&&v&&Ne&&_(be)},[R,v,Ne,be]);let jr=or.useMemo(()=>({position:"absolute",top:pe.arrow?.y,left:pe.arrow?.x}),[pe.arrow]),Ct=pe.arrow?.centerOffset!==0;return or.useMemo(()=>({positionerStyles:We,arrowStyles:jr,arrowRef:ve,arrowUncentered:Ct,side:Rr,align:gr,physicalSide:be,anchorHidden:$e,refs:K,context:re,isPositioned:Ne,update:me}),[We,jr,ve,Ct,Rr,gr,be,$e,K,re,Ne,me])}function Qd(e){return e!=null&&"current"in e}function ii(e){return e==="starting"?Ff:pt}function tp(e,t,{styles:r,transitionStatus:o,props:n,refs:s,hidden:i,inert:a=!1}){let u={...r};return a&&(u.pointerEvents="none"),Ht("div",e,{state:t,ref:s,props:[{role:"presentation",hidden:i,style:u},ii(o),n],stateAttributesMapping:pn})}var kt=h(ge(),1),cp=h(io(),1);var rp=h(ge(),1);function op(e){let[t,r]=rp.useState({current:e,previous:null});return e!==t.current&&r({current:e,previous:t.current}),t.previous}var mn=h(ge(),1);function Rl(e){let t=Lt(e),r=parseFloat(t.width)||0,o=parseFloat(t.height)||0,n=Et(e),s=n?e.offsetWidth:r,i=n?e.offsetHeight:o;return(co(r)!==s||co(o)!==i)&&(r=s,o=i),{width:r,height:o}}function sp(e){let{popupElement:t,positionerElement:r,content:o,mounted:n,onMeasureLayout:s,onMeasureLayoutComplete:i,side:a,direction:u}=e,l=on(t,!0,!1),c=tn(),f=mn.useRef(null),m=mn.useRef(!0),g=mn.useRef(oo),d=Te(s),v=Te(i),x=mn.useMemo(()=>{let C=a==="top",w=a==="left";return u==="rtl"?(C=C||a==="inline-end",w=w||a==="inline-end"):(C=C||a==="inline-start",w=w||a==="inline-start"),C?{position:"absolute",[a==="top"?"bottom":"top"]:"0",[w?"right":"left"]:"0"}:pt},[a,u]);ye(()=>{if(!n){g.current=oo,m.current=!0,f.current=null;return}if(!t||!r)return;g.current=np(t,x),El(t,"auto");let C=li(t,"position","static"),w=li(t,"transform","none"),b=li(t,"scale","1"),R=np(r,{"--available-width":"max-content","--available-height":"max-content"});function A(){C(),w(),R()}function T(){A(),b()}if(d?.(),m.current||f.current===null){ai(r,"max-content");let q=Rl(t);return f.current=q,ai(r,q),T(),v?.(null,q),m.current=!1,()=>{g.current(),g.current=oo}}ai(r,"max-content");let _=f.current,P=Rl(t);f.current=P,El(t,_),T(),v?.(_,P),ai(r,P);let N=new AbortController;return c.request(()=>{El(t,P),l(()=>{t.style.setProperty("--popup-width","auto"),t.style.setProperty("--popup-height","auto")},N.signal)}),()=>{N.abort(),c.cancel(),g.current(),g.current=oo}},[o,t,r,l,c,n,d,v,x])}function li(e,t,r){let o=e.style.getPropertyValue(t);return e.style.setProperty(t,r),()=>{e.style.setProperty(t,o)}}function np(e,t){let r=[];for(let[o,n]of Object.entries(t))r.push(li(e,o,n));return r.length?()=>{r.forEach(o=>o())}:oo}function El(e,t){let r=t==="auto"?"auto":`${t.width}px`,o=t==="auto"?"auto":`${t.height}px`;e.style.setProperty("--popup-width",r),e.style.setProperty("--popup-height",o)}function ai(e,t){let r=t==="max-content"?"max-content":`${t.width}px`,o=t==="max-content"?"max-content":`${t.height}px`;e.style.setProperty("--positioner-width",r),e.style.setProperty("--positioner-height",o)}var ip=h(ge(),1);var ap=h(Y(),1),ci=function(t){let{direction:r="ltr"}=t,o=ip.useMemo(()=>({direction:r}),[r]);return(0,ap.jsx)(Ta.Provider,{value:o,children:t.children})};var hn=h(Y(),1);function up(e){let{store:t,side:r,cssVars:o,children:n}=e,s=Qo(),i=t.useState("activeTriggerElement"),a=t.useState("activeTriggerId"),u=t.useState("open"),l=t.useState("payload"),c=t.useState("mounted"),f=t.useState("popupElement"),m=t.useState("positionerElement"),g=op(u?i:null),d=aw(a,l),v=kt.useRef(null),[x,C]=kt.useState(null),[w,b]=kt.useState(null),R=kt.useRef(null),A=kt.useRef(null),T=on(R,!0,!1),_=tn(),[P,N]=kt.useState(null),[q,H]=kt.useState(!1);ye(()=>(t.set("hasViewport",!0),()=>{t.set("hasViewport",!1)}),[t]);let S=Te(()=>{R.current?.style.setProperty("animation","none"),R.current?.style.setProperty("transition","none"),A.current?.style.setProperty("display","none")}),I=Te(M=>{R.current?.style.removeProperty("animation"),R.current?.style.removeProperty("transition"),A.current?.style.removeProperty("display"),M&&N(M)}),W=kt.useRef(null);ye(()=>{(!u||!c)&&(W.current=null)},[u,c]),ye(()=>{if(i&&g&&i!==g&&W.current!==i&&v.current){C(v.current),H(!0);let M=iw(g,i);b(M),_.request(()=>{cp.flushSync(()=>{H(!1)}),T(()=>{C(null),N(null),v.current=null})}),W.current=i}},[i,g,x,T,_]),ye(()=>{let M=R.current;if(!M)return;let E=xt(M).createElement("div");for(let L of Array.from(M.childNodes))E.appendChild(L.cloneNode(!0));v.current=E});let O=x!=null,D;O?D=(0,hn.jsxs)(kt.Fragment,{children:[(0,hn.jsx)("div",{"data-previous":!0,inert:qd(!0),ref:A,style:{...P?{[o.popupWidth]:`${P.width}px`,[o.popupHeight]:`${P.height}px`}:null,position:"absolute"},"data-ending-style":q?void 0:""},"previous"),(0,hn.jsx)("div",{"data-current":!0,ref:R,"data-starting-style":q?"":void 0,children:n},d)]}):D=(0,hn.jsx)("div",{"data-current":!0,ref:R,children:n},d),ye(()=>{let M=A.current;!M||!x||M.replaceChildren(...Array.from(x.childNodes))},[x]),sp({popupElement:f,positionerElement:m,mounted:c,content:l,onMeasureLayout:S,onMeasureLayoutComplete:I,side:r,direction:s});let J={activationDirection:sw(w),transitioning:O};return{children:D,state:J}}function sw(e){if(e)return`${lp(e.horizontal,5,"right","left")} ${lp(e.vertical,5,"down","up")}`}function lp(e,t,r,o){return e>t?r:e<-t?o:""}function iw(e,t){let r=e.getBoundingClientRect(),o=t.getBoundingClientRect(),n={x:r.left+r.width/2,y:r.top+r.height/2},s={x:o.left+o.width/2,y:o.top+o.height/2};return{horizontal:s.x-n.x,vertical:s.y-n.y}}function aw(e,t){let[r,o]=kt.useState(0),n=kt.useRef(e),s=kt.useRef(t),i=kt.useRef(!1);return ye(()=>{let a=n.current,u=s.current,l=e!==a,c=t!==u;l?(o(f=>f+1),i.current=!c):i.current&&c&&(o(f=>f+1),i.current=!1),n.current=e,s.current=t},[e,t]),`${e??"current"}-${r}`}var ui=h(ge(),1),fp=h(io(),1);var dp=h(Y(),1),pp=ui.forwardRef(function(t,r){let{children:o,container:n,className:s,render:i,style:a,...u}=t,{portalNode:l,portalSubtree:c}=Xa({container:n,ref:r,componentProps:t,elementProps:u});return!c&&!l?null:(0,dp.jsxs)(ui.Fragment,{children:[c,l&&fp.createPortal(o,l)]})});var Zt={};ro(Zt,{Arrow:()=>Op,Handle:()=>ss,Popup:()=>_p,Portal:()=>Cp,Positioner:()=>Ep,Provider:()=>kp,Root:()=>hp,Trigger:()=>wp,Viewport:()=>Ip,createHandle:()=>Lp});var Ar=h(ge(),1);var fi=h(ge(),1),Tl=fi.createContext(void 0);function ir(e){let t=fi.useContext(Tl);if(t===void 0&&!e)throw new Error(Ut(72));return t}var mp=h(ge(),1);var lw={...Ud,disabled:De(e=>e.disabled),instantType:De(e=>e.instantType),isInstantPhase:De(e=>e.isInstantPhase),trackCursorAxis:De(e=>e.trackCursorAxis),disableHoverablePopup:De(e=>e.disableHoverablePopup),lastOpenChangeReason:De(e=>e.openChangeReason),closeOnClick:De(e=>e.closeOnClick),closeDelay:De(e=>e.closeDelay),hasViewport:De(e=>e.hasViewport)},gn=class e extends cn{constructor(t,r,o=!1){let n=new fo,s={...cw(),...t};s.floatingRootContext=jd(n,r,o),super(s,{popupRef:mp.createRef(),onOpenChange:void 0,onOpenChangeComplete:void 0,triggerElements:n},lw)}setOpen=(t,r)=>{Fd(this,t,r,{extraState:{openChangeReason:r.reason}})};cancelPendingOpen(t){this.state.floatingRootContext.dispatchOpenChange(!1,je(_e.triggerPress,t))}static useStore(t,r){return kd(t,(n,s)=>new e(r,n,s)).store}};function cw(){return{...Bd(),disabled:!1,instantType:void 0,isInstantPhase:!1,trackCursorAxis:"none",disableHoverablePopup:!1,openChangeReason:null,closeOnClick:!0,closeDelay:0,hasViewport:!1}}var di=h(Y(),1),hp=dl(function(t){let{disabled:r=!1,defaultOpen:o=!1,open:n,disableHoverablePopup:s=!1,trackCursorAxis:i="none",actionsRef:a,onOpenChange:u,onOpenChangeComplete:l,handle:c,triggerId:f,defaultTriggerId:m=null,children:g}=t,d=gn.useStore(c?.store,{open:o,openProp:n,activeTriggerId:m,triggerIdProp:f});Ad(d,n,o,m),d.useControlledProp("openProp",n),d.useControlledProp("triggerIdProp",f),d.useContextCallback("onOpenChange",u),d.useContextCallback("onOpenChangeComplete",l);let v=d.useState("open"),x=!r&&v,C=d.useState("activeTriggerId"),w=d.useState("mounted"),b=d.useState("payload");d.useSyncedValues({trackCursorAxis:i,disableHoverablePopup:s}),d.useSyncedValue("disabled",r),Ld(d,{closeOnActiveTriggerUnmount:!0});let{forceUnmount:R,transitionStatus:A}=Nd(x,d),T=d.useState("isInstantPhase"),_=d.useState("instantType"),P=d.useState("lastOpenChangeReason"),N=Ar.useRef(null);ye(()=>{v&&r&&d.setOpen(!1,je(_e.disabled))},[v,r,d]),ye(()=>{A==="ending"&&P===_e.none||A!=="ending"&&T?(_!=="delay"&&(N.current=_),d.set("instantType","delay")):N.current!==null&&(d.set("instantType",N.current),N.current=null)},[A,T,P,_,d]),ye(()=>{x&&C==null&&d.set("payload",void 0)},[d,C,x]);let q=Ar.useCallback(()=>{d.setOpen(!1,je(_e.imperativeAction))},[d]);Ar.useImperativeHandle(a,()=>({unmount:R,close:q}),[R,q]);let H=x||w||!r&&i!=="none";return(0,di.jsxs)(Tl.Provider,{value:d,children:[H&&(0,di.jsx)(uw,{store:d,disabled:r,trackCursorAxis:i}),typeof g=="function"?g({payload:b}):g]})});function uw({store:e,disabled:t,trackCursorAxis:r}){let o=e.useState("floatingRootContext"),n=Ja(o,{enabled:!t,referencePress:()=>e.select("closeOnClick")}),s=Ka(o,{enabled:!t&&r!=="none",axis:r==="none"?void 0:r}),i=Ar.useMemo(()=>er(s.reference,n.reference),[s.reference,n.reference]),a=Ar.useMemo(()=>er(s.trigger,n.trigger),[s.trigger,n.trigger]),u=Ar.useMemo(()=>er(Od,s.floating,n.floating),[s.floating,n.floating]);return Dd(e,{activeTriggerProps:i,inactiveTriggerProps:a,popupProps:u}),null}var mi=h(ge(),1);var pi=h(ge(),1),_l=pi.createContext(void 0);function gp(){return pi.useContext(_l)}var yp=(function(e){return e[e.popupOpen=os.popupOpen]="popupOpen",e.triggerDisabled="data-trigger-disabled",e})({});var bp="data-base-ui-tooltip-trigger";function vp(e){if("composedPath"in e){let r=e.composedPath();for(let o=0;ov.select("transitionStatus")==="ending",shouldOpen(){return!E.current}}),ie=yl(b,{enabled:!O}).reference,ve=Oe=>{let Ue=E.current,G=vp(Oe),z=se(G),X=R.current,U=X&&G&&Ze(X,G);if(z&&v.select("open")&&v.select("lastOpenChangeReason")===_e.triggerHover){v.setOpen(!1,je(_e.triggerHover,Oe));return}if(Ue&&!z&&U&&!D.current&&!v.select("open")&&X&&Gr($.current)){let K=()=>{!E.current&&!D.current&&!v.select("open")&&v.setOpen(!0,je(_e.triggerHover,Oe,X))},fe=F();fe===0?(L.clear(),K()):L.start(fe,K)}},Ee=v.useState("triggerProps",P);return Ht("button",t,{state:{open:w},ref:[r,_,R],props:[we,ie,P||J!=="none"?Ee:void 0,{onMouseOver(Oe){ve(Oe.nativeEvent)},onFocus(Oe){Z(vp(Oe.nativeEvent))&&Oe.preventBaseUIHandler()},onMouseLeave(){E.current=!1,L.clear(),$.current=void 0},onPointerEnter(Oe){$.current=Oe.pointerType},onPointerDown(Oe){$.current=Oe.pointerType,v.set("closeOnClick",c),c&&!v.select("open")&&v.cancelPendingOpen(Oe.nativeEvent)},onClick(Oe){c&&!v.select("open")&&v.cancelPendingOpen(Oe.nativeEvent)},id:x,[yp.triggerDisabled]:O?"":void 0,[bp]:O?void 0:""},g],stateAttributesMapping:Yd})});var Sp=h(ge(),1);var hi=h(ge(),1),Pl=hi.createContext(void 0);function xp(){let e=hi.useContext(Pl);if(e===void 0)throw new Error(Ut(70));return e}var Ol=h(Y(),1),Cp=Sp.forwardRef(function(t,r){let{keepMounted:o=!1,...n}=t;return ir().useState("mounted")||o?(0,Ol.jsx)(Pl.Provider,{value:o,children:(0,Ol.jsx)(pp,{ref:r,...n})}):null});var yi=h(ge(),1);var gi=h(ge(),1),kl=gi.createContext(void 0);function yn(){let e=gi.useContext(kl);if(e===void 0)throw new Error(Ut(71));return e}var Rp=h(Y(),1),Ep=yi.forwardRef(function(t,r){let{render:o,className:n,anchor:s,positionMethod:i="absolute",side:a="top",align:u="center",sideOffset:l=0,alignOffset:c=0,collisionBoundary:f="clipping-ancestors",collisionPadding:m=5,arrowPadding:g=5,sticky:d=!1,disableAnchorTracking:v=!1,collisionAvoidance:x=Af,style:C,...w}=t,b=ir(),R=xp(),A=b.useState("open"),T=b.useState("mounted"),_=b.useState("trackCursorAxis"),P=b.useState("disableHoverablePopup"),N=b.useState("floatingRootContext"),q=b.useState("instantType"),H=b.useState("transitionStatus"),S=b.useState("hasViewport"),I=ep({anchor:s,positionMethod:i,floatingRootContext:N,mounted:T,side:a,sideOffset:l,align:u,alignOffset:c,collisionBoundary:f,collisionPadding:m,sticky:d,arrowPadding:g,disableAnchorTracking:v,keepMounted:R,collisionAvoidance:x,adaptiveOrigin:S?Kd:void 0}),W=yi.useMemo(()=>({open:A,side:I.side,align:I.align,anchorHidden:I.anchorHidden,instant:_!=="none"?"tracking-cursor":q}),[A,I.side,I.align,I.anchorHidden,_,q]),O=tp(t,W,{styles:I.positionerStyles,transitionStatus:H,props:w,refs:[r,b.useStateSetter("positionerElement")],hidden:!T,inert:!A||_==="both"||P});return(0,Rp.jsx)(kl.Provider,{value:I,children:O})});var Tp=h(ge(),1);var dw={...pn,...rf},_p=Tp.forwardRef(function(t,r){let{render:o,className:n,style:s,...i}=t,a=ir(),{side:u,align:l}=yn(),c=a.useState("open"),f=a.useState("instantType"),m=a.useState("transitionStatus"),g=a.useState("popupProps"),d=a.useState("floatingRootContext"),v=a.useState("disabled"),x=a.useState("closeDelay");js({open:c,ref:a.context.popupRef,onComplete(){c&&a.context.onOpenChangeComplete?.(!0)}}),wl(d,{enabled:!v,closeDelay:x});let C=a.useStateSetter("popupElement");return Ht("div",t,{state:{open:c,side:u,align:l,instant:f,transitionStatus:m},ref:[r,a.context.popupRef,C],props:[g,ii(m),i],stateAttributesMapping:dw})});var Pp=h(ge(),1);var Op=Pp.forwardRef(function(t,r){let{render:o,className:n,style:s,...i}=t,a=ir(),{arrowRef:u,side:l,align:c,arrowUncentered:f,arrowStyles:m}=yn(),g=a.useState("open"),d=a.useState("instantType");return Ht("div",t,{state:{open:g,side:l,align:c,uncentered:f,instant:d},ref:[r,u],props:[{style:m,"aria-hidden":!0},i],stateAttributesMapping:pn})});var Fl=h(ge(),1);var Al=h(Y(),1),kp=function(t){let{delay:r,closeDelay:o,timeout:n=400}=t,s=Fl.useMemo(()=>({delay:r,closeDelay:o}),[r,o]),i=Fl.useMemo(()=>({open:r,close:o}),[r,o]);return(0,Al.jsx)(_l.Provider,{value:s,children:(0,Al.jsx)(qa,{delay:i,timeoutMs:n,children:t.children})})};var Ap=h(ge(),1);var Fp=(function(e){return e.popupWidth="--popup-width",e.popupHeight="--popup-height",e})({});var pw={activationDirection:e=>e?{"data-activation-direction":e}:null},Ip=Ap.forwardRef(function(t,r){let{render:o,className:n,style:s,children:i,...a}=t,u=ir(),l=yn(),c=u.useState("instantType"),{children:f,state:m}=up({store:u,side:l.side,cssVars:Fp,children:i}),g={activationDirection:m.activationDirection,transitioning:m.transitioning,instant:c};return Ht("div",t,{state:g,ref:r,props:[a,{children:f}],stateAttributesMapping:pw})});var ss=class{constructor(){this.store=new gn}open(t){let r=t?this.store.context.triggerElements.getById(t):void 0;if(t&&!r)throw new Error(Ut(81,t));this.store.setOpen(!0,je(_e.imperativeAction,void 0,r))}close(){this.store.setOpen(!1,je(_e.imperativeAction,void 0,void 0))}get isOpen(){return this.store.select("open")}};function Lp(){return new ss}function vn(e){return Ht(e.defaultTagName??"div",e,e)}var Mp=h(ke(),1),Il="data-wp-hash";function Ll(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&hw(document)),e.__wpStyleRuntime}function mw(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${Il}]`))if(r.getAttribute(Il)===t)return!0;return!1}function Vp(e,t,r){if(!e.head)return;let o=Ll(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(mw(e,t)){n.add(t);return}let s=e.createElement("style");s.setAttribute(Il,t),s.appendChild(e.createTextNode(r)),e.head.appendChild(s),n.add(t)}function hw(e){let t=Ll();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)Vp(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function Bp(e,t){let r=Ll();r.styles.set(e,t);for(let o of r.documents.keys())Vp(o,e,t)}typeof process>"u",Bp("a495f9d138",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._83ed8a8da5dd50ea__text{margin:0}._14437cfb77831647__heading-2xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-2xl,32px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-2xl,32px);--_gcd-p-line-height:var(--wpds-typography-line-height-2xl,40px);font-size:var(--wpds-typography-font-size-2xl,32px);line-height:var(--wpds-typography-line-height-2xl,40px)}._14437cfb77831647__heading-2xl,._3c78b7fa9b4072dd__heading-xl{font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-emphasis,600)}._3c78b7fa9b4072dd__heading-xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-p-line-height:var(--wpds-typography-line-height-md,24px);font-size:var(--wpds-typography-font-size-xl,20px);line-height:var(--wpds-typography-line-height-md,24px)}.aa58f227716bcde2__heading-lg{--_gcd-heading-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-lg,15px)}.aa58f227716bcde2__heading-lg,.fc4da56d8dfe52c4__heading-md{font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:var(--wpds-typography-line-height-sm,20px)}.fc4da56d8dfe52c4__heading-md{--_gcd-heading-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-md,13px)}.a9b78c7c82e8dff7__heading-sm{--_gcd-heading-font-size:var(--wpds-typography-font-size-xs,11px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-xs,11px);--_gcd-p-line-height:var(--wpds-typography-line-height-xs,16px);font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-xs,11px);font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:var(--wpds-typography-line-height-xs,16px);text-transform:uppercase}._305ff559e52180d5__body-xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-p-line-height:var(--wpds-typography-line-height-xl,32px);font-size:var(--wpds-typography-font-size-xl,20px);line-height:var(--wpds-typography-line-height-xl,32px)}._305ff559e52180d5__body-xl,.ca1aa3fc2029e958__body-lg{font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-default,400)}.ca1aa3fc2029e958__body-lg{--_gcd-heading-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-p-line-height:var(--wpds-typography-line-height-md,24px);font-size:var(--wpds-typography-font-size-lg,15px);line-height:var(--wpds-typography-line-height-md,24px)}._131101940be12424__body-md{--_gcd-heading-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-md,13px);line-height:var(--wpds-typography-line-height-sm,20px)}._0e8d87a42c1f75fa__body-sm,._131101940be12424__body-md{font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-default,400)}._0e8d87a42c1f75fa__body-sm{--_gcd-heading-font-size:var(--wpds-typography-font-size-sm,12px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-sm,12px);--_gcd-p-line-height:var(--wpds-typography-line-height-xs,16px);font-size:var(--wpds-typography-font-size-sm,12px);line-height:var(--wpds-typography-line-height-xs,16px)}}}');var Np={text:"_83ed8a8da5dd50ea__text","heading-2xl":"_14437cfb77831647__heading-2xl","heading-xl":"_3c78b7fa9b4072dd__heading-xl","heading-lg":"aa58f227716bcde2__heading-lg","heading-md":"fc4da56d8dfe52c4__heading-md","heading-sm":"a9b78c7c82e8dff7__heading-sm","body-xl":"_305ff559e52180d5__body-xl","body-lg":"ca1aa3fc2029e958__body-lg","body-md":"_131101940be12424__body-md","body-sm":"_0e8d87a42c1f75fa__body-sm"};typeof process>"u",Bp("af6d9984a6","._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}");var Dp={button:"_6defc79820e382c6__button",input:"d2cff2e5dea83bd1__input",textarea:"_547d86373d02e108__textarea",div:"_8c15fd0ed9f28ba4__div",p:"_43cec3e1eec1066d__p",heading:"e97669c6d9a38497__heading",a:"_2c0831b0499dbd6e__a"},vi=(0,Mp.forwardRef)(function({variant:t="body-md",render:r,className:o,...n},s){return vn({render:r,defaultTagName:"span",ref:s,props:er(n,{className:st(Np.text,Dp.heading,Dp.p,Np[t],o)})})});var bi=h(ke(),1),is=(0,bi.forwardRef)(({icon:e,size:t=24,...r},o)=>(0,bi.cloneElement)(e,{width:t,height:t,...r,ref:o}));var wi=h(bn(),1),Nl=h(Y(),1),Do=(0,Nl.jsx)(wi.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,Nl.jsx)(wi.Path,{d:"M14.6 7l-1.2-1L8 12l5.4 6 1.2-1-4.6-5z"})});var xi=h(bn(),1),Dl=h(Y(),1),Mo=(0,Dl.jsx)(xi.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,Dl.jsx)(xi.Path,{d:"M10.6 6L9.4 7l4.6 5-4.6 5 1.2 1 5.4-6z"})});var Si=h(bn(),1),Ml=h(Y(),1),Vl=(0,Ml.jsx)(Si.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,Ml.jsx)(Si.Path,{d:"M13 19h-2v-2h2v2zm0-6h-2v-2h2v2zm0-6h-2V5h2v2z"})});var Ci=h(bn(),1),Bl=h(Y(),1),Ri=(0,Bl.jsx)(Ci.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,Bl.jsx)(Ci.Path,{d:"M6.6 6L5.4 7l4.5 5-4.5 5 1.1 1 5.5-6-5.4-6zm6 0l-1.1 1 4.5 5-4.5 5 1.1 1 5.5-6-5.5-6z"})});var Ei=h(bn(),1),jl=h(Y(),1),Ti=(0,jl.jsx)(Ei.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,jl.jsx)(Ei.Path,{d:"M11.6 7l-1.1-1L5 12l5.5 6 1.1-1L7 12l4.6-5zm6 0l-1.1-1-5.5 6 5.5 6 1.1-1-4.6-5 4.6-5z"})});var Up=h(ke(),1);function zl(e,t,r){return(0,Up.cloneElement)(e??t,{children:r})}var gw=h(Wp(),1);var Yp=h(as(),1),{lock:CA,unlock:qp}=(0,Yp.__dangerousOptInToUnstableAPIsOnlyForCoreModules)("I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.","@wordpress/ui");function yw(){let e=gw;if(e.ThemeProvider)return e.ThemeProvider;if(!e.privateApis)throw new Error("@wordpress/ui: @wordpress/theme must expose `ThemeProvider` or `privateApis.ThemeProvider`.");return qp(e.privateApis).ThemeProvider}var Zp=yw();var Xp=h(ke(),1),Ul="data-wp-hash";function Hl(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&bw(document)),e.__wpStyleRuntime}function vw(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${Ul}]`))if(r.getAttribute(Ul)===t)return!0;return!1}function Kp(e,t,r){if(!e.head)return;let o=Hl(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(vw(e,t)){n.add(t);return}let s=e.createElement("style");s.setAttribute(Ul,t),s.appendChild(e.createTextNode(r)),e.head.appendChild(s),n.add(t)}function bw(e){let t=Hl();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)Kp(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function ww(e,t){let r=Hl();r.styles.set(e,t);for(let o of r.documents.keys())Kp(o,e,t)}typeof process>"u",ww("32aba35fe1","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._19ce0419607e1896__stack{display:flex}}}");var xw={stack:"_19ce0419607e1896__stack"},Sw={xs:"var(--wpds-dimension-gap-xs, 4px)",sm:"var(--wpds-dimension-gap-sm, 8px)",md:"var(--wpds-dimension-gap-md, 12px)",lg:"var(--wpds-dimension-gap-lg, 16px)",xl:"var(--wpds-dimension-gap-xl, 24px)","2xl":"var(--wpds-dimension-gap-2xl, 32px)","3xl":"var(--wpds-dimension-gap-3xl, 40px)"},wn=(0,Xp.forwardRef)(function({direction:t,gap:r,align:o,justify:n,wrap:s,render:i,...a},u){let l={gap:r&&Sw[r],alignItems:o,justifyContent:n,flexDirection:t,flexWrap:s};return vn({render:i,ref:u,props:er(a,{style:l,className:xw.stack})})});var xn={};ro(xn,{Popup:()=>cm,Portal:()=>_i,Positioner:()=>Pi,Provider:()=>vm,Root:()=>gm,Trigger:()=>dm});var am=h(ke(),1);var tm=h(ke(),1);var Gl="data-wp-hash";function Yl(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Rw(document)),e.__wpStyleRuntime}function Cw(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${Gl}]`))if(r.getAttribute(Gl)===t)return!0;return!1}function Qp(e,t,r){if(!e.head)return;let o=Yl(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(Cw(e,t)){n.add(t);return}let s=e.createElement("style");s.setAttribute(Gl,t),s.appendChild(e.createTextNode(r)),e.head.appendChild(s),n.add(t)}function Rw(e){let t=Yl();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)Qp(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function Ew(e,t){let r=Yl();r.styles.set(e,t);for(let o of r.documents.keys())Qp(o,e,t)}typeof process>"u",Ew("be37f31c1e","._11fc52b637ff8a7e__slot{inset:0;isolation:isolate;pointer-events:none;position:fixed;z-index:1000000003}@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._11fc52b637ff8a7e__slot>*{pointer-events:auto}}}");var Jp={slot:"_11fc52b637ff8a7e__slot"},$p="data-wp-compat-overlay-slot";function Tw(){return typeof document>"u"?null:document}function _w(){let e;try{e=window.top?.wp}catch{}let t=e??window.wp;return typeof t?.components=="object"&&t.components!==null}var Ir=null;function Wl(e){return e.setAttribute("aria-hidden","false"),e}function Pw(e){let t=e.createElement("div");return t.setAttribute($p,""),Jp.slot&&t.classList.add(Jp.slot),e.body.appendChild(t),t}function em(){if(typeof window>"u"||!_w()&&window.__wpUiCompatOverlaySlotEnabled!==!0)return;let e=Tw();if(!e||!e.body)return;if(Ir&&Ir.ownerDocument===e&&Ir.isConnected)return Wl(Ir);let t=e.querySelector(`[${$p}]`);return t instanceof HTMLDivElement?(Ir=Wl(t),Ir):(Ir?.isConnected&&Ir.remove(),Ir=Wl(Pw(e)),Ir)}var rm=h(Y(),1),_i=(0,tm.forwardRef)(function({container:t,...r},o){return(0,rm.jsx)(Zt.Portal,{container:t??em(),...r,ref:o})});var om=h(ke(),1),im=h(Y(),1),ql="data-wp-hash";function Zl(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&kw(document)),e.__wpStyleRuntime}function Ow(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${ql}]`))if(r.getAttribute(ql)===t)return!0;return!1}function nm(e,t,r){if(!e.head)return;let o=Zl(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(Ow(e,t)){n.add(t);return}let s=e.createElement("style");s.setAttribute(ql,t),s.appendChild(e.createTextNode(r)),e.head.appendChild(s),n.add(t)}function kw(e){let t=Zl();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)nm(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function sm(e,t){let r=Zl();r.styles.set(e,t);for(let o of r.documents.keys())nm(o,e,t)}typeof process>"u",sm("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var Fw={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",sm("19fcc06039",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}');var Aw={positioner:"_480b748dd3510e64__positioner",popup:"_50096b232db7709d__popup"},Pi=(0,om.forwardRef)(function({align:t="center",className:r,side:o="top",sideOffset:n=4,...s},i){return(0,im.jsx)(Zt.Positioner,{ref:i,align:t,side:o,sideOffset:n,...s,className:st(Fw["box-sizing"],Aw.positioner,r)})});var ls=h(Y(),1),Xl="data-wp-hash";function Kl(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Lw(document)),e.__wpStyleRuntime}function Iw(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${Xl}]`))if(r.getAttribute(Xl)===t)return!0;return!1}function lm(e,t,r){if(!e.head)return;let o=Kl(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(Iw(e,t)){n.add(t);return}let s=e.createElement("style");s.setAttribute(Xl,t),s.appendChild(e.createTextNode(r)),e.head.appendChild(s),n.add(t)}function Lw(e){let t=Kl();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)lm(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function Nw(e,t){let r=Kl();r.styles.set(e,t);for(let o of r.documents.keys())lm(o,e,t)}typeof process>"u",Nw("19fcc06039",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}');var Dw={positioner:"_480b748dd3510e64__positioner",popup:"_50096b232db7709d__popup"},Mw={background:"#1e1e1e"},cm=(0,am.forwardRef)(function({portal:t,positioner:r,children:o,className:n,...s},i){let a=(0,ls.jsx)(Zp,{color:Mw,children:(0,ls.jsx)(Zt.Popup,{ref:i,className:st(Dw.popup,n),...s,children:o})}),u=zl(r,(0,ls.jsx)(Pi,{}),a);return zl(t,(0,ls.jsx)(_i,{}),u)});var um=h(ke(),1),fm=h(Y(),1),dm=(0,um.forwardRef)(function(t,r){return(0,fm.jsx)(Zt.Trigger,{ref:r,...t})});var pm=h(xe(),1),mm=h(Y(),1);function hm({children:e}){return(0,mm.jsx)(ci,{direction:(0,pm.isRTL)()?"rtl":"ltr",children:e})}var Jl=h(Y(),1);function gm(e){return(0,Jl.jsx)(hm,{children:(0,Jl.jsx)(Zt.Root,{...e})})}var ym=h(Y(),1);function vm({...e}){return(0,ym.jsx)(Zt.Provider,{...e})}var wm=h(ke(),1),Ql="data-wp-hash";function $l(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Bw(document)),e.__wpStyleRuntime}function Vw(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${Ql}]`))if(r.getAttribute(Ql)===t)return!0;return!1}function xm(e,t,r){if(!e.head)return;let o=$l(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(Vw(e,t)){n.add(t);return}let s=e.createElement("style");s.setAttribute(Ql,t),s.appendChild(e.createTextNode(r)),e.head.appendChild(s),n.add(t)}function Bw(e){let t=$l();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)xm(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function Sm(e,t){let r=$l();r.styles.set(e,t);for(let o of r.documents.keys())xm(o,e,t)}typeof process>"u",Sm("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var jw={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",Sm("ed2c39ec90","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.b20cc1690085c2f0__skeleton{background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);display:block;@media (forced-colors:active){border:var(--wpds-border-width-xs,1px) solid CanvasText}}._9b143194fdb45f93__pulse{@media not (prefers-reduced-motion){animation:e2b9fe0690281bc8__skeleton-pulse 1.5s ease-in-out infinite}}@keyframes e2b9fe0690281bc8__skeleton-pulse{0%,to{opacity:1}50%{opacity:.4}}}}");var bm={skeleton:"b20cc1690085c2f0__skeleton",pulse:"_9b143194fdb45f93__pulse","skeleton-pulse":"e2b9fe0690281bc8__skeleton-pulse"},ec=(0,wm.forwardRef)(function({render:t,...r},o){return vn({render:t,ref:o,props:er({className:st(bm.skeleton,bm.pulse,jw["box-sizing"]),"aria-hidden":!0},r)})});var Cm=h(ke(),1),Rm=h(Y(),1),Em=(0,Cm.forwardRef)(({children:e,className:t,ariaLabel:r,as:o="div",...n},s)=>(0,Rm.jsx)(o,{ref:s,className:st("admin-ui-navigable-region",t),"aria-label":r,role:"region",tabIndex:"-1",...n,children:e}));Em.displayName="NavigableRegion";var Tm=Em;var Pm=h(ce(),1),{Fill:Om,Slot:km}=(0,Pm.createSlotFill)("SidebarToggle");var ar=h(Y(),1),tc="data-wp-hash";function rc(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Uw(document)),e.__wpStyleRuntime}function zw(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${tc}]`))if(r.getAttribute(tc)===t)return!0;return!1}function Fm(e,t,r){if(!e.head)return;let o=rc(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(zw(e,t)){n.add(t);return}let s=e.createElement("style");s.setAttribute(tc,t),s.appendChild(e.createTextNode(r)),e.head.appendChild(s),n.add(t)}function Uw(e){let t=rc();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)Fm(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function Hw(e,t){let r=rc();r.styles.set(e,t);for(let o of r.documents.keys())Fm(o,e,t)}typeof process>"u",Hw("ddd9aab364","._956b6df0898efed0__page{text-wrap:pretty;background-color:var(--wpds-color-background-surface-neutral,#fcfcfc);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);display:flex;flex-flow:column;height:100%;position:relative;z-index:1}._0625b55e82a0d93d__header{background:var(--wpds-color-background-surface-neutral-strong,#fff);border-block-end:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral-weak,#f0f0f0);inset-block-start:0;padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px);position:sticky;z-index:1}.a43c44d5ae28b2e8__header-content{min-height:var(--wpds-dimension-size-md,32px)}.b7cb5b9daf3a3b25__header-actions{flex-shrink:0}._8113be94e7caf73c__header-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._9a776c7f70996f61__header-visual{display:grid;flex-shrink:0;grid-template-columns:1fr;grid-template-rows:1fr;height:var(--wpds-dimension-size-sm,24px);width:var(--wpds-dimension-size-sm,24px);>*{grid-column:1/-1;grid-row:1/-1;max-height:100%;max-width:100%}}.d5e0920cd15d35bc__sidebar-toggle-slot:empty{display:none}._60fea2f6bf5319cd__header-subtitle{color:var(--wpds-color-foreground-content-neutral-weak,#707070);padding-block-end:var(--wpds-dimension-padding-xs,4px)}.be5e57d029ec4036__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;&._128806d0b26e3a50__has-padding{padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px)}}");var Vo={page:"_956b6df0898efed0__page",header:"_0625b55e82a0d93d__header","header-content":"a43c44d5ae28b2e8__header-content","header-actions":"b7cb5b9daf3a3b25__header-actions","header-title":"_8113be94e7caf73c__header-title","header-visual":"_9a776c7f70996f61__header-visual","sidebar-toggle-slot":"d5e0920cd15d35bc__sidebar-toggle-slot","header-subtitle":"_60fea2f6bf5319cd__header-subtitle",content:"be5e57d029ec4036__content","has-padding":"_128806d0b26e3a50__has-padding"};function Am({headingLevel:e=1,breadcrumbs:t,badges:r,visual:o,title:n,subTitle:s,actions:i,showSidebarToggle:a=!0}){let u=`h${e}`;return(0,ar.jsxs)(wn,{direction:"column",className:Vo.header,children:[(0,ar.jsxs)(wn,{className:Vo["header-content"],direction:"row",gap:"sm",justify:"space-between",children:[(0,ar.jsxs)(wn,{direction:"row",gap:"sm",align:"center",justify:"start",children:[a&&(0,ar.jsx)(km,{bubblesVirtually:!0,className:Vo["sidebar-toggle-slot"]}),o&&(0,ar.jsx)("div",{className:Vo["header-visual"],"aria-hidden":"true",children:o}),n&&(0,ar.jsx)(vi,{className:Vo["header-title"],render:(0,ar.jsx)(u,{}),variant:"heading-lg",children:n}),t,r]}),i&&(0,ar.jsx)(wn,{align:"center",className:Vo["header-actions"],direction:"row",gap:"sm",children:i})]}),s&&(0,ar.jsx)(vi,{render:(0,ar.jsx)("p",{}),variant:"body-md",className:Vo["header-subtitle"],children:s})]})}var cs=h(Y(),1),nc="data-wp-hash";function sc(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Gw(document)),e.__wpStyleRuntime}function Ww(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${nc}]`))if(r.getAttribute(nc)===t)return!0;return!1}function Im(e,t,r){if(!e.head)return;let o=sc(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(Ww(e,t)){n.add(t);return}let s=e.createElement("style");s.setAttribute(nc,t),s.appendChild(e.createTextNode(r)),e.head.appendChild(s),n.add(t)}function Gw(e){let t=sc();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)Im(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function Yw(e,t){let r=sc();r.styles.set(e,t);for(let o of r.documents.keys())Im(o,e,t)}typeof process>"u",Yw("ddd9aab364","._956b6df0898efed0__page{text-wrap:pretty;background-color:var(--wpds-color-background-surface-neutral,#fcfcfc);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);display:flex;flex-flow:column;height:100%;position:relative;z-index:1}._0625b55e82a0d93d__header{background:var(--wpds-color-background-surface-neutral-strong,#fff);border-block-end:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral-weak,#f0f0f0);inset-block-start:0;padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px);position:sticky;z-index:1}.a43c44d5ae28b2e8__header-content{min-height:var(--wpds-dimension-size-md,32px)}.b7cb5b9daf3a3b25__header-actions{flex-shrink:0}._8113be94e7caf73c__header-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._9a776c7f70996f61__header-visual{display:grid;flex-shrink:0;grid-template-columns:1fr;grid-template-rows:1fr;height:var(--wpds-dimension-size-sm,24px);width:var(--wpds-dimension-size-sm,24px);>*{grid-column:1/-1;grid-row:1/-1;max-height:100%;max-width:100%}}.d5e0920cd15d35bc__sidebar-toggle-slot:empty{display:none}._60fea2f6bf5319cd__header-subtitle{color:var(--wpds-color-foreground-content-neutral-weak,#707070);padding-block-end:var(--wpds-dimension-padding-xs,4px)}.be5e57d029ec4036__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;&._128806d0b26e3a50__has-padding{padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px)}}");var oc={page:"_956b6df0898efed0__page",header:"_0625b55e82a0d93d__header","header-content":"a43c44d5ae28b2e8__header-content","header-actions":"b7cb5b9daf3a3b25__header-actions","header-title":"_8113be94e7caf73c__header-title","header-visual":"_9a776c7f70996f61__header-visual","sidebar-toggle-slot":"d5e0920cd15d35bc__sidebar-toggle-slot","header-subtitle":"_60fea2f6bf5319cd__header-subtitle",content:"be5e57d029ec4036__content","has-padding":"_128806d0b26e3a50__has-padding"};function Lm({headingLevel:e,breadcrumbs:t,badges:r,visual:o,title:n,subTitle:s,children:i,className:a,actions:u,ariaLabel:l,hasPadding:c=!1,showSidebarToggle:f=!0}){let m=st(oc.page,a);return(0,cs.jsxs)(Tm,{className:m,ariaLabel:l??(typeof n=="string"?n:""),children:[(n||t||r||u||o)&&(0,cs.jsx)(Am,{headingLevel:e,breadcrumbs:t,badges:r,visual:o,title:n,subTitle:s,actions:u,showSidebarToggle:f}),c?(0,cs.jsx)("div",{className:st(oc.content,oc["has-padding"]),children:i}):i]})}Lm.SidebarToggleFill=Om;var ic=Lm;var jn=h(xe()),uv=h(ce()),fv=h(Dm()),wa=h(nr()),dv=h(Xt()),pv=h(ke());var av=h(ce(),1),lv=h(Sn(),1),D2=h(Xt(),1),M2=h(Dt(),1),wu=h(ke(),1),V2=h(No(),1);function Cn(e,t,r){t=Array.isArray(t)?[...t]:[t],e=Array.isArray(e)?[...e]:{...e};let o=t.pop(),n=e;for(let s of t){let i=n[s];n=n[s]=Array.isArray(i)?[...i]:{...i}}return n[o]=r,e}var vt=(e,t,r)=>{let o=Array.isArray(t)?t:t.split("."),n=e;return o.forEach(s=>{n=n?.[s]}),n??r};var qw=["appearanceTools","useRootPaddingAwareAlignments","background.backgroundImage","background.backgroundRepeat","background.backgroundSize","background.backgroundPosition","background.gradient","border.color","border.radius","border.radiusSizes","border.style","border.width","shadow.presets","shadow.defaultPresets","color.background","color.button","color.caption","color.custom","color.customDuotone","color.customGradient","color.defaultDuotone","color.defaultGradients","color.defaultPalette","color.duotone","color.gradients","color.heading","color.link","color.palette","color.text","custom","dimensions.aspectRatio","dimensions.height","dimensions.minHeight","dimensions.minWidth","dimensions.width","dimensions.dimensionSizes","layout.contentSize","layout.definitions","layout.wideSize","lightbox.enabled","lightbox.allowEditing","position.fixed","position.sticky","spacing.customSpacingSize","spacing.defaultSpacingSizes","spacing.spacingSizes","spacing.spacingScale","spacing.blockGap","spacing.margin","spacing.padding","spacing.units","typography.fluid","typography.customFontSize","typography.defaultFontSizes","typography.dropCap","typography.fontFamilies","typography.fontSizes","typography.fontStyle","typography.fontWeight","typography.letterSpacing","typography.lineHeight","typography.textAlign","typography.textColumns","typography.textDecoration","typography.textIndent","typography.textTransform","typography.writingMode","viewport.mobile","viewport.tablet"];function ac(e,t,r){let o=r?".blocks."+r:"",n=t?"."+t:"",s=`settings${o}${n}`,i=`settings${n}`;if(t)return vt(e,s)??vt(e,i);let a={};return qw.forEach(u=>{let l=vt(e,`settings${o}.${u}`)??vt(e,`settings.${u}`);l!==void 0&&(a=Cn(a,u.split("."),l))}),a}function lc(e,t,r,o){let n=o?".blocks."+o:"",s=t?"."+t:"",i=`settings${n}${s}`;return Cn(e,i.split("."),r)}var Gm=h(Um(),1);var Zw="1600px",Xw="320px",Kw=1,Jw=.25,Qw=.75,$w="14px";function Hm({minimumFontSize:e,maximumFontSize:t,fontSize:r,minimumViewportWidth:o=Xw,maximumViewportWidth:n=Zw,scaleFactor:s=Kw,minimumFontSizeLimit:i}){if(i=Lr(i)?i:$w,r){let b=Lr(r);if(!b?.unit||!b?.value)return null;let R=Lr(i,{coerceTo:b.unit});if(R?.value&&!e&&!t&&b?.value<=R?.value)return null;if(t||(t=`${b.value}${b.unit}`),!e){let A=b.unit==="px"?b.value:b.value*16,T=Math.min(Math.max(1-.075*Math.log2(A),Jw),Qw),_=us(b.value*T,3);R?.value&&_0}function e1(e){let t=e?.typography??{},r=e?.layout,o=Lr(r?.wideSize)?r?.wideSize:null;return cc(t)&&o?{fluid:{maxViewportWidth:o,...typeof t.fluid=="object"?t.fluid:{}}}:{fluid:t?.fluid}}function Wm(e,t){let{size:r}=e;if(!r||r==="0"||e?.fluid===!1||!cc(t?.typography)&&!cc(e))return r;let o=e1(t)?.fluid??{},n=Hm({minimumFontSize:typeof e?.fluid=="boolean"?void 0:e?.fluid?.min,maximumFontSize:typeof e?.fluid=="boolean"?void 0:e?.fluid?.max,fontSize:r,minimumFontSizeLimit:typeof o=="object"?o?.minFontSize:void 0,maximumViewportWidth:typeof o=="object"?o?.maxViewportWidth:void 0,minimumViewportWidth:typeof o=="object"?o?.minViewportWidth:void 0});return n||r}var t1=[{path:["color","palette"],valueKey:"color",cssVarInfix:"color",classes:[{classSuffix:"color",propertyName:"color"},{classSuffix:"background-color",propertyName:"background-color"},{classSuffix:"border-color",propertyName:"border-color"}]},{path:["color","gradients"],valueKey:"gradient",cssVarInfix:"gradient",classes:[{classSuffix:"gradient-background",propertyName:"background"}]},{path:["color","duotone"],valueKey:"colors",cssVarInfix:"duotone",valueFunc:({slug:e})=>`url( '#wp-duotone-${e}' )`,classes:[]},{path:["shadow","presets"],valueKey:"shadow",cssVarInfix:"shadow",classes:[]},{path:["typography","fontSizes"],valueFunc:(e,t)=>Wm(e,t),valueKey:"size",cssVarInfix:"font-size",classes:[{classSuffix:"font-size",propertyName:"font-size"}]},{path:["typography","fontFamilies"],valueKey:"fontFamily",cssVarInfix:"font-family",classes:[{classSuffix:"font-family",propertyName:"font-family"}]},{path:["spacing","spacingSizes"],valueKey:"size",cssVarInfix:"spacing",valueFunc:({size:e})=>e,classes:[]},{path:["border","radiusSizes"],valueKey:"size",cssVarInfix:"border-radius",classes:[]},{path:["dimensions","dimensionSizes"],valueKey:"size",cssVarInfix:"dimension",classes:[]}];function r1(e,t){if(!e||!t)return e;if(typeof e=="object"&&"ref"in e&&e?.ref){let r=(0,Gm.getCSSValueFromRawStyle)(vt(t,e.ref));return typeof r=="object"&&r!==null&&"ref"in r&&r?.ref?void 0:r===void 0?e:r}return e}function o1(e,t){if(!e||!t||!Array.isArray(t))return e;let r=t.find(o=>o?.name===e);return r?.href?r?.href:e}function Ym(e,t){if(!e||!t)return e;let r=r1(e,t);return typeof r=="object"&&r!==null&&"url"in r&&r?.url&&(r.url=o1(r.url,t?._links?.["wp:theme-file"])),r}function qm(e,t,r=[],o="slug",n){let s=[t?vt(e,["blocks",t,...r]):void 0,vt(e,r)].filter(Boolean);for(let i of s)if(i){let a=["custom","theme","default"];for(let u of a){let l=i[u];if(l){let c=l.find(f=>f[o]===n);if(c)return o==="slug"||qm(e,t,r,"slug",c.slug)[o]===c[o]?c:void 0}}}}function n1(e,t,r,[o,n]=[]){let s=t1.find(a=>a.cssVarInfix===o);if(!s||!e.settings)return r;let i=qm(e.settings,t,s.path,"slug",n);if(i){let{valueKey:a}=s,u=i[a];return Oi(e,t,u)}return r}function s1(e,t,r,o=[]){let n=(t?vt(e?.settings??{},["blocks",t,"custom",...o]):void 0)??vt(e?.settings??{},["custom",...o]);return n?Oi(e,t,n):r}function Oi(e,t,r){if(!r||typeof r!="string")if(typeof r=="object"&&r!==null&&"ref"in r&&typeof r.ref=="string"){let l=vt(e,r.ref);if(!l||typeof l=="object"&&"ref"in l)return l;r=l}else return r;let o="var:",n="var(--wp--",s=")",i;if(r.startsWith(o))i=r.slice(o.length).split("|");else if(r.startsWith(n)&&r.endsWith(s))i=r.slice(n.length,-s.length).split("--");else return r;let[a,...u]=i;return a==="preset"?n1(e,t,r,u):a==="custom"?s1(e,t,r,u):r}function ki(e,t,r,o=!0){let n=t?"."+t:"",s=r?`styles.blocks.${r}${n}`:`styles${n}`;if(!e)return;let i=vt(e,s),a=void 0;if(i===void 0&&a){let l=!0,c=e;for(let f of s.split(".")){if(!c||typeof c!="object"||!Object.hasOwn(c,f)){l=!1;break}c=c[f]}l||(i=vt(e,a))}return o?Oi(e,r,i):i}function uc(e,t,r,o){let n=t?"."+t:"",s=o?`styles.blocks.${o}${n}`:`styles${n}`;return Cn(e,s.split("."),r)}var fc=h(Xm(),1);function fs(e,t){return typeof e!="object"||typeof t!="object"?e===t:(0,fc.default)(e?.styles,t?.styles)&&(0,fc.default)(e?.settings,t?.settings)}var rh=h($m(),1);function eh(e){return Object.prototype.toString.call(e)==="[object Object]"}function th(e){var t,r;return eh(e)===!1?!1:(t=e.constructor,t===void 0?!0:(r=t.prototype,!(eh(r)===!1||r.hasOwnProperty("isPrototypeOf")===!1)))}function Bo(e,t){return(0,rh.default)(e,t,{isMergeableObject:th,customMerge:r=>{if(r==="backgroundImage")return(o,n)=>n??o}})}var b1={grad:.9,turn:360,rad:360/(2*Math.PI)},Zr=function(e){return typeof e=="string"?e.length>0:typeof e=="number"},St=function(e,t,r){return t===void 0&&(t=0),r===void 0&&(r=Math.pow(10,t)),Math.round(r*e)/r+0},cr=function(e,t,r){return t===void 0&&(t=0),r===void 0&&(r=1),e>r?r:e>t?e:t},uh=function(e){return(e=isFinite(e)?e%360:0)>0?e:e+360},oh=function(e){return{r:cr(e.r,0,255),g:cr(e.g,0,255),b:cr(e.b,0,255),a:cr(e.a)}},dc=function(e){return{r:St(e.r),g:St(e.g),b:St(e.b),a:St(e.a,3)}},w1=/^#([0-9a-f]{3,8})$/i,Fi=function(e){var t=e.toString(16);return t.length<2?"0"+t:t},fh=function(e){var t=e.r,r=e.g,o=e.b,n=e.a,s=Math.max(t,r,o),i=s-Math.min(t,r,o),a=i?s===t?(r-o)/i:s===r?2+(o-t)/i:4+(t-r)/i:0;return{h:60*(a<0?a+6:a),s:s?i/s*100:0,v:s/255*100,a:n}},dh=function(e){var t=e.h,r=e.s,o=e.v,n=e.a;t=t/360*6,r/=100,o/=100;var s=Math.floor(t),i=o*(1-r),a=o*(1-(t-s)*r),u=o*(1-(1-t+s)*r),l=s%6;return{r:255*[o,a,i,i,u,o][l],g:255*[u,o,o,a,i,i][l],b:255*[i,i,u,o,o,a][l],a:n}},nh=function(e){return{h:uh(e.h),s:cr(e.s,0,100),l:cr(e.l,0,100),a:cr(e.a)}},sh=function(e){return{h:St(e.h),s:St(e.s),l:St(e.l),a:St(e.a,3)}},ih=function(e){return dh((r=(t=e).s,{h:t.h,s:(r*=((o=t.l)<50?o:100-o)/100)>0?2*r/(o+r)*100:0,v:o+r,a:t.a}));var t,r,o},ps=function(e){return{h:(t=fh(e)).h,s:(n=(200-(r=t.s))*(o=t.v)/100)>0&&n<200?r*o/100/(n<=100?n:200-n)*100:0,l:n/2,a:t.a};var t,r,o,n},x1=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s*,\s*([+-]?\d*\.?\d+)%\s*,\s*([+-]?\d*\.?\d+)%\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,S1=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s+([+-]?\d*\.?\d+)%\s+([+-]?\d*\.?\d+)%\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,C1=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,R1=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,hc={string:[[function(e){var t=w1.exec(e);return t?(e=t[1]).length<=4?{r:parseInt(e[0]+e[0],16),g:parseInt(e[1]+e[1],16),b:parseInt(e[2]+e[2],16),a:e.length===4?St(parseInt(e[3]+e[3],16)/255,2):1}:e.length===6||e.length===8?{r:parseInt(e.substr(0,2),16),g:parseInt(e.substr(2,2),16),b:parseInt(e.substr(4,2),16),a:e.length===8?St(parseInt(e.substr(6,2),16)/255,2):1}:null:null},"hex"],[function(e){var t=C1.exec(e)||R1.exec(e);return t?t[2]!==t[4]||t[4]!==t[6]?null:oh({r:Number(t[1])/(t[2]?100/255:1),g:Number(t[3])/(t[4]?100/255:1),b:Number(t[5])/(t[6]?100/255:1),a:t[7]===void 0?1:Number(t[7])/(t[8]?100:1)}):null},"rgb"],[function(e){var t=x1.exec(e)||S1.exec(e);if(!t)return null;var r,o,n=nh({h:(r=t[1],o=t[2],o===void 0&&(o="deg"),Number(r)*(b1[o]||1)),s:Number(t[3]),l:Number(t[4]),a:t[5]===void 0?1:Number(t[5])/(t[6]?100:1)});return ih(n)},"hsl"]],object:[[function(e){var t=e.r,r=e.g,o=e.b,n=e.a,s=n===void 0?1:n;return Zr(t)&&Zr(r)&&Zr(o)?oh({r:Number(t),g:Number(r),b:Number(o),a:Number(s)}):null},"rgb"],[function(e){var t=e.h,r=e.s,o=e.l,n=e.a,s=n===void 0?1:n;if(!Zr(t)||!Zr(r)||!Zr(o))return null;var i=nh({h:Number(t),s:Number(r),l:Number(o),a:Number(s)});return ih(i)},"hsl"],[function(e){var t=e.h,r=e.s,o=e.v,n=e.a,s=n===void 0?1:n;if(!Zr(t)||!Zr(r)||!Zr(o))return null;var i=(function(a){return{h:uh(a.h),s:cr(a.s,0,100),v:cr(a.v,0,100),a:cr(a.a)}})({h:Number(t),s:Number(r),v:Number(o),a:Number(s)});return dh(i)},"hsv"]]},ah=function(e,t){for(var r=0;r=.5},e.prototype.toHex=function(){return t=dc(this.rgba),r=t.r,o=t.g,n=t.b,i=(s=t.a)<1?Fi(St(255*s)):"","#"+Fi(r)+Fi(o)+Fi(n)+i;var t,r,o,n,s,i},e.prototype.toRgb=function(){return dc(this.rgba)},e.prototype.toRgbString=function(){return t=dc(this.rgba),r=t.r,o=t.g,n=t.b,(s=t.a)<1?"rgba("+r+", "+o+", "+n+", "+s+")":"rgb("+r+", "+o+", "+n+")";var t,r,o,n,s},e.prototype.toHsl=function(){return sh(ps(this.rgba))},e.prototype.toHslString=function(){return t=sh(ps(this.rgba)),r=t.h,o=t.s,n=t.l,(s=t.a)<1?"hsla("+r+", "+o+"%, "+n+"%, "+s+")":"hsl("+r+", "+o+"%, "+n+"%)";var t,r,o,n,s},e.prototype.toHsv=function(){return t=fh(this.rgba),{h:St(t.h),s:St(t.s),v:St(t.v),a:St(t.a,3)};var t},e.prototype.invert=function(){return lr({r:255-(t=this.rgba).r,g:255-t.g,b:255-t.b,a:t.a});var t},e.prototype.saturate=function(t){return t===void 0&&(t=.1),lr(pc(this.rgba,t))},e.prototype.desaturate=function(t){return t===void 0&&(t=.1),lr(pc(this.rgba,-t))},e.prototype.grayscale=function(){return lr(pc(this.rgba,-1))},e.prototype.lighten=function(t){return t===void 0&&(t=.1),lr(lh(this.rgba,t))},e.prototype.darken=function(t){return t===void 0&&(t=.1),lr(lh(this.rgba,-t))},e.prototype.rotate=function(t){return t===void 0&&(t=15),this.hue(this.hue()+t)},e.prototype.alpha=function(t){return typeof t=="number"?lr({r:(r=this.rgba).r,g:r.g,b:r.b,a:t}):St(this.rgba.a,3);var r},e.prototype.hue=function(t){var r=ps(this.rgba);return typeof t=="number"?lr({h:t,s:r.s,l:r.l,a:r.a}):St(r.h)},e.prototype.isEqual=function(t){return this.toHex()===lr(t).toHex()},e})(),lr=function(e){return e instanceof gc?e:new gc(e)},ch=[],ph=function(e){e.forEach(function(t){ch.indexOf(t)<0&&(t(gc,hc),ch.push(t))})};function T1(e=[]){let t={r:[],g:[],b:[],a:[]};return e.forEach(r=>{let o=lr(r).toRgb();t.r.push(o.r/255),t.g.push(o.g/255),t.b.push(o.b/255),t.a.push(o.a)}),t}function mh(e){return`${e}{filter:none}`}function hh(e,t){return`${e}{filter:url(#${t})}`}function gh(e,t){let r=T1(t);return` +var Uv=Object.create;var ka=Object.defineProperty;var Wv=Object.getOwnPropertyDescriptor;var Gv=Object.getOwnPropertyNames;var Yv=Object.getPrototypeOf,qv=Object.prototype.hasOwnProperty;var Wt=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof require<"u"?require:t)[r]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var tt=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),so=(e,t)=>{for(var r in t)ka(e,r,{get:t[r],enumerable:!0})},Zv=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Gv(t))!qv.call(e,n)&&n!==r&&ka(e,n,{get:()=>t[n],enumerable:!(o=Wv(t,n))||o.enumerable});return e};var f=(e,t,r)=>(r=e!=null?Uv(Yv(e)):{},Zv(t||!e||!e.__esModule?ka(r,"default",{value:e,enumerable:!0}):r,e));var ge=tt((ME,zu)=>{zu.exports=window.wp.i18n});var Te=tt((DE,Uu)=>{Uu.exports=window.wp.element});var ve=tt((BE,Wu)=>{Wu.exports=window.React});var Z=tt((YE,Zu)=>{Zu.exports=window.ReactJSXRuntime});var lo=tt((jT,wf)=>{wf.exports=window.ReactDOM});var xd=tt(wd=>{"use strict";var fn=ve();function Z0(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var X0=typeof Object.is=="function"?Object.is:Z0,K0=fn.useState,J0=fn.useEffect,Q0=fn.useLayoutEffect,$0=fn.useDebugValue;function ew(e,t){var r=t(),o=K0({inst:{value:r,getSnapshot:t}}),n=o[0].inst,i=o[1];return Q0(function(){n.value=r,n.getSnapshot=t,dl(n)&&i({inst:n})},[e,r,t]),J0(function(){return dl(n)&&i({inst:n}),e(function(){dl(n)&&i({inst:n})})},[e]),$0(r),r}function dl(e){var t=e.getSnapshot;e=e.value;try{var r=t();return!X0(e,r)}catch{return!0}}function tw(e,t){return t()}var rw=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?tw:ew;wd.useSyncExternalStore=fn.useSyncExternalStore!==void 0?fn.useSyncExternalStore:rw});var ts=tt((FO,Sd)=>{"use strict";Sd.exports=xd()});var _d=tt(Cd=>{"use strict";var rs=ve(),ow=ts();function nw(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var iw=typeof Object.is=="function"?Object.is:nw,sw=ow.useSyncExternalStore,aw=rs.useRef,lw=rs.useEffect,cw=rs.useMemo,uw=rs.useDebugValue;Cd.useSyncExternalStoreWithSelector=function(e,t,r,o,n){var i=aw(null);if(i.current===null){var s={hasValue:!1,value:null};i.current=s}else s=i.current;i=cw(function(){function u(h){if(!l){if(l=!0,c=h,h=o(h),n!==void 0&&s.hasValue){var g=s.value;if(n(g,h))return m=g}return m=h}if(g=m,iw(c,h))return g;var b=o(h);return n!==void 0&&n(g,b)?(c=h,g):(c=h,m=b)}var l=!1,c,m,d=r===void 0?null:r;return[function(){return u(t())},d===null?void 0:function(){return u(d())}]},[t,r,o,n]);var a=sw(e,i[0],i[1]);return lw(function(){s.hasValue=!0,s.value=a},[a]),uw(a),a}});var Ed=tt((IO,Rd)=>{"use strict";Rd.exports=_d()});var xn=tt((B5,rm)=>{rm.exports=window.wp.primitives});var yo=tt((j5,om)=>{om.exports=window.wp.compose});var gm=tt((uA,hm)=>{hm.exports=window.wp.theme});var li=tt((fA,ym)=>{ym.exports=window.wp.privateApis});var ue=tt((w4,Jm)=>{Jm.exports=window.wp.components});var sh=tt((L4,ih)=>{ih.exports=window.wp.editor});var sr=tt((N4,ah)=>{ah.exports=window.wp.coreData});var Kt=tt((M4,lh)=>{lh.exports=window.wp.data});var _n=tt((V4,ch)=>{ch.exports=window.wp.blocks});var Dt=tt((D4,uh)=>{uh.exports=window.wp.blockEditor});var dh=tt((W4,fh)=>{fh.exports=window.wp.styleEngine});var bh=tt((rI,vh)=>{"use strict";vh.exports=function e(t,r){if(t===r)return!0;if(t&&r&&typeof t=="object"&&typeof r=="object"){if(t.constructor!==r.constructor)return!1;var o,n,i;if(Array.isArray(t)){if(o=t.length,o!=r.length)return!1;for(n=o;n--!==0;)if(!e(t[n],r[n]))return!1;return!0}if(t instanceof Map&&r instanceof Map){if(t.size!==r.size)return!1;for(n of t.entries())if(!r.has(n[0]))return!1;for(n of t.entries())if(!e(n[1],r.get(n[0])))return!1;return!0}if(t instanceof Set&&r instanceof Set){if(t.size!==r.size)return!1;for(n of t.entries())if(!r.has(n[0]))return!1;return!0}if(ArrayBuffer.isView(t)&&ArrayBuffer.isView(r)){if(o=t.length,o!=r.length)return!1;for(n=o;n--!==0;)if(t[n]!==r[n])return!1;return!0}if(t.constructor===RegExp)return t.source===r.source&&t.flags===r.flags;if(t.valueOf!==Object.prototype.valueOf)return t.valueOf()===r.valueOf();if(t.toString!==Object.prototype.toString)return t.toString()===r.toString();if(i=Object.keys(t),o=i.length,o!==Object.keys(r).length)return!1;for(n=o;n--!==0;)if(!Object.prototype.hasOwnProperty.call(r,i[n]))return!1;for(n=o;n--!==0;){var s=i[n];if(!e(t[s],r[s]))return!1}return!0}return t!==t&&r!==r}});var Ch=tt((nI,Sh)=>{"use strict";var W1=function(t){return G1(t)&&!Y1(t)};function G1(e){return!!e&&typeof e=="object"}function Y1(e){var t=Object.prototype.toString.call(e);return t==="[object RegExp]"||t==="[object Date]"||X1(e)}var q1=typeof Symbol=="function"&&Symbol.for,Z1=q1?Symbol.for("react.element"):60103;function X1(e){return e.$$typeof===Z1}function K1(e){return Array.isArray(e)?[]:{}}function mi(e,t){return t.clone!==!1&&t.isMergeableObject(e)?En(K1(e),e,t):e}function J1(e,t,r){return e.concat(t).map(function(o){return mi(o,r)})}function Q1(e,t){if(!t.customMerge)return En;var r=t.customMerge(e);return typeof r=="function"?r:En}function $1(e){return Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(e).filter(function(t){return Object.propertyIsEnumerable.call(e,t)}):[]}function wh(e){return Object.keys(e).concat($1(e))}function xh(e,t){try{return t in e}catch{return!1}}function ex(e,t){return xh(e,t)&&!(Object.hasOwnProperty.call(e,t)&&Object.propertyIsEnumerable.call(e,t))}function tx(e,t,r){var o={};return r.isMergeableObject(e)&&wh(e).forEach(function(n){o[n]=mi(e[n],r)}),wh(t).forEach(function(n){ex(e,n)||(xh(e,n)&&r.isMergeableObject(t[n])?o[n]=Q1(n,r)(e[n],t[n],r):o[n]=mi(t[n],r))}),o}function En(e,t,r){r=r||{},r.arrayMerge=r.arrayMerge||J1,r.isMergeableObject=r.isMergeableObject||W1,r.cloneUnlessOtherwiseSpecified=mi;var o=Array.isArray(t),n=Array.isArray(e),i=o===n;return i?o?r.arrayMerge(e,t,r):tx(e,t,r):mi(t,r)}En.all=function(t,r){if(!Array.isArray(t))throw new Error("first argument should be an array");return t.reduce(function(o,n){return En(o,n,r)},{})};var rx=En;Sh.exports=rx});var Qc=tt((JN,Ng)=>{Ng.exports=window.wp.keycodes});var Bg=tt((c8,Dg)=>{Dg.exports=window.wp.apiFetch});var Sv=tt((o7,xv)=>{xv.exports=window.wp.date});function Hu(e){var t,r,o="";if(typeof e=="string"||typeof e=="number")o+=e;else if(typeof e=="object")if(Array.isArray(e)){var n=e.length;for(t=0;te();function Pe(e){let t=Ct(Qv).current;return t.next=e,Jv(t.effect),t.trampoline}function Qv(){let e={next:void 0,callback:$v,trampoline:(...t)=>e.callback?.(...t),effect:()=>{e.callback=e.next}};return e}function $v(){}var qu=f(ve(),1),eb=()=>{},we=typeof document<"u"?qu.useLayoutEffect:eb;function tb(e,t){return function(o,...n){let i=new URL(e);return i.searchParams.set("code",o.toString()),n.forEach(s=>i.searchParams.append("args[]",s)),`${t} error #${o}; visit ${i} for the full message.`}}var rb=tb("https://base-ui.com/production-error","Base UI"),lr=rb;var Ao=f(ve(),1);function Aa(e,t,r,o){let n=Ct(Ku).current;return ob(n,e,t,r,o)&&Ju(n,[e,t,r,o]),n.callback}function Xu(e){let t=Ct(Ku).current;return nb(t,e)&&Ju(t,e),t.callback}function Ku(){return{callback:null,cleanup:null,refs:[]}}function ob(e,t,r,o,n){return e.refs[0]!==t||e.refs[1]!==r||e.refs[2]!==o||e.refs[3]!==n}function nb(e,t){return e.refs.length!==t.length||e.refs.some((r,o)=>r!==t[o])}function Ju(e,t){if(e.refs=t,t.every(r=>r==null)){e.callback=null;return}e.callback=r=>{if(e.cleanup&&(e.cleanup(),e.cleanup=null),r!=null){let o=Array(t.length).fill(null);for(let n=0;n{for(let n=0;n=e}function Ia(e){if(!$u.isValidElement(e))return null;let t=e,r=t.props;return(rn(19)?r?.ref:t.ref)??null}function Yn(e,t){if(e&&!t)return e;if(!e&&t)return t;if(e||t)return{...e,...t}}function tr(){}var ef=Object.freeze([]),nt=Object.freeze({});function tf(e,t){let r={};for(let o in e){let n=e[o];if(t?.hasOwnProperty(o)){let i=t[o](n);i!=null&&Object.assign(r,i);continue}n===!0?r[`data-${o.toLowerCase()}`]="":n&&(r[`data-${o.toLowerCase()}`]=n.toString())}return r}function rf(e,t){return typeof e=="function"?e(t):e}function of(e,t){return typeof e=="function"?e(t):e}var La={};function It(e,t,r,o,n){if(!r&&!o&&!n&&!e)return Ai(t);let i=Ai(e);return t&&(i=qn(i,t)),r&&(i=qn(i,r)),o&&(i=qn(i,o)),n&&(i=qn(i,n)),i}function nf(e){if(e.length===0)return La;if(e.length===1)return Ai(e[0]);let t=Ai(e[0]);for(let r=1;r=65&&n<=90&&(typeof t=="function"||typeof t>"u")}function Na(e){return typeof e=="function"}function af(e,t){return Na(e)?e(t):e??La}function lb(e,t){return t?e?(...r)=>{let o=r[0];if(uf(o)){let i=o;cf(i);let s=t(...r);return i.baseUIHandlerPrevented||e?.(...r),s}let n=t(...r);return e?.(...r),n}:lf(t):e}function lf(e){return e&&((...t)=>{let r=t[0];return uf(r)&&cf(r),e(...t)})}function cf(e){return e.preventBaseUIHandler=()=>{e.baseUIHandlerPrevented=!0},e}function Ma(e,t){return t?e?t+" "+e:t:e}function uf(e){return e!=null&&typeof e=="object"&&"nativeEvent"in e}var Va=f(ve(),1);function Gt(e,t,r={}){let o=t.render,n=cb(t,r);if(r.enabled===!1)return null;let i=r.state??nt;return db(e,o,n,i)}function cb(e,t={}){let{className:r,style:o,render:n}=e,{state:i=nt,ref:s,props:a,stateAttributesMapping:u,enabled:l=!0}=t,c=l?rf(r,i):void 0,m=l?of(o,i):void 0,d=l?tf(i,u):nt,h=l&&a?ub(a):void 0,g=l?Yn(d,h)??{}:nt;return typeof document<"u"&&(l?Array.isArray(s)?g.ref=Xu([g.ref,Ia(n),...s]):g.ref=Aa(g.ref,Ia(n),s):Aa(null,null)),l?(c!==void 0&&(g.className=Ma(g.className,c)),m!==void 0&&(g.style=Yn(g.style,m)),g):nt}function ub(e){return Array.isArray(e)?nf(e):It(void 0,e)}var fb=Symbol.for("react.lazy");function db(e,t,r,o){if(t){if(typeof t=="function")return t(r,o);let n=It(r,t.props);n.ref=r.ref;let i=t;return i?.$$typeof===fb&&(i=Ao.Children.toArray(t)[0]),Ao.cloneElement(i,n)}if(e&&typeof e=="string")return pb(e,r);throw new Error(lr(8))}function pb(e,t){return e==="button"?(0,Va.createElement)("button",{type:"button",...t,key:t.key}):e==="img"?(0,Va.createElement)("img",{alt:"",...t,key:t.key}):Ao.createElement(e,t)}var Ii=f(ve(),1);var ff=0;function mb(e,t="mui"){let[r,o]=Ii.useState(e),n=e||r;return Ii.useEffect(()=>{r==null&&(ff+=1,o(`${t}-${ff}`))},[r,t]),n}var df=Gn.useId;function on(e,t){if(df!==void 0){let r=df();return e??(t?`${t}-${r}`:r)}return mb(e,t)}function pf(e){return on(e,"base-ui")}var Oe={};so(Oe,{cancelOpen:()=>Hb,chipRemovePress:()=>_b,clearPress:()=>Cb,closePress:()=>xb,closeWatcher:()=>Nb,decrementPress:()=>Tb,disabled:()=>Wb,drag:()=>Bb,escapeKey:()=>Lb,focusOut:()=>Ib,imperativeAction:()=>qb,incrementPress:()=>Eb,initial:()=>Yb,inputBlur:()=>kb,inputChange:()=>Pb,inputClear:()=>Ob,inputPaste:()=>Fb,inputPress:()=>Ab,itemPress:()=>wb,keyboard:()=>Vb,linkPress:()=>Sb,listNavigation:()=>Mb,missing:()=>Gb,none:()=>hb,outsidePress:()=>bb,pointer:()=>Db,scrub:()=>zb,siblingOpen:()=>Ub,swipe:()=>Zb,trackPress:()=>Rb,triggerFocus:()=>vb,triggerHover:()=>yb,triggerPress:()=>gb,wheel:()=>jb,windowResize:()=>Xb});var hb="none",gb="trigger-press",yb="trigger-hover",vb="trigger-focus",bb="outside-press",wb="item-press",xb="close-press",Sb="link-press",Cb="clear-press",_b="chip-remove-press",Rb="track-press",Eb="increment-press",Tb="decrement-press",Pb="input-change",Ob="input-clear",kb="input-blur",Fb="input-paste",Ab="input-press",Ib="focus-out",Lb="escape-key",Nb="close-watcher",Mb="list-navigation",Vb="keyboard",Db="pointer",Bb="drag",jb="wheel",zb="scrub",Hb="cancel-open",Ub="sibling-open",Wb="disabled",Gb="missing",Yb="initial",qb="imperative-action",Zb="swipe",Xb="window-resize";function De(e,t,r,o){let n=!1,i=!1,s=o??nt;return{reason:e,event:t??new Event("base-ui"),cancel(){n=!0},allowPropagation(){i=!0},get isCanceled(){return n},get isPropagationAllowed(){return i},trigger:r,...s}}var Ba=f(ve(),1);var mf=f(ve(),1);function nn(e){mf.useEffect(e,ef)}var Li=null,TT=globalThis.requestAnimationFrame,Da=class{callbacks=[];callbacksCount=0;nextId=1;startId=1;isScheduled=!1;tick=t=>{this.isScheduled=!1;let r=this.callbacks,o=this.callbacksCount;if(this.callbacks=[],this.callbacksCount=0,this.startId=this.nextId,o>0)for(let n=0;n=this.callbacks.length||(this.callbacks[r]=null,this.callbacksCount-=1)}},Ni=new Da;var kr=class e{static create(){return new e}static request(t){return Ni.request(t)}static cancel(t){return Ni.cancel(t)}currentId=Li;request(t){this.cancel(),this.currentId=Ni.request(()=>{this.currentId=Li,t()})}cancel=()=>{this.currentId!==Li&&(Ni.cancel(this.currentId),this.currentId=Li)};disposeEffect=()=>this.cancel};function sn(){let e=Ct(kr.create).current;return nn(e.disposeEffect),e}function hf(e,t=!1,r=!1){let[o,n]=Ba.useState(e&&t?"idle":void 0),[i,s]=Ba.useState(e);return e&&!i&&(s(!0),n("starting")),!e&&i&&o!=="ending"&&!r&&n("ending"),!e&&!i&&o==="ending"&&n(void 0),we(()=>{if(!e&&i&&o!=="ending"&&r){let a=kr.request(()=>{n("ending")});return()=>{kr.cancel(a)}}},[e,i,o,r]),we(()=>{if(!e||t)return;let a=kr.request(()=>{n(void 0)});return()=>{kr.cancel(a)}},[t,e]),we(()=>{if(!e||!t)return;e&&i&&o!=="idle"&&n("starting");let a=kr.request(()=>{n("idle")});return()=>{kr.cancel(a)}},[t,e,i,o]),{mounted:i,setMounted:s,transitionStatus:o}}var ja=(function(e){return e.startingStyle="data-starting-style",e.endingStyle="data-ending-style",e})({}),Kb={"data-starting-style":""},Jb={"data-ending-style":""},gf={transitionStatus(e){return e==="starting"?Kb:e==="ending"?Jb:null}};function Mi(){return typeof window<"u"}function Lo(e){return Vi(e)?(e.nodeName||"").toLowerCase():"#document"}function it(e){var t;return(e==null||(t=e.ownerDocument)==null?void 0:t.defaultView)||window}function Ar(e){var t;return(t=(Vi(e)?e.ownerDocument:e.document)||window.document)==null?void 0:t.documentElement}function Vi(e){return Mi()?e instanceof Node||e instanceof it(e).Node:!1}function Re(e){return Mi()?e instanceof Element||e instanceof it(e).Element:!1}function _t(e){return Mi()?e instanceof HTMLElement||e instanceof it(e).HTMLElement:!1}function an(e){return!Mi()||typeof ShadowRoot>"u"?!1:e instanceof ShadowRoot||e instanceof it(e).ShadowRoot}function Zn(e){let{overflow:t,overflowX:r,overflowY:o,display:n}=Lt(e);return/auto|scroll|overlay|hidden|clip/.test(t+o+r)&&n!=="inline"&&n!=="contents"}function yf(e){return/^(table|td|th)$/.test(Lo(e))}function Xn(e){try{if(e.matches(":popover-open"))return!0}catch{}try{return e.matches(":modal")}catch{return!1}}var Qb=/transform|translate|scale|rotate|perspective|filter/,$b=/paint|layout|strict|content/,Io=e=>!!e&&e!=="none",za;function Di(e){let t=Re(e)?Lt(e):e;return Io(t.transform)||Io(t.translate)||Io(t.scale)||Io(t.rotate)||Io(t.perspective)||!Bi()&&(Io(t.backdropFilter)||Io(t.filter))||Qb.test(t.willChange||"")||$b.test(t.contain||"")}function vf(e){let t=Fr(e);for(;_t(t)&&!Ir(t);){if(Di(t))return t;if(Xn(t))return null;t=Fr(t)}return null}function Bi(){return za==null&&(za=typeof CSS<"u"&&CSS.supports&&CSS.supports("-webkit-backdrop-filter","none")),za}function Ir(e){return/^(html|body|#document)$/.test(Lo(e))}function Lt(e){return it(e).getComputedStyle(e)}function Kn(e){return Re(e)?{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}:{scrollLeft:e.scrollX,scrollTop:e.scrollY}}function Fr(e){if(Lo(e)==="html")return e;let t=e.assignedSlot||e.parentNode||an(e)&&e.host||Ar(e);return an(t)?t.host:t}function bf(e){let t=Fr(e);return Ir(t)?(e.ownerDocument||e).body:_t(t)&&Zn(t)?t:bf(t)}function ao(e,t,r){var o;t===void 0&&(t=[]),r===void 0&&(r=!0);let n=bf(e),i=n===((o=e.ownerDocument)==null?void 0:o.body),s=it(n);if(i){let a=ji(s);return t.concat(s,s.visualViewport||[],Zn(n)?n:[],a&&r?ao(a):[])}else return t.concat(n,ao(n,[],r))}function ji(e){return e.parent&&Object.getPrototypeOf(e.parent)?e.frameElement:null}function Rt(e){return e?.ownerDocument||document}function ze(e,t,r,o){return e.addEventListener(t,r,o),()=>{e.removeEventListener(t,r,o)}}function Yt(e){let t=Ct(e0,e).current;return t.next=e,we(t.effect),t}function e0(e){let t={current:e,next:e,effect:()=>{t.current=t.next}};return t}var Cf=f(ve(),1);var Sf=f(lo(),1);function xf(e){return e==null?e:"current"in e?e.current:e}function ln(e,t=!1){let r=sn();return Pe((o,n=null)=>{r.cancel();let i=xf(e);if(i==null)return;let s=i,a=()=>{Sf.flushSync(o)};if(typeof s.getAnimations!="function"||globalThis.BASE_UI_ANIMATIONS_DISABLED){o();return}function u(){Promise.all(s.getAnimations().map(l=>l.finished)).then(()=>{n?.aborted||a()},()=>{if(n?.aborted)return;if(s.getAnimations().some(c=>c.pending||c.playState!=="finished")){u();return}a()})}if(t){let l="data-starting-style";if(!s.hasAttribute(l)){r.request(u);return}let c=new MutationObserver(()=>{s.hasAttribute(l)||(c.disconnect(),u())});c.observe(s,{attributes:!0,attributeFilter:[l]}),n?.addEventListener("abort",()=>c.disconnect(),{once:!0});return}r.request(u)})}function zi(e){let{enabled:t=!0,open:r,ref:o,onComplete:n}=e,i=Pe(n),s=ln(o,r);Cf.useEffect(()=>{if(!t)return;let a=new AbortController;return s(i,a.signal),()=>{a.abort()}},[t,r,i,s])}var Zr={};so(Zr,{engine:()=>Ya,env:()=>Za,os:()=>Wa,screenReader:()=>qa});var Wa={};so(Wa,{android:()=>Ef,apple:()=>Ua,ios:()=>Ha,linux:()=>i0,mac:()=>Tf,windows:()=>n0});function t0(){return typeof navigator>"u"?{userAgent:"",platform:"",maxTouchPoints:0}:{userAgent:navigator.userAgent,platform:navigator.platform??"",maxTouchPoints:navigator.maxTouchPoints??0}}var{userAgent:r0,platform:o0,maxTouchPoints:_f}=t0(),No=r0.toLowerCase(),Mo=o0.toLowerCase();var Ha=/^i(os$|p)/.test(Mo)||Mo==="macintel"&&_f>1,Rf="android",Ef=Mo===Rf||No.includes(Rf),Tf=!Ha&&Mo.startsWith("mac"),n0=Mo.startsWith("win"),i0=!Ef&&/^(linux|chrome os)/.test(Mo),Ua=Tf||Ha;var Ya={};so(Ya,{blink:()=>a0,gecko:()=>s0,webkit:()=>Ga});var Ga=typeof CSS<"u"&&!!CSS.supports?.("-webkit-backdrop-filter:none"),s0=!Ga&&No.includes("firefox"),a0=!Ga&&No.includes("chrom");var qa={};so(qa,{voiceOver:()=>l0});var l0=Ua;var Za={};so(Za,{jsdom:()=>c0});var c0=/jsdom|happydom/.test(No);var Jn=0,rr=class e{static create(){return new e}currentId=Jn;start(t,r){this.clear(),this.currentId=setTimeout(()=>{this.currentId=Jn,r()},t)}isStarted(){return this.currentId!==Jn}clear=()=>{this.currentId!==Jn&&(clearTimeout(this.currentId),this.currentId=Jn)};disposeEffect=()=>this.clear};function xr(){let e=Ct(rr.create).current;return nn(e.disposeEffect),e}var Mt=f(ve(),1);function Pf(e){return"nativeEvent"in e}function Xr(e,t){let r=["mouse","pen"];return t||r.push("",void 0),r.includes(e)}function Of(e){let t=e.type;return t==="click"||t==="mousedown"||t==="keydown"||t==="keyup"}var Xa="data-base-ui-focusable";var Ka="input:not([type='hidden']):not([disabled]),[contenteditable]:not([contenteditable='false']),textarea:not([disabled])";function Hi(e){let t=e.activeElement;for(;t?.shadowRoot?.activeElement!=null;)t=t.shadowRoot.activeElement;return t}function Ge(e,t){if(!e||!t)return!1;let r=t.getRootNode?.();if(e.contains(t))return!0;if(r&&an(r)){let o=t;for(;o;){if(e===o)return!0;o=o.parentNode||o.host}}return!1}function Nt(e){return"composedPath"in e?e.composedPath()[0]:e.target}function co(e,t){if(!Re(e))return!1;let r=e;if(t.hasElement(r))return!r.hasAttribute("data-trigger-disabled");for(let[,o]of t.entries())if(Ge(o,r))return!o.hasAttribute("data-trigger-disabled");return!1}function Ui(e,t){if(t==null)return!1;if("composedPath"in e)return e.composedPath().includes(t);let r=e;return r.target!=null&&t.contains(r.target)}function kf(e){return e.matches("html,body")}function Ff(e){return _t(e)&&e.matches(Ka)}function Ja(e){return e?.closest(`button,a[href],[role="button"],select,[tabindex]:not([tabindex="-1"]),${Ka}`)!=null}function Af(e){if(!e||Zr.env.jsdom)return!0;try{return e.matches(":focus-visible")}catch{return!0}}function u0(e,t){return t!=null&&!Xr(t)?0:typeof e=="function"?e():e}function cr(e,t,r){let o=u0(e,r);return typeof o=="number"?o:o?.[t]}function Qa(e){return typeof e=="function"?e():e}function Wi(e,t){return t||e==="click"||e==="mousedown"}function If(e){return e?.includes("mouse")&&e!=="mousedown"}var Lf=f(Z(),1),Nf=Mt.createContext({hasProvider:!1,timeoutMs:0,delayRef:{current:0},initialDelayRef:{current:0},timeout:new rr,currentIdRef:{current:null},currentContextRef:{current:null}});function f0(e,t){e.current=t.current}function $a(e){let{children:t,delay:r,timeoutMs:o=0}=e,n=Mt.useRef(r),i=Mt.useRef(r),s=Mt.useRef(null),a=Mt.useRef(null),u=xr();return we(()=>{if(i.current=r,!s.current){n.current=r;return}n.current={open:cr(n.current,"open"),close:cr(r,"close")}},[r,s,n,i]),(0,Lf.jsx)(Nf.Provider,{value:Mt.useMemo(()=>({hasProvider:!0,delayRef:n,initialDelayRef:i,currentIdRef:s,timeoutMs:o,currentContextRef:a,timeout:u}),[o,u]),children:t})}function el(e,t={open:!1}){let{open:r}=t,o="rootStore"in e?e.rootStore:e,n=o.useState("floatingId"),i=Mt.useContext(Nf),{currentIdRef:s,delayRef:a,timeoutMs:u,initialDelayRef:l,currentContextRef:c,hasProvider:m,timeout:d}=i,[h,g]=Mt.useState(!1),b=Mt.useRef(r);return we(()=>{b.current=r},[r]),we(()=>{function w(){c.current?.setIsInstantPhase(!1),s.current=null,c.current=null,a.current=l.current,d.clear()}if(s.current&&!r&&s.current===n){if(g(!1),u){let C=n;return d.start(u,()=>{o.select("open")||s.current&&s.current!==C||w()}),()=>{(b.current||s.current!==C)&&d.clear()}}w()}},[r,n,s,a,u,l,c,d,o]),we(()=>{if(!r)return;let w=c.current,C=s.current;d.clear(),c.current={onOpenChange:o.setOpen,setIsInstantPhase:g},s.current=n,a.current={open:0,close:cr(l.current,"close")},C!==null&&C!==n?(g(!0),w?.setIsInstantPhase(!0),w?.onOpenChange(!1,De(Oe.none))):(g(!1),w?.setIsInstantPhase(!1))},[r,n,o,s,a,l,c,d]),we(()=>()=>{if(s.current===n){if(c.current=null,!b.current)return;s.current=null,f0(a,l),d.clear()}},[c,s,a,n,l,d]),Mt.useMemo(()=>({hasProvider:m,delayRef:a,isInstantPhase:h}),[m,a,h])}function Sr(...e){return()=>{for(let t=0;t({x:e,y:e}),d0={left:"right",right:"left",bottom:"top",top:"bottom"};function Yi(e,t,r){return Cr(e,uo(t,r))}function Nr(e,t){return typeof e=="function"?e(t):e}function Tt(e){return e.split("-")[0]}function _r(e){return e.split("-")[1]}function qi(e){return e==="x"?"y":"x"}function ei(e){return e==="y"?"height":"width"}function qt(e){let t=e[0];return t==="t"||t==="b"?"y":"x"}function ti(e){return qi(qt(e))}function Df(e,t,r){r===void 0&&(r=!1);let o=_r(e),n=ti(e),i=ei(n),s=n==="x"?o===(r?"end":"start")?"right":"left":o==="start"?"bottom":"top";return t.reference[i]>t.floating[i]&&(s=Qn(s)),[s,Qn(s)]}function Bf(e){let t=Qn(e);return[Gi(e),t,Gi(t)]}function Gi(e){return e.includes("start")?e.replace("start","end"):e.replace("end","start")}var Mf=["left","right"],Vf=["right","left"],p0=["top","bottom"],m0=["bottom","top"];function h0(e,t,r){switch(e){case"top":case"bottom":return r?t?Vf:Mf:t?Mf:Vf;case"left":case"right":return t?p0:m0;default:return[]}}function jf(e,t,r,o){let n=_r(e),i=h0(Tt(e),r==="start",o);return n&&(i=i.map(s=>s+"-"+n),t&&(i=i.concat(i.map(Gi)))),i}function Qn(e){let t=Tt(e);return d0[t]+e.slice(t.length)}function g0(e){var t,r,o,n;return{top:(t=e.top)!=null?t:0,right:(r=e.right)!=null?r:0,bottom:(o=e.bottom)!=null?o:0,left:(n=e.left)!=null?n:0}}function Zi(e){return typeof e!="number"?g0(e):{top:e,right:e,bottom:e,left:e}}function Vo(e){let{x:t,y:r,width:o,height:n}=e;return{width:o,height:n,top:r,left:t,right:t+o,bottom:r+n,x:t,y:r}}function Kr(e,t,r=!0){return e.filter(n=>n.parentId===t).flatMap(n=>[...!r||n.context?.open?[n]:[],...Kr(e,n.id,r)])}function cn(e){return`data-base-ui-${e}`}var Vt=f(ve(),1),Uf=f(lo(),1);var zf={style:{transition:"none"}};var y0="data-base-ui-swipe-ignore",v0="data-swipe-ignore",EP=`[${y0}]`,TP=`[${v0}]`;var Hf={fallbackAxisSide:"end"};var Wf=f(Z(),1),b0=Vt.createContext(null),w0=()=>Vt.useContext(b0),x0=cn("portal");function Gf(e={}){let{ref:t,container:r,componentProps:o=nt,elementProps:n}=e,i=on(),a=w0()?.portalNode,[u,l]=Vt.useState(null),[c,m]=Vt.useState(null),d=Pe(w=>{w!==null&&m(w)}),h=Vt.useRef(null);we(()=>{if(r===null){h.current&&(h.current=null,m(null),l(null));return}let w=(r&&(Vi(r)?r:r.current))??a??document.body;if(w==null){h.current&&(h.current=null,m(null),l(null));return}h.current!==w&&(h.current=w,m(null),l(w))},[r,a]);let g=Gt("div",o,{ref:[t,d],props:[{id:i,[x0]:""},n]}),b=u&&g?Uf.createPortal(g,u):null;return{node:c,nodeId:Vt.isValidElement(g)?g.props.id:void 0,subtree:b}}var Do=f(ve(),1);function Yf(){let e=new Map;return{emit(t,r){e.get(t)?.forEach(o=>o(r))},on(t,r){e.has(t)||e.set(t,new Set),e.get(t).add(r)},off(t,r){e.get(t)?.delete(r)}}}var S0=f(Z(),1),C0=Do.createContext(null),_0=Do.createContext(null),Xi=()=>Do.useContext(C0)?.id||null,po=e=>{let t=Do.useContext(_0);return e??t};var Zt=f(ve(),1);function R0(e,t){let r=null,o=null,n=!1;return{contextElement:e||void 0,getBoundingClientRect(){let i=e?.getBoundingClientRect()||{width:0,height:0,x:0,y:0},s=t.axis==="x"||t.axis==="both",a=t.axis==="y"||t.axis==="both",u=["mouseenter","mousemove"].includes(t.dataRef.current.openEvent?.type||"")&&t.pointerType!=="touch",l=i.width,c=i.height,m=i.x,d=i.y;return r==null&&t.x&&s&&(r=i.x-t.x),o==null&&t.y&&a&&(o=i.y-t.y),m-=r||0,d-=o||0,l=0,c=0,!n||u?(l=t.axis==="y"?i.width:0,c=t.axis==="x"?i.height:0,m=s&&t.x!=null?t.x:m,d=a&&t.y!=null?t.y:d):n&&!u&&(c=t.axis==="x"?i.height:c,l=t.axis==="y"?i.width:l),n=!0,{width:l,height:c,x:m,y:d,top:d,right:m+l,bottom:d+c,left:m}}}}function qf(e){return e!=null&&e.clientX!=null}function tl(e,t={}){let{enabled:r=!0,axis:o="both"}=t,n="rootStore"in e?e.rootStore:e,i=n.useState("open"),s=n.useState("floatingElement"),a=n.useState("domReferenceElement"),u=n.context.dataRef,l=Zt.useRef(!1),c=Zt.useRef(null),[m,d]=Zt.useState(),[h,g]=Zt.useState([]),b=Pe(_=>{n.set("positionReference",_)}),w=Pe((_,k,E)=>{l.current||u.current.openEvent&&!qf(u.current.openEvent)||n.set("positionReference",R0(E??a,{x:_,y:k,axis:o,dataRef:u,pointerType:m}))}),C=Pe(_=>{i?c.current||(w(_.clientX,_.clientY,_.currentTarget),g([])):w(_.clientX,_.clientY,_.currentTarget)}),x=Xr(m)?s:i;Zt.useEffect(()=>{if(!r){b(a);return}if(!x)return;function _(){c.current?.(),c.current=null}let k=it(s);function E(T){let O=Nt(T);Ge(s,O)?_():w(T.clientX,T.clientY)}return!u.current.openEvent||qf(u.current.openEvent)?c.current=ze(k,"mousemove",E):b(a),_},[x,r,s,u,a,n,w,b,h]),Zt.useEffect(()=>()=>{n.set("positionReference",null)},[n]),Zt.useEffect(()=>{r&&!s&&(l.current=!1)},[r,s]),Zt.useEffect(()=>{!r&&i&&(l.current=!0)},[r,i]);let v=Zt.useMemo(()=>{function _(k){d(k.pointerType)}return{onPointerDown:_,onPointerEnter:_,onMouseMove:C,onMouseEnter:C}},[C]);return Zt.useMemo(()=>r?{reference:v,trigger:v}:{},[r,v])}var or=f(ve(),1);function E0(){return!1}function T0(e){return{escapeKey:typeof e=="boolean"?e:e?.escapeKey??!1,outsidePress:typeof e=="boolean"?e:e?.outsidePress??!0}}function rl(e,t={}){let{enabled:r=!0,escapeKey:o=!0,outsidePress:n=!0,outsidePressEvent:i="sloppy",referencePress:s=E0,bubbles:a,externalTree:u}=t,l="rootStore"in e?e.rootStore:e,c=l.useState("open"),m=l.useState("floatingElement"),{dataRef:d}=l.context,h=po(u),g=Pe(typeof n=="function"?n:()=>!1),b=typeof n=="function"?g:n,w=b!==!1,C=Pe(()=>i),{escapeKey:x,outsidePress:v}=T0(a),_=or.useRef(!1),k=or.useRef(!1),E=or.useRef(!1),T=or.useRef(!1),O=or.useRef(""),I=or.useRef(null),J=xr(),D=xr(),S=Pe(()=>{D.clear(),d.current.insideReactTree=!1}),L=Pe(P=>{let W=d.current.floatingContext?.nodeId;return(h?Kr(h.nodesRef.current,W):[]).some(xe=>xe.context?.open&&!xe.context.dataRef.current[P])}),Y=Pe(P=>Ui(P,l.select("floatingElement"))||Ui(P,l.select("domReferenceElement"))),A=Pe(P=>{s()&&l.setOpen(!1,De(Oe.triggerPress,P.nativeEvent))}),N=Pe(P=>{if(!c||!r||!o||P.key!=="Escape"||T.current||!x&&L("__escapeKeyBubbles"))return;let W=Pf(P)?P.nativeEvent:P,ne=De(Oe.escapeKey,W);l.setOpen(!1,ne),ne.isCanceled||P.preventDefault(),!x&&!ne.isPropagationAllowed&&P.stopPropagation()}),q=Pe(()=>{d.current.insideReactTree=!0,D.start(0,S)}),U=Pe(P=>{if(!c||!r||P.button!==0)return;let W=Nt(P.nativeEvent);Ge(l.select("floatingElement"),W)&&(_.current||(_.current=!0,k.current=!1))}),R=Pe(P=>{!c||!r||(P.defaultPrevented||P.nativeEvent.defaultPrevented)&&_.current&&(k.current=!0)});or.useEffect(()=>{if(!c||!r)return S;d.current.__escapeKeyBubbles=x,d.current.__outsidePressBubbles=v;let P=new rr,W=new rr;function ne(){P.clear(),T.current=!0}function xe(){P.start(Zr.engine.webkit?5:0,()=>{T.current=!1})}function se(){E.current=!0,W.start(0,()=>{E.current=!1})}function be(){_.current=!1,k.current=!1}function ye(){let V=O.current,te=V==="pen"||!V?"mouse":V,Ne=C(),He=typeof Ne=="function"?Ne():Ne;return typeof He=="string"?He:He[te]}function $(V){let te=ye();return te==="intentional"&&V.type!=="click"||te==="sloppy"&&V.type==="click"}function _e(V){let te=d.current.floatingContext?.nodeId,Ne=h&&Kr(h.nodesRef.current,te).some(He=>Ui(V,He.context?.elements.floating));return Y(V)||Ne}function Fe(V){if($(V)){V.type!=="click"&&!Y(V)&&(W.clear(),E.current=!1),S();return}if(d.current.insideReactTree){S();return}let te=Nt(V),Ne=`[${cn("inert")}]`,He=Re(te)?te.getRootNode():null,ot=Array.from((an(He)?He:Rt(l.select("floatingElement"))).querySelectorAll(Ne)),Ze=l.context.triggerElements;if(te&&(Ze.hasElement(te)||Ze.hasMatchingElement(Ue=>Ge(Ue,te))))return;let Be=Re(te)?te:null;for(;Be&&!Ir(Be);){let Ue=Fr(Be);if(Ir(Ue)||!Re(Ue))break;Be=Ue}if(!(ot.length&&Re(te)&&!kf(te)&&!Ge(te,l.select("floatingElement"))&&ot.every(Ue=>!Ge(Be,Ue)))){if(_t(te)&&!("touches"in V)){let Ue=Ir(te),ct=Lt(te),Se=/auto|scroll/,Pr=Ue||Se.test(ct.overflowX),$t=Ue||Se.test(ct.overflowY),Ye=Pr&&te.clientWidth>0&&te.scrollWidth>te.clientWidth,Yr=$t&&te.clientHeight>0&&te.scrollHeight>te.clientHeight,St=ct.direction==="rtl",kt=Yr&&(St?V.offsetX<=te.offsetWidth-te.clientWidth:V.offsetX>te.clientWidth),vt=Ye&&V.offsetY>te.clientHeight;if(kt||vt)return}if(!_e(V)){if(ye()==="intentional"&&E.current){W.clear(),E.current=!1;return}typeof b=="function"&&!b(V)||L("__outsidePressBubbles")||(l.setOpen(!1,De(Oe.outsidePress,V)),S())}}}function xt(V){ye()!=="sloppy"||V.pointerType==="touch"||!l.select("open")||!r||Y(V)||Fe(V)}function Le(V){if(ye()!=="sloppy"||!l.select("open")||!r||Y(V))return;let te=V.touches[0];te&&(I.current={startTime:Date.now(),startX:te.clientX,startY:te.clientY,dismissOnTouchEnd:!1,dismissOnMouseDown:!0},J.start(1e3,()=>{I.current&&(I.current.dismissOnTouchEnd=!1,I.current.dismissOnMouseDown=!1)}))}function X(V,te){let Ne=Nt(V);if(!Ne)return;let He=ze(Ne,V.type,()=>{te(V),He()})}function M(V){O.current="touch",X(V,Le)}function K(V){J.clear(),V.type==="pointerdown"&&(O.current=V.pointerType),!(V.type==="mousedown"&&I.current&&!I.current.dismissOnMouseDown)&&X(V,te=>{te.type==="pointerdown"?xt(te):Fe(te)})}function H(V){if(!_.current)return;let te=k.current;if(be(),ye()==="intentional"){if(V.type==="pointercancel"){te&&se();return}if(!_e(V)){if(te){se();return}typeof b=="function"&&!b(V)||(W.clear(),E.current=!0,S())}}}function Q(V){if(ye()!=="sloppy"||!I.current||Y(V))return;let te=V.touches[0];if(!te)return;let Ne=Math.abs(te.clientX-I.current.startX),He=Math.abs(te.clientY-I.current.startY),ot=Math.sqrt(Ne*Ne+He*He);ot>5&&(I.current.dismissOnTouchEnd=!0),ot>10&&(Fe(V),J.clear(),I.current=null)}function pe(V){X(V,Q)}function le(V){ye()!=="sloppy"||!I.current||Y(V)||(I.current.dismissOnTouchEnd&&Fe(V),J.clear(),I.current=null)}function fe(V){X(V,le)}let me=Rt(m),he=Sr(o&&Sr(ze(me,"keydown",N),ze(me,"compositionstart",ne),ze(me,"compositionend",xe)),w&&Sr(ze(me,"click",K,!0),ze(me,"pointerdown",K,!0),ze(me,"pointerup",H,!0),ze(me,"pointercancel",H,!0),ze(me,"mousedown",K,!0),ze(me,"mouseup",H,!0),ze(me,"touchstart",M,!0),ze(me,"touchmove",pe,!0),ze(me,"touchend",fe,!0)));return()=>{he(),P.clear(),W.clear(),be(),E.current=!1,S()}},[d,m,o,w,b,c,r,x,v,N,S,C,L,Y,h,l,J]);let B=or.useMemo(()=>({onKeyDown:N,onPointerDown:A,onClick:A}),[N,A]),re=or.useMemo(()=>({onKeyDown:N,onPointerDown:R,onMouseDown:R,onClickCapture:q,onMouseDownCapture(P){q(),U(P)},onPointerDownCapture(P){q(),U(P)},onMouseUpCapture:q,onTouchEndCapture:q,onTouchMoveCapture:q}),[N,q,U,R]);return or.useMemo(()=>r?{reference:B,floating:re,trigger:B}:{},[r,B,re])}var Pt=f(ve(),1);function Zf(e,t,r){let{reference:o,floating:n}=e,i=qt(t),s=ti(t),a=ei(s),u=Tt(t),l=i==="y",c=o.x+o.width/2-n.width/2,m=o.y+o.height/2-n.height/2,d=o[a]/2-n[a]/2,h;switch(u){case"top":h={x:c,y:o.y-n.height};break;case"bottom":h={x:c,y:o.y+o.height};break;case"right":h={x:o.x+o.width,y:m};break;case"left":h={x:o.x-n.width,y:m};break;default:h={x:o.x,y:o.y}}let g=_r(t);return g&&(h[s]+=d*(g==="end"?1:-1)*(r&&l?-1:1)),h}async function Xf(e,t){var r;t===void 0&&(t={});let{x:o,y:n,platform:i,rects:s,elements:a,strategy:u}=e,{boundary:l="clippingAncestors",rootBoundary:c="viewport",elementContext:m="floating",altBoundary:d=!1,padding:h=0}=Nr(t,e),g=Zi(h),w=a[d?m==="floating"?"reference":"floating":m],C=Vo(await i.getClippingRect({element:(r=await(i.isElement==null?void 0:i.isElement(w)))==null||r?w:w.contextElement||await(i.getDocumentElement==null?void 0:i.getDocumentElement(a.floating)),boundary:l,rootBoundary:c,strategy:u})),x=m==="floating"?{x:o,y:n,width:s.floating.width,height:s.floating.height}:s.reference,v=await(i.getOffsetParent==null?void 0:i.getOffsetParent(a.floating)),_=await(i.isElement==null?void 0:i.isElement(v))&&await(i.getScale==null?void 0:i.getScale(v))||{x:1,y:1},k=Vo(i.convertOffsetParentRelativeRectToViewportRelativeRect?await i.convertOffsetParentRelativeRectToViewportRelativeRect({elements:a,rect:x,offsetParent:v,strategy:u}):x);return{top:(C.top-k.top+g.top)/_.y,bottom:(k.bottom-C.bottom+g.bottom)/_.y,left:(C.left-k.left+g.left)/_.x,right:(k.right-C.right+g.right)/_.x}}var P0=50,Kf=async(e,t,r)=>{let{placement:o="bottom",strategy:n="absolute",middleware:i=[],platform:s}=r,a=s.detectOverflow?s:{...s,detectOverflow:Xf},u=await(s.isRTL==null?void 0:s.isRTL(t)),l=await s.getElementRects({reference:e,floating:t,strategy:n}),{x:c,y:m}=Zf(l,o,u),d=o,h=0,g={};for(let b=0;bY<=0)){var D,S;let Y=(((D=i.flip)==null?void 0:D.index)||0)+1,A=T[Y];if(A&&(!(m==="alignment"?x!==qt(A):!1)||J.every(U=>qt(U.placement)===x?U.overflows[0]>0:!0)))return{data:{index:Y,overflows:J},reset:{placement:A}};let N=(S=J.filter(q=>q.overflows[0]<=0).sort((q,U)=>q.overflows[1]-U.overflows[1])[0])==null?void 0:S.placement;if(!N)switch(h){case"bestFit":{var L;let q=(L=J.filter(U=>{if(E){let R=qt(U.placement);return R===x||R==="y"}return!0}).map(U=>[U.placement,U.overflows.filter(R=>R>0).reduce((R,B)=>R+B,0)]).sort((U,R)=>U[1]-R[1])[0])==null?void 0:L[0];q&&(N=q);break}case"initialPlacement":N=a;break}if(n!==N)return{reset:{placement:N}}}return{}}}};var Qf=new Set(["left","top"]);async function O0(e,t){let{placement:r,platform:o,elements:n}=e,i=await(o.isRTL==null?void 0:o.isRTL(n.floating)),s=Tt(r),a=_r(r),u=qt(r)==="y",l=Qf.has(s)?-1:1,c=i&&u?-1:1,m=Nr(t,e),{mainAxis:d,crossAxis:h,alignmentAxis:g}=typeof m=="number"?{mainAxis:m,crossAxis:0,alignmentAxis:null}:{mainAxis:m.mainAxis||0,crossAxis:m.crossAxis||0,alignmentAxis:m.alignmentAxis};return a&&typeof g=="number"&&(h=a==="end"?g*-1:g),u?{x:h*c,y:d*l}:{x:d*l,y:h*c}}var $f=function(e){return e===void 0&&(e=0),{name:"offset",options:e,async fn(t){var r,o;let{x:n,y:i,placement:s,middlewareData:a}=t,u=await O0(t,e);return s===((r=a.offset)==null?void 0:r.placement)&&(o=a.arrow)!=null&&o.alignmentOffset?{}:{x:n+u.x,y:i+u.y,data:{...u,placement:s}}}}},ed=function(e){return e===void 0&&(e={}),{name:"shift",options:e,async fn(t){let{x:r,y:o,placement:n,platform:i}=t,{mainAxis:s=!0,crossAxis:a=!1,limiter:u={fn:x=>{let{x:v,y:_}=x;return{x:v,y:_}}},...l}=Nr(e,t),c={x:r,y:o},m=await i.detectOverflow(t,l),d=qt(n),h=qi(d),g=c[h],b=c[d],w=(x,v)=>Yi(v+m[x==="y"?"top":"left"],v,v-m[x==="y"?"bottom":"right"]);s&&(g=w(h,g)),a&&(b=w(d,b));let C=u.fn({...t,[h]:g,[d]:b});return{...C,data:{x:C.x-r,y:C.y-o,enabled:{[h]:s,[d]:a}}}}}},td=function(e){return e===void 0&&(e={}),{options:e,fn(t){var r,o;let{x:n,y:i,placement:s,rects:a,middlewareData:u}=t,{offset:l=0,mainAxis:c=!0,crossAxis:m=!0}=Nr(e,t),d={x:n,y:i},h=qt(s),g=qi(h),b=d[g],w=d[h],C=Nr(l,t),x=typeof C=="number"?{mainAxis:C,crossAxis:0}:{mainAxis:(r=C.mainAxis)!=null?r:0,crossAxis:(o=C.crossAxis)!=null?o:0};if(c){let k=g==="y"?"height":"width",E=a.reference[g]-a.floating[k]+x.mainAxis,T=a.reference[g]+a.reference[k]-x.mainAxis;bT&&(b=T)}if(m){var v,_;let k=g==="y"?"width":"height",E=Qf.has(Tt(s)),T=a.reference[h]-a.floating[k]+(E&&((v=u.offset)==null?void 0:v[h])||0)+(E?0:x.crossAxis),O=a.reference[h]+a.reference[k]+(E?0:((_=u.offset)==null?void 0:_[h])||0)-(E?x.crossAxis:0);wO&&(w=O)}return{[g]:b,[h]:w}}}},rd=function(e){return e===void 0&&(e={}),{name:"size",options:e,async fn(t){let{placement:r,rects:o,platform:n,elements:i}=t,{apply:s=()=>{},...a}=Nr(e,t),u=await n.detectOverflow(t,a),l=Tt(r),c=_r(r),m=qt(r)==="y",{width:d,height:h}=o.floating,g,b;l==="top"||l==="bottom"?(g=l,b=c===(await(n.isRTL==null?void 0:n.isRTL(i.floating))?"start":"end")?"left":"right"):(b=l,g=c==="end"?"top":"bottom");let w=h-u.top-u.bottom,C=d-u.left-u.right,x=uo(h-u[g],w),v=uo(d-u[b],C),_=t.middlewareData.shift,k=!_,E=x,T=v;_!=null&&_.enabled.x&&(T=C),_!=null&&_.enabled.y&&(E=w),k&&!c&&(m?T=d-2*Cr(u.left,u.right):E=h-2*Cr(u.top,u.bottom)),await s({...t,availableWidth:T,availableHeight:E});let O=await n.getDimensions(i.floating);return d!==O.width||h!==O.height?{reset:{rects:!0}}:{}}}};function id(e){let t=Lt(e),r=parseFloat(t.width)||0,o=parseFloat(t.height)||0,n=_t(e),i=n?e.offsetWidth:r,s=n?e.offsetHeight:o,a=fo(r)!==i||fo(o)!==s;return a&&(r=i,o=s),{width:r,height:o,$:a}}function nl(e){return Re(e)?e:e.contextElement}function un(e){let t=nl(e);if(!_t(t))return Lr(1);let r=t.getBoundingClientRect(),{width:o,height:n,$:i}=id(t),s=(i?fo(r.width):r.width)/o,a=(i?fo(r.height):r.height)/n;return(!s||!Number.isFinite(s))&&(s=1),(!a||!Number.isFinite(a))&&(a=1),{x:s,y:a}}var k0=Lr(0);function sd(e){let t=it(e);return!Bi()||!t.visualViewport?k0:{x:t.visualViewport.offsetLeft,y:t.visualViewport.offsetTop}}function F0(e,t,r){return t===void 0&&(t=!1),!!r&&t&&r===it(e)}function Bo(e,t,r,o){t===void 0&&(t=!1),r===void 0&&(r=!1);let n=e.getBoundingClientRect(),i=nl(e),s=Lr(1);t&&(o?Re(o)&&(s=un(o)):s=un(e));let a=F0(i,r,o)?sd(i):Lr(0),u=(n.left+a.x)/s.x,l=(n.top+a.y)/s.y,c=n.width/s.x,m=n.height/s.y;if(i&&o){let d=it(i),h=Re(o)?it(o):o,g=d,b=ji(g);for(;b&&h!==g;){let w=un(b),C=b.getBoundingClientRect(),x=Lt(b),v=C.left+(b.clientLeft+parseFloat(x.paddingLeft))*w.x,_=C.top+(b.clientTop+parseFloat(x.paddingTop))*w.y;u*=w.x,l*=w.y,c*=w.x,m*=w.y,u+=v,l+=_,g=it(b),b=ji(g)}}return Vo({width:c,height:m,x:u,y:l})}function Ki(e,t){let r=Kn(e).scrollLeft;return t?t.left+r:Bo(Ar(e)).left+r}function ad(e,t){let r=e.getBoundingClientRect(),o=r.left+t.scrollLeft-Ki(e,r),n=r.top+t.scrollTop;return{x:o,y:n}}function A0(e){let{elements:t,rect:r,offsetParent:o,strategy:n}=e,i=n==="fixed",s=Ar(o),a=t?Xn(t.floating):!1;if(o===s||a&&i)return r;let u={scrollLeft:0,scrollTop:0},l=Lr(1),c=Lr(0),m=_t(o);if((m||!i)&&((Lo(o)!=="body"||Zn(s))&&(u=Kn(o)),m)){let h=Bo(o);l=un(o),c.x=h.x+o.clientLeft,c.y=h.y+o.clientTop}let d=s&&!m&&!i?ad(s,u):Lr(0);return{width:r.width*l.x,height:r.height*l.y,x:r.x*l.x-u.scrollLeft*l.x+c.x+d.x,y:r.y*l.y-u.scrollTop*l.y+c.y+d.y}}function I0(e){return e.getClientRects?Array.from(e.getClientRects()):[]}function L0(e){let t=Kn(e),r=e.ownerDocument.body,o=Cr(e.scrollWidth,e.clientWidth,r.scrollWidth,r.clientWidth),n=Cr(e.scrollHeight,e.clientHeight,r.scrollHeight,r.clientHeight),i=-t.scrollLeft+Ki(e),s=-t.scrollTop;return Lt(r).direction==="rtl"&&(i+=Cr(e.clientWidth,r.clientWidth)-o),{width:o,height:n,x:i,y:s}}var N0=25;function M0(e,t,r){r===void 0&&(r="viewport");let o=r==="layoutViewport",n=it(e),i=Ar(e),s=n.visualViewport,a=i.clientWidth,u=i.clientHeight,l=0,c=0;if(s){let d=!Bi()||t==="fixed";o?d||(l=-s.offsetLeft,c=-s.offsetTop):(a=s.width,u=s.height,d&&(l=s.offsetLeft,c=s.offsetTop))}if(Ki(i)<=0){let d=i.ownerDocument,h=d.body,g=getComputedStyle(h),b=d.compatMode==="CSS1Compat"&&parseFloat(g.marginLeft)+parseFloat(g.marginRight)||0,w=Math.abs(i.clientWidth-h.clientWidth-b),C=getComputedStyle(i).scrollbarGutter==="stable both-edges"?w/2:w;C<=N0&&(a-=C)}return{width:a,height:u,x:l,y:c}}function V0(e,t){let r=Bo(e,!0,t==="fixed"),o=r.top+e.clientTop,n=r.left+e.clientLeft,i=un(e),s=e.clientWidth*i.x,a=e.clientHeight*i.y,u=n*i.x,l=o*i.y;return{width:s,height:a,x:u,y:l}}function od(e,t,r){let o;if(t==="viewport"||t==="layoutViewport")o=M0(e,r,t);else if(t==="document")o=L0(Ar(e));else if(Re(t))o=V0(t,r);else{let n=sd(e);o={x:t.x-n.x,y:t.y-n.y,width:t.width,height:t.height}}return Vo(o)}function D0(e,t){let r=t.get(e);if(r)return r;let o=ao(e,[],!1).filter(a=>Re(a)&&Lo(a)!=="body"),n=null,i=Lt(e).position==="fixed",s=i?Fr(e):e;for(;Re(s)&&!Ir(s);){let a=Lt(s),u=Di(s),l=n?n.position:i?"fixed":"";!u&&(l==="fixed"||l==="absolute"&&a.position==="static")?o=o.filter(m=>m!==s):n=a,s=Fr(s)}return t.set(e,o),o}function B0(e){let{element:t,boundary:r,rootBoundary:o,strategy:n}=e,s=[...r==="clippingAncestors"?Xn(t)?[]:D0(t,this._c):[].concat(r),o],a=od(t,s[0],n),u=a.top,l=a.right,c=a.bottom,m=a.left;for(let d=1;d{a(!1,1e-7)},1e3)}T=!1}try{o=new IntersectionObserver(O,{...E,root:i.ownerDocument})}catch{o=new IntersectionObserver(O,E)}o.observe(e)}let u=it(e),l=()=>a(r);return u.addEventListener("resize",l),a(!0),()=>{u.removeEventListener("resize",l),s()}}function ri(e,t,r,o){o===void 0&&(o={});let{ancestorScroll:n=!0,ancestorResize:i=!0,elementResize:s=typeof ResizeObserver=="function",layoutShift:a=typeof IntersectionObserver=="function",animationFrame:u=!1}=o,l=nl(e),c=n||i?[...l?ao(l):[],...t?ao(t):[]]:[];c.forEach(C=>{n&&C.addEventListener("scroll",r),i&&C.addEventListener("resize",r)});let m=l&&a?W0(l,r,i):null,d=-1,h=null;s&&(h=new ResizeObserver(C=>{let[x]=C;x&&x.target===l&&h&&t&&(h.unobserve(t),cancelAnimationFrame(d),d=requestAnimationFrame(()=>{var v;(v=h)==null||v.observe(t)})),r()}),l&&!u&&h.observe(l),t&&h.observe(t));let g,b=u?Bo(e):null;u&&w();function w(){let C=Bo(e);b&&!cd(b,C)&&r(),b=C,g=requestAnimationFrame(w)}return r(),()=>{var C;c.forEach(x=>{n&&x.removeEventListener("scroll",r),i&&x.removeEventListener("resize",r)}),m?.(),(C=h)==null||C.disconnect(),h=null,u&&cancelAnimationFrame(g)}}var ud=$f;var fd=ed,dd=Jf,pd=rd;var md=td,Ji=(e,t,r)=>{let o=new Map,n=r??{},i={...il,...n.platform,_c:o};return Kf(e,t,{...n,platform:i})};var mt=f(ve(),1),gd=f(ve(),1),yd=f(lo(),1),Y0=typeof document<"u",q0=function(){},Qi=Y0?gd.useLayoutEffect:q0;function $i(e,t){if(e===t)return!0;if(typeof e!=typeof t)return!1;if(typeof e=="function"&&e.toString()===t.toString())return!0;let r,o,n;if(e&&t&&typeof e=="object"){if(Array.isArray(e)){if(r=e.length,r!==t.length)return!1;for(o=r;o--!==0;)if(!$i(e[o],t[o]))return!1;return!0}if(n=Object.keys(e),r=n.length,r!==Object.keys(t).length)return!1;for(o=r;o--!==0;)if(!{}.hasOwnProperty.call(t,n[o]))return!1;for(o=r;o--!==0;){let i=n[o];if(!(i==="_owner"&&e.$$typeof)&&!$i(e[i],t[i]))return!1}return!0}return e!==e&&t!==t}function vd(e){return typeof window>"u"?1:(e.ownerDocument.defaultView||window).devicePixelRatio||1}function hd(e,t){let r=vd(e);return Math.round(t*r)/r}function sl(e){let t=mt.useRef(e);return Qi(()=>{t.current=e}),t}function bd(e){e===void 0&&(e={});let{placement:t="bottom",strategy:r="absolute",middleware:o=[],platform:n,elements:{reference:i,floating:s}={},transform:a=!0,whileElementsMounted:u,open:l}=e,[c,m]=mt.useState({x:0,y:0,strategy:r,placement:t,middlewareData:{},isPositioned:!1}),[d,h]=mt.useState(o);$i(d,o)||h(o);let[g,b]=mt.useState(null),[w,C]=mt.useState(null),x=mt.useCallback(U=>{U!==E.current&&(E.current=U,b(U))},[]),v=mt.useCallback(U=>{U!==T.current&&(T.current=U,C(U))},[]),_=i||g,k=s||w,E=mt.useRef(null),T=mt.useRef(null),O=mt.useRef(c),I=u!=null,J=sl(u),D=sl(n),S=sl(l),L=mt.useCallback(()=>{if(!E.current||!T.current)return;let U={placement:t,strategy:r,middleware:d};D.current&&(U.platform=D.current),Ji(E.current,T.current,U).then(R=>{let B={...R,isPositioned:S.current!==!1};Y.current&&!$i(O.current,B)&&(O.current=B,yd.flushSync(()=>{m(B)}))})},[d,t,r,D,S]);Qi(()=>{l===!1&&O.current.isPositioned&&(O.current.isPositioned=!1,m(U=>({...U,isPositioned:!1})))},[l]);let Y=mt.useRef(!1);Qi(()=>(Y.current=!0,()=>{Y.current=!1}),[]),Qi(()=>{if(_&&(E.current=_),k&&(T.current=k),_&&k){if(J.current)return J.current(_,k,L);L()}},[_,k,L,J,I]);let A=mt.useMemo(()=>({reference:E,floating:T,setReference:x,setFloating:v}),[x,v]),N=mt.useMemo(()=>({reference:_,floating:k}),[_,k]),q=mt.useMemo(()=>{let U={position:r,left:0,top:0};if(!N.floating)return U;let R=hd(N.floating,c.x),B=hd(N.floating,c.y);return a?{...U,transform:"translate("+R+"px, "+B+"px)",...vd(N.floating)>=1.5&&{willChange:"transform"}}:{position:r,left:R,top:B}},[r,a,N.floating,c.x,c.y]);return mt.useMemo(()=>({...c,update:L,refs:A,elements:N,floatingStyles:q}),[c,L,A,N,q])}var al=(e,t)=>{let r=ud(e);return{name:r.name,fn:r.fn,options:[e,t]}},ll=(e,t)=>{let r=fd(e);return{name:r.name,fn:r.fn,options:[e,t]}},cl=(e,t)=>({fn:md(e).fn,options:[e,t]}),ul=(e,t)=>{let r=dd(e);return{name:r.name,fn:r.fn,options:[e,t]}},fl=(e,t)=>{let r=pd(e);return{name:r.name,fn:r.fn,options:[e,t]}};var es=class{attachedStores=[];attachedStoreValue=null;storeListeners=new Set;constructor(t,r,o=!0){this.fallbackStore=t,this.componentName=r,this.throwOnMissingTrigger=o}get attachedStore(){return this.attachedStoreValue}get store(){return this.attachedStoreValue??this.fallbackStore}get serverStore(){return this.fallbackStore}subscribeStore(t){return this.storeListeners.add(t),()=>{this.storeListeners.delete(t)}}attachStore(t){return this.attachedStores.push(t),this.setActiveStore(t),()=>{let r=this.attachedStores.lastIndexOf(t);r!==-1&&this.attachedStores.splice(r,1),this.setActiveStore(this.attachedStores[this.attachedStores.length-1]??null)}}setActiveStore(t){this.attachedStoreValue!==t&&(this.attachedStoreValue=t,this.storeListeners.forEach(r=>{r()}))}openByTrigger(t){let r=this.attachedStore;if(r===null)return;let o;if(t){for(let n=this.attachedStores.length-1;n>=0&&!o;n-=1)o=this.attachedStores[n].context.triggerElements.getById(t);o??=this.fallbackStore.context.triggerElements.getById(t)}if(t&&!o&&this.throwOnMissingTrigger)throw new Error(lr(99,this.componentName,t,this.componentName));r.setOpen(!0,De(Oe.imperativeAction,void 0,o))}closePopup(){let t=this.attachedStore;t!==null&&t.setOpen(!1,De(Oe.imperativeAction))}};var zo=f(ve(),1),Nd=f(lo(),1);var Id=f(ve(),1);var Fd=f(ve(),1),gl=f(ts(),1),Ad=f(Ed(),1);var Td=f(ve(),1);var pl=[],ml;function Pd(){return ml}function Od(e){pl.push(e)}function hl(e){let t=(r,o)=>{let n=Ct(fw).current,i;try{ml=n;for(let s of pl)s.before(n);i=e(r,o);for(let s of pl)s.after(n);n.didInitialize=!0}finally{ml=void 0}return i};return t.displayName=e.displayName||e.name,t}function kd(e){return Td.forwardRef(hl(e))}function fw(){return{didInitialize:!1}}var dw=rn(19),pw=dw?hw:gw;function os(e,t,r,o,n){return pw(e,t,r,o,n)}function mw(e,t,r,o,n){let i=Fd.useCallback(()=>t(e.getSnapshot(),r,o,n),[e,t,r,o,n]);return(0,gl.useSyncExternalStore)(e.subscribe,i,i)}Od({before(e){e.syncIndex=0,e.didInitialize||(e.syncTick=1,e.syncHooks=[],e.didChangeStore=!0,e.getSnapshot=()=>{let t=!1;for(let r=0;r0&&(e.didChangeStore&&(e.didChangeStore=!1,e.subscribe=t=>{let r=new Set;for(let n of e.syncHooks)r.add(n.store);let o=[];for(let n of r)o.push(n.subscribe(t));return()=>{for(let n of o)n()}}),(0,gl.useSyncExternalStore)(e.subscribe,e.getSnapshot,e.getSnapshot))}});function hw(e,t,r,o,n){let i=Pd();if(!i)return mw(e,t,r,o,n);let s=i.syncIndex;i.syncIndex+=1;let a;return i.didInitialize?(a=i.syncHooks[s],(a.store!==e||a.selector!==t||!Object.is(a.a1,r)||!Object.is(a.a2,o)||!Object.is(a.a3,n))&&(a.store!==e&&(i.didChangeStore=!0),a.store=e,a.selector=t,a.a1=r,a.a2=o,a.a3=n,a.value=t(e.getSnapshot(),r,o,n))):(a={store:e,selector:t,a1:r,a2:o,a3:n,value:t(e.getSnapshot(),r,o,n)},i.syncHooks.push(a)),a.value}function gw(e,t,r,o,n){return(0,Ad.useSyncExternalStoreWithSelector)(e.subscribe,e.getSnapshot,e.getSnapshot,i=>t(i,r,o,n))}var ns=class{constructor(t){this.state=t,this.listeners=new Set,this.updateTick=0}subscribe=t=>(this.listeners.add(t),()=>{this.listeners.delete(t)});getSnapshot=()=>this.state;setState(t){if(this.state===t)return;this.state=t,this.updateTick+=1;let r=this.updateTick;for(let o of this.listeners){if(r!==this.updateTick)return;o(t)}}update(t){for(let r in t)if(!Object.is(this.state[r],t[r])){this.setState({...this.state,...t});return}}set(t,r){Object.is(this.state[t],r)||this.setState({...this.state,[t]:r})}notifyAll(){let t={...this.state};this.setState(t)}use(t,r,o,n){return os(this,t,r,o,n)}};var jo=f(ve(),1);var mo=class extends ns{constructor(t,r={},o){super(t),this.context=r,this.selectors=o}useSyncedValue(t,r){jo.useDebugValue(t);let o=this;we(()=>{o.state[t]!==r&&o.set(t,r)},[o,t,r])}useSyncedValueWithCleanup(t,r){let o=this;we(()=>(o.state[t]!==r&&o.set(t,r),()=>{o.set(t,void 0)}),[o,t,r])}useSyncedValues(t){let r=this,o=Object.values(t);we(()=>{r.update(t)},[r,...o])}useControlledProp(t,r){jo.useDebugValue(t);let o=this,n=r!==void 0;we(()=>{n&&!Object.is(o.state[t],r)&&o.setState({...o.state,[t]:r})},[o,t,r,n])}select(t,r,o,n){let i=this.selectors[t];return i(this.state,r,o,n)}useState(t,r,o,n){return jo.useDebugValue(t),os(this,this.selectors[t],r,o,n)}useContextCallback(t,r){jo.useDebugValue(t);let o=Pe(r??tr);this.context[t]=o}useStateSetter(t){let r=jo.useRef(void 0);return r.current===void 0&&(r.current=o=>{this.set(t,o)}),r.current}observe(t,r){let o;typeof t=="function"?o=t:o=this.selectors[t];let n=o(this.state);return r(n,n,this),this.subscribe(i=>{let s=o(i);if(!Object.is(n,s)){let a=n;n=s,r(s,a,this)}})}};var yw={open:e=>e.open,transitionStatus:e=>e.transitionStatus,domReferenceElement:e=>e.domReferenceElement,referenceElement:e=>e.positionReference??e.referenceElement,floatingElement:e=>e.floatingElement,floatingId:e=>e.floatingId},ho=class extends mo{constructor(t){let{syncOnly:r,nested:o,onOpenChange:n,triggerElements:i,...s}=t;super({...s,positionReference:s.referenceElement,domReferenceElement:s.referenceElement},{onOpenChange:n,dataRef:{current:{}},events:Yf(),nested:o,triggerElements:i},yw),this.syncOnly=r}syncOpenEvent=(t,r)=>{(!t||!this.state.open||r!=null&&Of(r))&&(this.context.dataRef.current.openEvent=t?r:void 0)};dispatchOpenChange=(t,r)=>{this.syncOpenEvent(t,r.event);let o={open:t,reason:r.reason,nativeEvent:r.event,nested:this.context.nested,triggerElement:r.trigger};this.context.events.emit("openchange",o)};setOpen=(t,r)=>{if(this.syncOnly){this.context.onOpenChange?.(t,r);return}this.dispatchOpenChange(t,r),this.context.onOpenChange?.(t,r)}};function Ld(e){let{popupStore:t,treatPopupAsFloatingElement:r=!1,floatingRootContext:o,floatingId:n,nested:i,onOpenChange:s}=e,a=t.useState("open"),u=t.useState("activeTriggerElement"),l=t.useState(r?"popupElement":"positionerElement"),c=t.context.triggerElements,m=s,d=Id.useRef(null);o===void 0&&d.current===null&&(d.current=new ho({open:a,transitionStatus:void 0,referenceElement:u,floatingElement:l,triggerElements:c,onOpenChange:m,floatingId:n,syncOnly:!0,nested:i}));let h=o??d.current;return t.useSyncedValue("floatingId",n),we(()=>{let g={open:a,floatingId:n,referenceElement:u,floatingElement:l};Re(u)&&(g.domReferenceElement=u),h.state.positionReference===h.state.referenceElement&&(g.positionReference=u),h.update(g)},[a,n,u,l,h]),h.context.onOpenChange=m,h.context.nested=i,h}var Md={tabIndex:-1,[Xa]:""};function Vd(e,t=!1){let r=on(),o=Xi()!=null,n=Ct(()=>e(r,o)).current;return Ld({popupStore:n,treatPopupAsFloatingElement:t,floatingRootContext:n.state.floatingRootContext,floatingId:r,nested:o,onOpenChange:n.setOpen}),n}function Dd({handle:e,store:t}){return we(()=>e.attachStore(t),[e,t]),null}function vw(e,t){let r=zo.useRef(null),o=zo.useRef(null);return zo.useCallback(n=>{if(e===void 0)return;let i=!1;if(r.current!==null){let s=r.current,a=o.current,u=t.context.triggerElements.getById(s);a&&u===a&&(t.context.triggerElements.delete(s),i=!0),r.current=null,o.current=null}if(n!==null&&(r.current=e,o.current=n,t.context.triggerElements.add(e,n),i=!0),i){let s=t.context.triggerElements.size;t.select("open")&&t.state.triggerCount!==s&&t.set("triggerCount",s)}},[t,e])}function bw(e,t,r,o=!1){t?e.preventUnmountingOnClose=!1:o&&(e.preventUnmountingOnClose=!0);let n=r?.id??null;(n||t)&&(e.activeTriggerId=n,e.activeTriggerElement=r??null)}function ww(e){let t=!1;return e.preventUnmountOnClose=()=>{t=!0},()=>t}function Bd(e,t,r,o={}){let n=r.reason,i=n===Oe.triggerHover,s=t&&n===Oe.triggerFocus,a=!t&&(n===Oe.triggerPress||n===Oe.escapeKey),u=ww(r);if(e.context.onOpenChange?.(t,r),r.isCanceled)return;o.onBeforeDispatch?.(),e.state.floatingRootContext.dispatchOpenChange(t,r);let l=()=>{let c={...o.extraState,open:t};s?c.instantType="focus":a?c.instantType="dismiss":i&&(c.instantType=void 0),bw(c,t,r.trigger,u()),e.update(c)};i?Nd.flushSync(l):l()}function jd(e,t,r,o){let n=r.useState("isMountedByTrigger",e),i=vw(e,r),s=Pe(u=>{let l=r.select("open"),c=r.select("activeTriggerId");if(c===e){r.update({activeTriggerElement:u,...l?o:null});return}c==null&&l&&r.update({activeTriggerId:e,activeTriggerElement:u,...o})}),a=zo.useCallback(u=>{i(u),u&&s(u)},[i,s]);return we(()=>{n&&r.update({activeTriggerElement:t.current,...o})},[n,r,t,...Object.values(o)]),{registerTrigger:a,isMountedByThisTrigger:n}}function zd(e,t={}){let{closeOnActiveTriggerUnmount:r=!1}=t,o=zo.useRef(null),n=e.useState("open"),i=e.useState("triggerCount"),s=e.useState("activeTriggerId"),a=e.useState("activeTriggerElement");we(()=>{if(!n){o.current=null,e.state.triggerCount!==0&&e.set("triggerCount",0);return}let u=e.context.triggerElements.size,l={};e.state.triggerCount!==u&&(l.triggerCount=u);let c=e.select("activeTriggerId"),m=null;if(c){let d=e.context.triggerElements.getById(c);if(d)o.current=c,d!==e.state.activeTriggerElement&&(l.activeTriggerElement=d);else{for(let[h,g]of e.context.triggerElements.entries())if(g===e.state.activeTriggerElement){l.activeTriggerId=h,l.activeTriggerElement=g,o.current=h;break}l.activeTriggerId===void 0&&(o.current===c?m=c:o.current=null)}}else o.current=null;if(!m&&!c&&u===1){let d=e.context.triggerElements.entries().next();if(!d.done){let[h,g]=d.value;l.activeTriggerId=h,l.activeTriggerElement=g,o.current=h}}(l.triggerCount!==void 0||l.activeTriggerId!==void 0||l.activeTriggerElement!==void 0)&&e.update(l),m&&r&&queueMicrotask(()=>{if(e.select("open")&&e.select("activeTriggerId")===m&&!e.context.triggerElements.getById(m)){let d=De(Oe.none);e.setOpen(!1,d),d.isCanceled||e.update({activeTriggerId:null,activeTriggerElement:null})}})},[n,e,i,s,a,r])}function Hd(e,t,r){let{mounted:o,setMounted:n,transitionStatus:i}=hf(e),s=t.useState("preventUnmountingOnClose"),a=e?!1:s;t.useSyncedValues({mounted:o,transitionStatus:i,preventUnmountingOnClose:a});let u=Pe(()=>{n(!1),t.update({activeTriggerId:null,activeTriggerElement:null,mounted:!1,preventUnmountingOnClose:!1}),r?.(),t.context.onOpenChangeComplete?.(!1)});return zi({enabled:o&&!e&&!a,open:e,ref:t.context.popupRef,onComplete(){e||u()}}),{forceUnmount:u,transitionStatus:i}}function Ud(e,t){e.useSyncedValues(t),we(()=>()=>{e.update({activeTriggerProps:nt,inactiveTriggerProps:nt,popupProps:nt})},[e])}var Ho=class{constructor(){this.idMap=new Map}add(t,r){this.idMap.set(t,r)}delete(t){this.idMap.delete(t)}hasElement(t){for(let r of this.idMap.values())if(r===t)return!0;return!1}hasMatchingElement(t){for(let r of this.idMap.values())if(t(r))return!0;return!1}getById(t){return this.idMap.get(t)}entries(){return this.idMap.entries()}elements(){return this.idMap.values()}get size(){return this.idMap.size}};function Wd(){return new ho({open:!1,transitionStatus:void 0,floatingElement:null,referenceElement:null,triggerElements:new Ho,floatingId:void 0,syncOnly:!1,nested:!1,onOpenChange:void 0})}function Yd(){return{open:!1,openProp:void 0,mounted:!1,transitionStatus:void 0,floatingRootContext:Wd(),floatingId:void 0,triggerCount:0,preventUnmountingOnClose:!1,payload:void 0,activeTriggerId:null,activeTriggerElement:null,triggerIdProp:void 0,popupElement:null,positionerElement:null,activeTriggerProps:nt,inactiveTriggerProps:nt,popupProps:nt}}function qd(e,t,r=!1){return new ho({open:!1,transitionStatus:void 0,floatingElement:null,referenceElement:null,triggerElements:e,floatingId:t,syncOnly:!0,nested:r,onOpenChange:void 0})}var oi=e=>e.triggerIdProp??e.activeTriggerId,yl=e=>e.openProp??e.open,Gd=e=>(e.popupElement?.id??e.floatingId)||void 0;function Zd(e,t){return t!==void 0&&yl(e)&&oi(e)===t}function xw(e,t){return Zd(e,t)?!0:t!==void 0&&yl(e)&&oi(e)==null&&e.triggerCount===1}var Xd={open:yl,mounted:e=>e.mounted,transitionStatus:e=>e.transitionStatus,floatingRootContext:e=>e.floatingRootContext,triggerCount:e=>e.triggerCount,preventUnmountingOnClose:e=>e.preventUnmountingOnClose,payload:e=>e.payload,activeTriggerId:oi,activeTriggerElement:e=>e.mounted?e.activeTriggerElement:null,popupId:Gd,isTriggerActive:(e,t)=>t!==void 0&&oi(e)===t,isOpenedByTrigger:(e,t)=>Zd(e,t),isMountedByTrigger:(e,t)=>t!==void 0&&oi(e)===t&&e.mounted,triggerProps:(e,t)=>t?e.activeTriggerProps:e.inactiveTriggerProps,triggerPopupId:(e,t)=>xw(e,t)?Gd(e):void 0,popupProps:e=>e.popupProps,popupElement:e=>e.popupElement,positionerElement:e=>e.positionerElement};var vl=f(ve(),1),Kd=f(ts(),1);function Jd(e){let t=vl.useCallback(o=>e===void 0?tr:e.subscribeStore(o),[e]),r=vl.useCallback(()=>e===void 0?void 0:e.store,[e]);return(0,Kd.useSyncExternalStore)(t,r,()=>e?.serverStore)}function Qd(e){return Sw(e,e.rootContext)}function Sw(e,t){let{nodeId:r,externalTree:o}=e,n=t.useState("referenceElement"),i=t.useState("floatingElement"),s=t.useState("domReferenceElement"),a=t.useState("open"),u=t.useState("floatingId"),[l,c]=Pt.useState(null),[m,d]=Pt.useState(void 0),[h,g]=Pt.useState(void 0),b=Pt.useRef(null),w=po(o),C=Pt.useMemo(()=>({reference:n,floating:i,domReference:s}),[n,i,s]),x=bd({...e,elements:{...C,...l&&{reference:l}}}),v=Re(m)?m:null,_=h===void 0?t.state.floatingElement:h;t.useSyncedValue("referenceElement",m??null),t.useSyncedValue("domReferenceElement",m===void 0?s:v),t.useSyncedValue("floatingElement",_);let k=Pt.useCallback(D=>{let S=Re(D)?{getBoundingClientRect:()=>D.getBoundingClientRect(),getClientRects:()=>D.getClientRects(),contextElement:D}:D;c(S),x.refs.setReference(S)},[x.refs]),E=Pt.useCallback(D=>{(Re(D)||D===null)&&(b.current=D,d(D)),(Re(x.refs.reference.current)||x.refs.reference.current===null||D!==null&&!Re(D))&&x.refs.setReference(D)},[x.refs,d]),T=Pt.useCallback(D=>{g(D),x.refs.setFloating(D)},[x.refs]),O=Pt.useMemo(()=>({...x.refs,setReference:E,setFloating:T,setPositionReference:k,domReference:b}),[x.refs,E,T,k]),I=Pt.useMemo(()=>({...x.elements,domReference:s}),[x.elements,s]),J=Pt.useMemo(()=>({...x,dataRef:t.context.dataRef,open:a,onOpenChange:t.setOpen,events:t.context.events,floatingId:u,refs:O,elements:I,nodeId:r,rootStore:t}),[x,O,I,r,t,a,u]);return we(()=>{s&&(b.current=s)},[s]),we(()=>{t.context.dataRef.current.floatingContext=J;let D=w?.nodesRef.current.find(S=>S.id===r);D&&(D.context=J)}),Pt.useMemo(()=>({...x,context:J,refs:O,elements:I,rootStore:t}),[x,O,I,J,t])}var Mr=f(ve(),1);var bl=Zr.os.mac&&Zr.engine.webkit;function wl(e,t={}){let{enabled:r=!0,delay:o}=t,n="rootStore"in e?e.rootStore:e,{events:i,dataRef:s}=n.context,a=Mr.useRef(!1),u=Mr.useRef(null),l=Mr.useRef(!0),c=xr();Mr.useEffect(()=>{let d=n.select("domReferenceElement");if(!r)return;let h=it(d);function g(){let C=n.select("domReferenceElement");!n.select("open")&&_t(C)&&C===Hi(Rt(C))&&(a.current=!0)}function b(){l.current=!0}function w(){l.current=!1}return Sr(ze(h,"blur",g),bl&&ze(h,"keydown",b,!0),bl&&ze(h,"pointerdown",w,!0))},[n,r]),Mr.useEffect(()=>{if(!r)return;function d(h){if(h.reason===Oe.triggerPress||h.reason===Oe.escapeKey){let g=n.select("domReferenceElement");Re(g)&&(u.current=g,a.current=!0)}}return i.on("openchange",d),()=>{i.off("openchange",d)}},[i,r,n]);let m=Mr.useMemo(()=>{function d(){a.current=!1,u.current=null}return{onMouseLeave(){d()},onFocus(h){let g=h.currentTarget;if(a.current){if(u.current===g)return;d()}let b=Nt(h.nativeEvent);if(Re(b)){if(bl&&!h.relatedTarget){if(!l.current&&!Ff(b))return}else if(!Af(b))return}let w=co(h.relatedTarget,n.context.triggerElements),{nativeEvent:C,currentTarget:x}=h,v=typeof o=="function"?o():o;if(n.select("open")&&w||v===0||v===void 0){n.setOpen(!0,De(Oe.triggerFocus,C,x));return}c.start(v,()=>{a.current||n.setOpen(!0,De(Oe.triggerFocus,C,x))})},onBlur(h){d();let g=h.relatedTarget,b=h.nativeEvent,w=Re(g)&&g.hasAttribute(cn("focus-guard"))&&g.getAttribute("data-type")==="outside";c.start(0,()=>{let C=n.select("domReferenceElement"),x=Hi(Rt(C));!g&&x===C||Ge(s.current.floatingContext?.refs.floating.current,x)||Ge(C,x)||w||co(g??x,n.context.triggerElements)||n.setOpen(!1,De(Oe.triggerFocus,b))})}}},[s,o,n,c]);return Mr.useMemo(()=>r?{reference:m,trigger:m}:{},[r,m])}var Sl=f(ve(),1);var xl=class e{constructor(){this.pointerType=void 0,this.interactedInside=!1,this.handler=void 0,this.blockMouseMove=!0,this.performedPointerEventsMutation=!1,this.pointerEventsScopeElement=null,this.pointerEventsReferenceElement=null,this.pointerEventsFloatingElement=null,this.restTimeoutPending=!1,this.openChangeTimeout=new rr,this.restTimeout=new rr,this.handleCloseOptions=void 0}static create(){return new e}dispose=()=>{this.openChangeTimeout.clear(),this.restTimeout.clear()};disposeEffect=()=>this.dispose},is=new WeakMap;function dn(e){if(!e.performedPointerEventsMutation)return;let t=e.pointerEventsScopeElement;t&&is.get(t)===e&&(e.pointerEventsScopeElement?.style.removeProperty("pointer-events"),e.pointerEventsReferenceElement?.style.removeProperty("pointer-events"),e.pointerEventsFloatingElement?.style.removeProperty("pointer-events"),is.delete(t)),e.performedPointerEventsMutation=!1,e.pointerEventsScopeElement=null,e.pointerEventsReferenceElement=null,e.pointerEventsFloatingElement=null}function ss(e,t){let{scopeElement:r,referenceElement:o,floatingElement:n}=t,i=is.get(r);i&&i!==e&&dn(i),dn(e),e.performedPointerEventsMutation=!0,e.pointerEventsScopeElement=r,e.pointerEventsReferenceElement=o,e.pointerEventsFloatingElement=n,is.set(r,e),r.style.pointerEvents="none",o.style.pointerEvents="auto",n.style.pointerEvents="auto"}function pn(e){let t=e.context.dataRef.current,r=Ct(()=>t.hoverInteractionState??xl.create()).current;return t.hoverInteractionState||(t.hoverInteractionState=r),nn(t.hoverInteractionState.disposeEffect),t.hoverInteractionState}function Cl(e,t={}){let{enabled:r=!0,closeDelay:o=0,nodeId:n}=t,i="rootStore"in e?e.rootStore:e,s=i.useState("open"),a=i.useState("floatingElement"),u=i.useState("domReferenceElement"),{dataRef:l}=i.context,c=po(),m=Xi(),d=pn(i),h=xr(),g=Pe(()=>Wi(l.current.openEvent?.type,d.interactedInside)),b=Pe(()=>If(l.current.openEvent?.type)),w=Pe(()=>{dn(d)});we(()=>{s||(d.pointerType=void 0,d.restTimeoutPending=!1,d.interactedInside=!1,w())},[s,d,w]),Sl.useEffect(()=>w,[w]),we(()=>{if(r&&s&&d.handleCloseOptions?.blockPointerEvents&&b()&&Re(u)&&a){let C=u,x=a,v=Rt(a),_=c?.nodesRef.current.find(O=>O.id===m)?.context?.elements.floating;_&&(_.style.pointerEvents="");let k=d.pointerEventsScopeElement!==x?d.pointerEventsScopeElement:null,E=_!==x?_:null,T=d.handleCloseOptions?.getScope?.()??k??E??C.closest("[data-rootownerid]")??v.body;return ss(d,{scopeElement:T,referenceElement:C,floatingElement:x}),()=>{w()}}},[r,s,u,a,d,b,c,m,w]),Sl.useEffect(()=>{if(!r)return;function C(){return!!(c&&m&&Kr(c.nodesRef.current,m).length>0)}function x(O){let I=cr(o,"close",d.pointerType),J=()=>{i.setOpen(!1,De(Oe.triggerHover,O)),c?.events.emit("floating.closed",O)};I?d.openChangeTimeout.start(I,J):(d.openChangeTimeout.clear(),J())}function v(O){let I=Nt(O);if(!Ja(I)){d.interactedInside=!1;return}d.interactedInside=I?.closest("[aria-haspopup]")!=null}function _(){d.openChangeTimeout.clear(),h.clear(),c?.events.off("floating.closed",E),w()}function k(O){if(C()&&c){c.events.on("floating.closed",E);return}if(co(O.relatedTarget,i.context.triggerElements))return;let I=l.current.floatingContext?.nodeId??n,J=O.relatedTarget;if(!(c&&I&&Re(J)&&Kr(c.nodesRef.current,I,!1).some(S=>Ge(S.context?.elements.floating,J)))){if(d.handler){d.handler(O);return}w(),b()&&!g()&&x(O)}}function E(O){!c||!m||C()||h.start(0,()=>{c.events.off("floating.closed",E),i.setOpen(!1,De(Oe.triggerHover,O)),c.events.emit("floating.closed",O)})}let T=a;return Sr(T&&ze(T,"mouseenter",_),T&&ze(T,"mouseleave",k),T&&ze(T,"pointerdown",v,!0),()=>{c?.events.off("floating.closed",E)})},[r,a,i,l,o,n,b,g,w,d,c,m,h])}var go=f(ve(),1),$d=f(lo(),1);var Cw={current:null};function _l(e,t={}){let{enabled:r=!0,delay:o=0,handleClose:n=null,mouseOnly:i=!1,restMs:s=0,move:a=!0,triggerElementRef:u=Cw,externalTree:l,isActiveTrigger:c=!0,getHandleCloseContext:m,isClosing:d,shouldOpen:h,guardStaleOpen:g=!1}=t,b="rootStore"in e?e.rootStore:e,{dataRef:w,events:C}=b.context,x=po(l),v=pn(b),_=go.useRef(!1),k=Yt(n),E=Yt(o),T=Yt(s),O=Yt(r),I=Yt(h),J=Yt(d),D=Pe(()=>Wi(w.current.openEvent?.type,v.interactedInside)),S=Pe(()=>I.current?.()!==!1),L=Pe((N,q,U)=>{let R=b.context.triggerElements;if(R.hasElement(q))return!N||!Ge(N,q);if(!Re(U))return!1;let B=U;return R.hasMatchingElement(re=>Ge(re,B))&&(!N||!Ge(N,B))}),Y=Pe(()=>{if(!v.handler)return;Rt(b.select("domReferenceElement")).removeEventListener("mousemove",v.handler),v.handler=void 0}),A=Pe(()=>{dn(v)});return c&&(v.handleCloseOptions=k.current?.__options),go.useEffect(()=>Y,[Y]),go.useEffect(()=>{if(!r)return;function N(q){q.open?_.current=!1:(_.current=q.reason===Oe.triggerHover,Y(),v.openChangeTimeout.clear(),v.restTimeout.clear(),v.blockMouseMove=!0,v.restTimeoutPending=!1)}return C.on("openchange",N),()=>{C.off("openchange",N)}},[r,C,v,Y]),go.useEffect(()=>{if(!r)return;function N(P,W=!0){let ne=cr(E.current,"close",v.pointerType);ne?v.openChangeTimeout.start(ne,()=>{b.setOpen(!1,De(Oe.triggerHover,P)),x?.events.emit("floating.closed",P)}):W&&(v.openChangeTimeout.clear(),b.setOpen(!1,De(Oe.triggerHover,P)),x?.events.emit("floating.closed",P))}let q=u.current??(c?b.select("domReferenceElement"):null);if(!Re(q))return;function U(P){if(v.openChangeTimeout.clear(),v.blockMouseMove=!1,i&&!Xr(v.pointerType))return;let W=Qa(T.current),ne=cr(E.current,"open",v.pointerType),xe=Nt(P),se=P.currentTarget??null,be=b.select("domReferenceElement"),ye=se;if(Re(xe)&&!b.context.triggerElements.hasElement(xe)){for(let H of b.context.triggerElements.elements())if(Ge(H,xe)){ye=H;break}}Re(se)&&Re(be)&&!b.context.triggerElements.hasElement(se)&&Ge(se,be)&&(ye=be);let $=ye==null?!1:L(be,ye,xe),_e=b.select("open"),Fe=J.current?.()??b.select("transitionStatus")==="ending",xt=!_e&&Fe&&_.current,Le=!$&&Re(ye)&&Re(be)&&Ge(be,ye)&&xt,X=W>0&&!ne,M=$&&(_e||xt)||Le,K=!_e||$;if(M){S()&&b.setOpen(!0,De(Oe.triggerHover,P,ye));return}X||(ne?v.openChangeTimeout.start(ne,()=>{K&&S()&&b.setOpen(!0,De(Oe.triggerHover,P,ye))}):K&&S()&&b.setOpen(!0,De(Oe.triggerHover,P,ye)))}function R(P){if(D()){A();return}Y();let W=b.select("domReferenceElement"),ne=Rt(W);v.restTimeout.clear(),v.restTimeoutPending=!1;let xe=w.current.floatingContext??m?.();if(co(P.relatedTarget,b.context.triggerElements))return;if(k.current&&xe){b.select("open")||v.openChangeTimeout.clear();let be=u.current;v.handler=k.current({...xe,tree:x,x:P.clientX,y:P.clientY,onClose(){A(),Y(),O.current&&!D()&&be===b.select("domReferenceElement")&&N(P,!0)}}),ne.addEventListener("mousemove",v.handler),v.handler(P);return}(v.pointerType!=="touch"||!Ge(b.select("floatingElement"),P.relatedTarget))&&N(P)}function B(P){Ge(q,P.relatedTarget)||(v.openChangeTimeout.clear(),v.restTimeout.clear(),v.restTimeoutPending=!1)}let re=g?ze(q,"mouseout",B):void 0;return a?Sr(ze(q,"mousemove",U,{once:!0}),ze(q,"mouseenter",U),ze(q,"mouseleave",R),re):Sr(ze(q,"mouseenter",U),ze(q,"mouseleave",R),re)},[Y,A,w,E,b,r,k,v,c,L,D,i,a,T,u,x,O,m,J,S,g]),go.useMemo(()=>{if(!r)return;function N(q){v.pointerType=q.pointerType}return{onPointerDown:N,onPointerEnter:N,onMouseMove(q){let{nativeEvent:U}=q,R=q.currentTarget,B=b.select("domReferenceElement"),re=b.select("open"),P=L(B,R,q.target);if(i&&!Xr(v.pointerType))return;if(re&&P&&v.handleCloseOptions?.blockPointerEvents){let xe=b.select("floatingElement");if(xe){let se=v.handleCloseOptions?.getScope?.()??R.ownerDocument.body;ss(v,{scopeElement:se,referenceElement:R,floatingElement:xe})}}let W=Qa(T.current);if(re&&!P||W===0||!P&&v.restTimeoutPending&&q.movementX**2+q.movementY**2<2)return;v.restTimeout.clear();function ne(){if(v.restTimeoutPending=!1,D())return;let xe=b.select("open");!v.blockMouseMove&&(!xe||P)&&S()&&b.setOpen(!0,De(Oe.triggerHover,U,R))}v.pointerType==="touch"?$d.flushSync(()=>{ne()}):P&&re?ne():(v.restTimeoutPending=!0,v.restTimeout.start(W,ne))}}},[r,v,D,L,i,b,T,S])}var ep=.1,_w=ep*ep,Xe=.5;function as(e,t,r,o,n,i){return o>=t!=i>=t&&e<=(n-r)*(t-o)/(i-o)+r}function ls(e,t,r,o,n,i,s,a,u,l){let c=!1;return as(e,t,r,o,n,i)&&(c=!c),as(e,t,n,i,s,a)&&(c=!c),as(e,t,s,a,u,l)&&(c=!c),as(e,t,u,l,r,o)&&(c=!c),c}function Rw(e,t,r){return e>=r.x&&e<=r.x+r.width&&t>=r.y&&t<=r.y+r.height}function cs(e,t,r,o,n,i){let s=Math.min(r,n),a=Math.max(r,n),u=Math.min(o,i),l=Math.max(o,i);return e>=s&&e<=a&&t>=u&&t<=l}function Rl(e={}){let{blockPointerEvents:t=!1}=e,r=new rr,o=({x:n,y:i,placement:s,elements:a,onClose:u,nodeId:l,tree:c})=>{let m=s?.split("-")[0],d=!1,h=null,g=null,b=typeof performance<"u"?performance.now():0;function w(x,v){let _=performance.now(),k=_-b;if(h===null||g===null||k===0)return h=x,g=v,b=_,!1;let E=x-h,T=v-g,O=E*E+T*T,I=k*k*_w;return h=x,g=v,b=_,O0)}function L(){S()||C()}if(S())return;let Y=_.getBoundingClientRect(),A=k.getBoundingClientRect(),N=n>A.right-A.width/2,q=i>A.bottom-A.height/2,U=A.width>Y.width,R=A.height>Y.height,B=(U?Y:A).left,re=(U?Y:A).right,P=(R?Y:A).top,W=(R?Y:A).bottom;if(m==="top"&&i>=Y.bottom-1||m==="bottom"&&i<=Y.top+1||m==="left"&&n>=Y.right-1||m==="right"&&n<=Y.left+1){L();return}let ne=!1;switch(m){case"top":ne=cs(E,T,B,Y.top+1,re,A.bottom-1);break;case"bottom":ne=cs(E,T,B,A.top+1,re,Y.bottom-1);break;case"left":ne=cs(E,T,A.right-1,W,Y.left+1,P);break;case"right":ne=cs(E,T,Y.right-1,W,A.left+1,P);break;default:}if(ne)return;if(d&&!Rw(E,T,Y)){L();return}if(!I&&w(E,T)){L();return}let xe=!1;switch(m){case"top":{let se=U?Xe/2:Xe*4,be=U||N?n+se:n-se,ye=U?n-se:N?n+se:n-se,$=i+Xe+1,_e=N||U?A.bottom-Xe:A.top,Fe=N?U?A.bottom-Xe:A.top:A.bottom-Xe;xe=ls(E,T,be,$,ye,$,A.left,_e,A.right,Fe);break}case"bottom":{let se=U?Xe/2:Xe*4,be=U||N?n+se:n-se,ye=U?n-se:N?n+se:n-se,$=i-Xe,_e=N||U?A.top+Xe:A.bottom,Fe=N?U?A.top+Xe:A.bottom:A.top+Xe;xe=ls(E,T,be,$,ye,$,A.left,_e,A.right,Fe);break}case"left":{let se=R?Xe/2:Xe*4,be=R||q?i+se:i-se,ye=R?i-se:q?i+se:i-se,$=n+Xe+1,_e=q||R?A.right-Xe:A.left,Fe=q?R?A.right-Xe:A.left:A.right-Xe;xe=ls(E,T,_e,A.top,Fe,A.bottom,$,be,$,ye);break}case"right":{let se=R?Xe/2:Xe*4,be=R||q?i+se:i-se,ye=R?i-se:q?i+se:i-se,$=n-Xe,_e=q||R?A.left+Xe:A.right,Fe=q?R?A.left+Xe:A.right:A.left+Xe;xe=ls(E,T,$,be,$,ye,_e,A.top,Fe,A.bottom);break}default:}xe?d||r.start(40,L):L()}};return o.__options={...e,blockPointerEvents:t},o}var us=class extends mo{setState(t){}update(t){}set(t,r){}notifyAll(){}};var zk=(function(e){return e.open="data-open",e.closed="data-closed",e[e.startingStyle=ja.startingStyle]="startingStyle",e[e.endingStyle=ja.endingStyle]="endingStyle",e.anchorHidden="data-anchor-hidden",e.side="data-side",e.align="data-align",e})({});var Ew={"data-popup-open":""};var Tw={"data-open":""},Pw={"data-closed":""},Ow={"data-anchor-hidden":""},tp={open(e){return e?Ew:null}};var ni={open(e){return e?Tw:Pw},anchorHidden(e){return e?Ow:null}},rp={...ni,...gf};function op(e){return rn(19)?e:e?"true":void 0}var fs=f(ve(),1),El=fs.createContext(void 0);function mn(){return fs.useContext(El)?.direction??"ltr"}var nr=f(ve(),1);var kw=e=>({name:"arrow",options:e,async fn(t){let{x:r,y:o,placement:n,rects:i,platform:s,elements:a,middlewareData:u}=t,{element:l,padding:c=0,offsetParent:m="real"}=Nr(e,t)||{};if(l==null)return{};let d=Zi(c),h={x:r,y:o},g=ti(n),b=ei(g),w=await s.getDimensions(l),C=g==="y",x=C?"top":"left",v=C?"bottom":"right",_=C?"clientHeight":"clientWidth",k=i.reference[b]+i.reference[g]-h[g]-i.floating[b],E=h[g]-i.reference[g],T=m==="real"?await s.getOffsetParent?.(l):a.floating,O=a.floating[_]||i.floating[b];(!O||!await s.isElement?.(T))&&(O=a.floating[_]||i.floating[b]);let I=k/2-E/2,J=O/2-w[b]/2-1,D=Math.min(d[x],J),S=Math.min(d[v],J),L=D,Y=O-w[b]-S,A=O/2-w[b]/2+I,N=Yi(L,A,Y),q=!u.arrow&&_r(n)!=null&&A!==N&&i.reference[b]/2-(A({...kw(e),options:[e,t]});var ip={name:"hide",async fn(e){let{width:t,height:r,x:o,y:n}=e.rects.reference,i=t===0&&r===0&&o===0&&n===0,s=await e.platform.detectOverflow(e,{elementContext:"reference"});return{data:{referenceHidden:s.top-r>=0||s.right-t>=0||s.bottom-r>=0||s.left-t>=0||i}}}};var hn={sideX:"left",sideY:"top"};var sp="--available-width",ap="--available-height";function up(e,t,r){let o=e==="inline-start"||e==="inline-end";return{top:"top",right:o?r?"inline-start":"inline-end":"right",bottom:"bottom",left:o?r?"inline-end":"inline-start":"left"}[t]}function lp(e,t,r){let{rects:o,placement:n}=e;return{side:up(t,Tt(n),r),align:_r(n)||"center",anchor:{width:o.reference.width,height:o.reference.height},positioner:{width:o.floating.width,height:o.floating.height}}}function fp(e){return Fw(e,Qd)}function Fw(e,t){let{anchor:r,positionMethod:o="absolute",side:n="bottom",sideOffset:i=0,align:s="center",alignOffset:a=0,collisionBoundary:u,collisionPadding:l=5,sticky:c=!1,arrowPadding:m=5,disableAnchorTracking:d=!1,inline:h,keepMounted:g=!1,floatingRootContext:b,mounted:w,collisionAvoidance:C,shift:x,nodeId:v,adaptiveOrigin:_,lazyFlip:k=!1,externalTree:E}=e,[T,O]=nr.useState(null);!w&&T!==null&&O(null);let I=C.side||"flip",J=C.align||"flip",D=C.fallbackAxisSide||"end",S=x?.crossAxis??!1,L=x?.rootBoundary,Y=typeof r=="function"?r:void 0,A=Pe(Y),N=Y?A:r,q=Yt(r),U=Yt(w),B=mn()==="rtl",re=T||{top:"top",right:"right",bottom:"bottom",left:"left","inline-end":B?"left":"right","inline-start":B?"right":"left"}[n],P=s==="center"?re:`${re}-${s}`,W=l;typeof W=="number"?W={top:W,right:W,bottom:W,left:W}:W&&(W={top:W.top||0,right:W.right||0,bottom:W.bottom||0,left:W.left||0});let ne=1,xe=n==="bottom"?ne:0,se=n==="top"?ne:0,be=n==="right"?ne:0,ye=n==="left"?ne:0,$={boundary:u==="clipping-ancestors"?"clippingAncestors":u,padding:W},_e=nr.useRef(null),Fe=Yt(i),xt=Yt(a),Le=typeof i!="function"?i:0,X=typeof a!="function"?a:0,M=[];h&&M.push(h),M.push(al(G=>{let y=lp(G,n,B),oe=typeof Fe.current=="function"?Fe.current(y):Fe.current,Ae=typeof xt.current=="function"?xt.current(y):xt.current;return{mainAxis:oe,crossAxis:Ae,alignmentAxis:Ae}},[Le,X,B,n]));let K=J==="none"&&I!=="shift",H=!K&&(c||S||I==="shift"),Q=I==="none"?null:ul({...$,padding:{top:W.top+ne+xe,right:W.right+ne+ye,bottom:W.bottom+ne+se,left:W.left+ne+be},mainAxis:!S&&I==="flip",crossAxis:J==="flip"?"alignment":!1,fallbackAxisSideDirection:D}),pe=K?null:ll({...$,rootBoundary:L,mainAxis:J!=="none",crossAxis:H,limiter:c||S?void 0:cl(G=>{if(!_e.current)return{};let{width:y,height:oe}=_e.current.getBoundingClientRect(),Ae=qt(Tt(G.placement)),ee=Ae==="y"?y:oe,Qe=Ae==="y"?W.left+W.right:W.top+W.bottom;return{offset:ee/2+Qe/2}})},[$,c,S,L,W,J]);I==="shift"||J==="shift"||s==="center"?M.push(pe,Q):M.push(Q,pe),M.push(fl({...$,apply({elements:{floating:G},availableWidth:y,availableHeight:oe,rects:Ae}){if(!U.current)return;let ee=G.style;ee.setProperty(sp,`${y}px`),ee.setProperty(ap,`${oe}px`);let Qe=it(G).devicePixelRatio||1,{x:ie,y:Je,width:j,height:z}=Ae.reference,vr=(Math.round((ie+j)*Qe)-Math.round(ie*Qe))/Qe,je=(Math.round((Je+z)*Qe)-Math.round(Je*Qe))/Qe;ee.setProperty("--anchor-width",`${vr}px`),ee.setProperty("--anchor-height",`${je}px`)}}),np(G=>({element:_e.current||Rt(G.elements.floating).createElement("div"),padding:m,offsetParent:"floating"}),[m]),{name:"transformOrigin",fn(G){let{elements:y,middlewareData:oe,placement:Ae,rects:ee,y:Qe}=G,ie=Tt(Ae),Je=qt(ie),j=_e.current,z=oe.arrow?.x||0,vr=oe.arrow?.y||0,je=j?.clientWidth||0,ce=j?.clientHeight||0,br=z+je/2,Or=vr+ce/2,et=Math.abs(oe.shift?.y||0),Me=ee.reference.height/2,$e=typeof i=="function"?i(lp(G,n,B)):i,ut=et>$e,pt={top:`${br}px calc(100% + ${$e}px)`,bottom:`${br}px ${-$e}px`,left:`calc(100% + ${$e}px) ${Or}px`,right:`${-$e}px ${Or}px`}[ie],wr=`${br}px ${ee.reference.y+Me-Qe}px`;return y.floating.style.setProperty("--transform-origin",H&&Je==="y"&&ut?wr:pt),{}}},ip,_),we(()=>{!w&&b&&b.update({referenceElement:null,floatingElement:null,domReferenceElement:null,positionReference:null})},[w,b]);let le=nr.useMemo(()=>({elementResize:!d&&typeof ResizeObserver<"u",layoutShift:!d&&typeof IntersectionObserver<"u"}),[d]),{refs:fe,elements:me,x:he,y:V,middlewareData:te,update:Ne,placement:He,context:ot,isPositioned:Ze,floatingStyles:Be}=t({rootContext:b,open:g?w:void 0,placement:P,middleware:M,strategy:o,whileElementsMounted:g?void 0:(...G)=>ri(...G,le),nodeId:v,externalTree:E}),{sideX:Ue,sideY:ct}=te.adaptiveOrigin||hn,Se=Ze?o:"fixed",Pr=nr.useMemo(()=>{let G;return Ze?_?G={position:Se,[Ue]:he,[ct]:V}:G={...Be,position:Se}:G={position:Se,top:0,left:0},G[sp]="100vw",G[ap]="100vh",Ze||(G.opacity=0),G},[_,Se,Ue,he,ct,V,Be,Ze]),$t=nr.useRef(null);we(()=>{if(!w)return;let G=q.current,y=typeof G=="function"?G():G,Ae=(cp(y)?y.current:y)||null||null;Ae!==$t.current&&(fe.setPositionReference(Ae),$t.current=Ae)},[w,fe,N,q]),nr.useEffect(()=>{if(!w)return;let G=q.current;typeof G!="function"&&cp(G)&&G.current!==$t.current&&(fe.setPositionReference(G.current),$t.current=G.current)},[w,fe,N,q]),nr.useEffect(()=>{if(g&&w&&me.reference&&me.floating)return ri(me.reference,me.floating,Ne,le)},[g,w,me,Ne,le]);let Ye=Tt(He),Yr=up(n,Ye,B),St=_r(He)||"center",kt=!!te.hide?.referenceHidden;we(()=>{k&&w&&Ze&&Ye!==re&&O(Ye)},[k,w,Ze,Ye,re]);let vt=nr.useMemo(()=>({position:"absolute",top:te.arrow?.y,left:te.arrow?.x}),[te.arrow]),F=te.arrow?.centerOffset!==0;return nr.useMemo(()=>({positionerStyles:Pr,arrowStyles:vt,arrowRef:_e,arrowUncentered:F,side:Yr,align:St,physicalSide:Ye,anchorHidden:kt,refs:fe,context:ot,isPositioned:Ze,update:Ne}),[Pr,vt,_e,F,Yr,St,Ye,kt,fe,ot,Ze,Ne])}function cp(e){return e!=null&&"current"in e}function ds(e){return e==="starting"?zf:nt}function dp(e,t,{styles:r,transitionStatus:o,props:n,refs:i,hidden:s,inert:a=!1}){let u={...r};return a&&(u.pointerEvents="none"),Gt("div",e,{state:t,ref:i,props:[{role:"presentation",hidden:s,style:u},ds(o),n],stateAttributesMapping:ni})}var Et=f(ve(),1),xp=f(lo(),1);var pp=f(ve(),1);function mp(e){let[t,r]=pp.useState({current:e,previous:null});return Object.is(e,t.current)||r({current:e,previous:t.current}),t.previous}var gn=f(ve(),1);function Tl(e){let t=Lt(e),r=parseFloat(t.width)||0,o=parseFloat(t.height)||0,n=_t(e),i=n?e.offsetWidth:r,s=n?e.offsetHeight:o;return(fo(r)!==i||fo(o)!==s)&&(r=i,o=s),{width:r,height:o}}function gp(e){let{popupElement:t,positionerElement:r,content:o,mounted:n,onMeasureLayout:i,onMeasureLayoutComplete:s,side:a,direction:u}=e,l=ln(t,!0),c=sn(),m=gn.useRef(null),d=gn.useRef(!0),h=gn.useRef(tr),g=Pe(i),b=Pe(s),w=gn.useMemo(()=>Aw(a,u),[a,u]);we(()=>{if(!n){h.current=tr,d.current=!0,m.current=null;return}if(!t||!r)return;h.current=hp(t,w),Pl(t,"auto");let C=ms(t,"position","static"),x=ms(t,"transform","none"),v=ms(t,"scale","1"),_=hp(r,{"--available-width":"max-content","--available-height":"max-content"});function k(){C(),x(),_()}function E(){k(),v()}if(g?.(),d.current||m.current===null){ps(r,"max-content");let J=Tl(t);return m.current=J,ps(r,J),E(),b?.(null,J),d.current=!1,()=>{h.current(),h.current=tr}}ps(r,"max-content");let T=m.current,O=Tl(t);m.current=O,Pl(t,T),E(),b?.(T,O),ps(r,O);let I=new AbortController;return c.request(()=>{Pl(t,O),l(()=>{t.style.setProperty("--popup-width","auto"),t.style.setProperty("--popup-height","auto")},I.signal)}),()=>{I.abort(),c.cancel(),h.current(),h.current=tr}},[o,t,r,l,c,n,g,b,w])}function Aw(e,t){let r=e==="top",o=e==="left"||e===(t==="rtl"?"inline-end":"inline-start");return!r&&!o?nt:{position:"absolute",[r?"bottom":"top"]:"0",[o?"right":"left"]:"0"}}function ms(e,t,r){let o=e.style.getPropertyValue(t);return e.style.setProperty(t,r),()=>{e.style.setProperty(t,o)}}function hp(e,t){let r=[];for(let[o,n]of Object.entries(t))r.push(ms(e,o,n));return r.length?()=>{r.forEach(o=>o())}:tr}function Pl(e,t){let r=t==="auto"?"auto":`${t.width}px`,o=t==="auto"?"auto":`${t.height}px`;e.style.setProperty("--popup-width",r),e.style.setProperty("--popup-height",o)}function ps(e,t){let r=t==="max-content"?"max-content":`${t.width}px`,o=t==="max-content"?"max-content":`${t.height}px`;e.style.setProperty("--positioner-width",r),e.style.setProperty("--positioner-height",o)}var yp=f(ve(),1);var vp=f(Z(),1),hs=function(t){let{direction:r="ltr"}=t,o=yp.useMemo(()=>({direction:r}),[r]);return(0,vp.jsx)(El.Provider,{value:o,children:t.children})};var bp={name:"adaptiveOrigin",async fn(e){let{x:t,y:r,rects:{floating:o},elements:{floating:n},platform:i,strategy:s,placement:a}=e,u=it(n),l=u.getComputedStyle(n);if(!(l.transitionDuration!=="0s"&&l.transitionDuration!==""))return{x:t,y:r,data:hn};let m=await i.getOffsetParent?.(n),d={width:0,height:0};if(s==="fixed"&&u?.visualViewport)d={width:u.visualViewport.width,height:u.visualViewport.height};else if(m===u){let x=Rt(n);d={width:x.documentElement.clientWidth,height:x.documentElement.clientHeight}}else await i.isElement?.(m)&&(d=await i.getDimensions(m));let h=Tt(a),g=t,b=r;h==="left"&&(g=d.width-(t+o.width)),h==="top"&&(b=d.height-(r+o.height));let w=h==="left"?"right":hn.sideX,C=h==="top"?"bottom":hn.sideY;return{x:g,y:b,data:{sideX:w,sideY:C}}}};var yn=f(Z(),1),Sp={activationDirection:e=>e?{"data-activation-direction":e}:null};function Cp(e){let{store:t,side:r,children:o}=e,n=mn(),i=t.useState("activeTriggerElement"),s=t.useState("activeTriggerId"),a=t.useState("open"),u=t.useState("payload"),l=t.useState("mounted"),c=t.useState("popupElement"),m=t.useState("positionerElement"),d=mp(a?i:null),h=Nw(s,u),g=Et.useRef(null),[b,w]=Et.useState(null),[C,x]=Et.useState(null),v=Et.useRef(null),_=Et.useRef(null),k=ln(v,!0),E=sn(),T=Et.useRef(null),[O,I]=Et.useState(null),[J,D]=Et.useState(!1);we(()=>(t.set("adaptiveOrigin",bp),()=>{t.set("adaptiveOrigin",void 0)}),[t]);let S=Pe(()=>{v.current?.style.setProperty("animation","none"),v.current?.style.setProperty("transition","none"),_.current?.style.setProperty("display","none")}),L=Pe(R=>{v.current?.style.removeProperty("animation"),v.current?.style.removeProperty("transition"),_.current?.style.removeProperty("display"),R&&I(R)}),Y=Pe(()=>{T.current?.abort();let R=new AbortController;T.current=R,k(()=>{w(null),I(null),g.current=null},R.signal)}),A=Et.useRef(null);we(()=>{(!a||!l)&&(A.current=null)},[a,l]),we(()=>{if(i&&d&&i!==d&&A.current!==i&&g.current){w(g.current),D(!0);let R=Lw(d,i);x(R),A.current=i}},[i,d]),we(()=>{b!=null&&(T.current?.abort(),D(!0),E.request(()=>{xp.flushSync(()=>{D(!1)}),Y()}))},[h,b,Y,E]),we(()=>{let R=v.current;if(!R)return;let B=Rt(R).createElement("div");for(let re of Array.from(R.childNodes))B.appendChild(re.cloneNode(!0));g.current=B});let N=b!=null,q;N?q=(0,yn.jsxs)(Et.Fragment,{children:[(0,yn.jsx)("div",{"data-previous":!0,inert:op(!0),ref:_,style:{...O?{"--popup-width":`${O.width}px`,"--popup-height":`${O.height}px`}:null,position:"absolute"},"data-ending-style":J?void 0:""},"previous"),(0,yn.jsx)("div",{"data-current":!0,ref:v,"data-starting-style":J?"":void 0,children:o},h)]}):q=(0,yn.jsx)("div",{"data-current":!0,ref:v,children:o},h),we(()=>{let R=_.current;!R||!b||R.replaceChildren(...Array.from(b.childNodes))},[b]),gp({popupElement:c,positionerElement:m,mounted:l,content:u,onMeasureLayout:S,onMeasureLayoutComplete:L,side:r,direction:n});let U={activationDirection:Iw(C),transitioning:N};return{children:q,state:U}}function Iw(e){if(e)return`${wp(e.horizontal,5,"right","left")} ${wp(e.vertical,5,"down","up")}`}function wp(e,t,r,o){return e>t?r:e<-t?o:""}function Lw(e,t){let r=e.getBoundingClientRect(),o=t.getBoundingClientRect(),n={x:r.left+r.width/2,y:r.top+r.height/2},i={x:o.left+o.width/2,y:o.top+o.height/2};return{horizontal:i.x-n.x,vertical:i.y-n.y}}function Nw(e,t){let[r,o]=Et.useState(0),n=Et.useRef(e),i=Et.useRef(t),s=Et.useRef(!1);return we(()=>{let a=n.current,u=i.current,l=e!==a,c=t!==u;l?(o(m=>m+1),s.current=!c):s.current&&c&&(o(m=>m+1),s.current=!1),n.current=e,i.current=t},[e,t]),`${e??"current"}-${r}`}var gs=f(ve(),1),_p=f(lo(),1);var Rp=f(Z(),1),Ep=gs.forwardRef(function(t,r){let{children:o,container:n,className:i,render:s,style:a,...u}=t,{node:l,subtree:c}=Gf({container:n,ref:r,componentProps:t,elementProps:u});return!c&&!l?null:(0,Rp.jsxs)(gs.Fragment,{children:[c,l&&_p.createPortal(o,l)]})});var Xt={};so(Xt,{Arrow:()=>Gp,Handle:()=>si,Popup:()=>Up,Portal:()=>Bp,Positioner:()=>zp,Provider:()=>qp,Root:()=>Ap,Trigger:()=>Mp,Viewport:()=>Xp,createHandle:()=>Kp});var vn=f(ve(),1);var ys=f(ve(),1),Ol=ys.createContext(void 0);function ur(e){let t=ys.useContext(Ol);if(t===void 0&&!e)throw new Error(lr(72));return t}var Tp=f(ve(),1);var Pp={...Xd,disabled:e=>e.disabled,instantType:e=>e.instantType,isInstantPhase:e=>e.isInstantPhase,trackCursorAxis:e=>e.trackCursorAxis,disableHoverablePopup:e=>e.disableHoverablePopup,lastOpenChangeReason:e=>e.openChangeReason,closeOnClick:e=>e.closeOnClick,closeDelay:e=>e.closeDelay,adaptiveOrigin:e=>e.adaptiveOrigin},vs=class extends mo{constructor(t,r,o){let n=new Ho;super(kp(t,n,r,o),Fp(n),Pp)}setOpen=(t,r)=>{Bd(this,t,r,{extraState:{openChangeReason:r.reason}})};cancelPendingOpen(t){this.state.floatingRootContext.dispatchOpenChange(!1,De(Oe.triggerPress,t))}};function Op(){let e=new Ho,t=new us(Object.freeze(kp(void 0,e)),Object.freeze(Fp(e)),Pp);return Object.assign(t,{setOpen:tr,cancelPendingOpen:tr})}function kp(e,t,r,o=!1){let n={...Yd(),disabled:!1,instantType:void 0,isInstantPhase:!1,trackCursorAxis:"none",disableHoverablePopup:!1,openChangeReason:null,closeOnClick:!0,closeDelay:0,adaptiveOrigin:void 0,...e};return n.floatingRootContext=qd(t,r,o),n}function Fp(e){return{popupRef:Tp.createRef(),onOpenChange:void 0,onOpenChangeComplete:void 0,triggerElements:e}}var ii=f(Z(),1),Ap=hl(function(t){let{disabled:r=!1,defaultOpen:o=!1,open:n,disableHoverablePopup:i=!1,trackCursorAxis:s="none",actionsRef:a,onOpenChange:u,onOpenChangeComplete:l,handle:c,triggerId:m,defaultTriggerId:d=null,children:h}=t,g=Vd((D,S)=>new vs({open:o,openProp:n,activeTriggerId:d,triggerIdProp:m},D,S));g.useControlledProp("openProp",n),g.useControlledProp("triggerIdProp",m),g.useContextCallback("onOpenChange",u),g.useContextCallback("onOpenChangeComplete",l);let b=g.useState("open"),w=!r&&b,C=g.useState("activeTriggerId"),x=g.useState("mounted"),v=g.useState("payload");g.useSyncedValues({trackCursorAxis:s,disableHoverablePopup:i,disabled:r}),zd(g,{closeOnActiveTriggerUnmount:!0});let{forceUnmount:_,transitionStatus:k}=Hd(w,g),E=g.useState("isInstantPhase"),T=g.useState("instantType"),O=g.useState("lastOpenChangeReason"),I=vn.useRef(null);we(()=>{b&&r&&g.setOpen(!1,De(Oe.disabled))},[b,r,g]),we(()=>{k==="ending"&&O===Oe.none||k!=="ending"&&E?(T!=="delay"&&(I.current=T),g.set("instantType","delay")):I.current!==null&&(g.set("instantType",I.current),I.current=null)},[k,E,O,T,g]),we(()=>{w&&C==null&&g.set("payload",void 0)},[g,C,w]),vn.useImperativeHandle(a,()=>({unmount:_,close:()=>g.setOpen(!1,De(Oe.imperativeAction))}),[_,g]);let J=w||x||!r&&s!=="none";return(0,ii.jsxs)(Ol.Provider,{value:g,children:[c&&(0,ii.jsx)(Dd,{handle:c,store:g}),J&&(0,ii.jsx)(Mw,{store:g,disabled:r,trackCursorAxis:s}),typeof h=="function"?h({payload:v}):h]})});function Mw({store:e,disabled:t,trackCursorAxis:r}){let o=e.useState("floatingRootContext"),n=rl(o,{enabled:!t,referencePress:()=>e.select("closeOnClick")}),i=tl(o,{enabled:!t&&r!=="none",axis:r==="none"?void 0:r}),s=vn.useMemo(()=>It(i.reference,n.reference),[i.reference,n.reference]);return Ud(e,{activeTriggerProps:s,inactiveTriggerProps:s,popupProps:n.floating??nt}),null}var ws=f(ve(),1);var bs=f(ve(),1),kl=bs.createContext(void 0);function Ip(){return bs.useContext(kl)}var Np="data-base-ui-tooltip-trigger";function Lp(e){if("composedPath"in e){let r=e.composedPath();for(let o=0;ow.select("transitionStatus")==="ending",shouldOpen(){return!B.current}}),be=wl(_,{enabled:!N}).reference,ye=Le=>{let X=B.current,M=Lp(Le),K=xe(M),H=k.current,Q=H&&M&&Ge(H,M);if(K&&w.select("open")&&w.select("lastOpenChangeReason")===Oe.triggerHover){w.setOpen(!1,De(Oe.triggerHover,Le));return}if(X&&!K&&Q&&!q.current&&!w.select("open")&&H&&Xr(P.current)){let pe=()=>{!B.current&&!q.current&&!w.select("open")&&w.setOpen(!0,De(Oe.triggerHover,Le,H))},le=W();le===0?(re.clear(),pe()):re.start(le,pe)}},$=w.useState("triggerProps",I);return Gt("button",t,{state:{open:v},ref:[r,O,k],props:[se,be,I||U!=="none"?$:void 0,{onMouseOver(Le){ye(Le.nativeEvent)},onFocus(Le){ne(Lp(Le.nativeEvent))&&Le.preventBaseUIHandler()},onMouseLeave(){B.current=!1,re.clear(),P.current=void 0},onPointerEnter(Le){P.current=Le.pointerType},onPointerDown(Le){P.current=Le.pointerType,w.set("closeOnClick",c),c&&!w.select("open")&&w.cancelPendingOpen(Le.nativeEvent)},onClick(Le){c&&!w.select("open")&&w.cancelPendingOpen(Le.nativeEvent)},id:C,"data-trigger-disabled":N?"":void 0,[Np]:N?void 0:""},h],stateAttributesMapping:tp})});var Dp=f(ve(),1);var xs=f(ve(),1),Fl=xs.createContext(void 0);function Vp(){let e=xs.useContext(Fl);if(e===void 0)throw new Error(lr(70));return e}var Al=f(Z(),1),Bp=Dp.forwardRef(function(t,r){let{keepMounted:o=!1,...n}=t;return ur().useState("mounted")||o?(0,Al.jsx)(Fl.Provider,{value:o,children:(0,Al.jsx)(Ep,{ref:r,...n})}):null});var Cs=f(ve(),1);var Ss=f(ve(),1),Il=Ss.createContext(void 0);function bn(){let e=Ss.useContext(Il);if(e===void 0)throw new Error(lr(71));return e}var jp=f(Z(),1),zp=Cs.forwardRef(function(t,r){let{render:o,className:n,anchor:i,positionMethod:s="absolute",side:a="top",align:u="center",sideOffset:l=0,alignOffset:c=0,collisionBoundary:m="clipping-ancestors",collisionPadding:d=5,arrowPadding:h=5,sticky:g=!1,disableAnchorTracking:b=!1,collisionAvoidance:w=Hf,style:C,...x}=t,v=ur(),_=Vp(),k=v.useState("open"),E=v.useState("mounted"),T=v.useState("trackCursorAxis"),O=v.useState("disableHoverablePopup"),I=v.useState("floatingRootContext"),J=v.useState("instantType"),D=v.useState("transitionStatus"),S=v.useState("adaptiveOrigin"),L=fp({anchor:i,positionMethod:s,floatingRootContext:I,mounted:E,side:a,sideOffset:l,align:u,alignOffset:c,collisionBoundary:m,collisionPadding:d,sticky:g,arrowPadding:h,disableAnchorTracking:b,keepMounted:_,collisionAvoidance:w,adaptiveOrigin:S}),Y=Cs.useMemo(()=>({open:k,side:L.side,align:L.align,anchorHidden:L.anchorHidden,instant:T!=="none"?"tracking-cursor":J}),[k,L.side,L.align,L.anchorHidden,T,J]),A=dp(t,Y,{styles:L.positionerStyles,transitionStatus:D,props:x,refs:[r,v.useStateSetter("positionerElement")],hidden:!E,inert:!k||T==="both"||O});return(0,jp.jsx)(Il.Provider,{value:L,children:A})});var Hp=f(ve(),1);var Up=Hp.forwardRef(function(t,r){let{render:o,className:n,style:i,...s}=t,a=ur(),{side:u,align:l}=bn(),c=a.useState("open"),m=a.useState("instantType"),d=a.useState("transitionStatus"),h=a.useState("popupProps"),g=a.useState("floatingRootContext"),b=a.useState("disabled"),w=a.useState("closeDelay");zi({open:c,ref:a.context.popupRef,onComplete(){c&&a.context.onOpenChangeComplete?.(!0)}}),Cl(g,{enabled:!b,closeDelay:w});let C=a.useStateSetter("popupElement");return Gt("div",t,{state:{open:c,side:u,align:l,instant:m,transitionStatus:d},ref:[r,a.context.popupRef,C],props:[Md,h,ds(d),s],stateAttributesMapping:rp})});var Wp=f(ve(),1);var Gp=Wp.forwardRef(function(t,r){let{render:o,className:n,style:i,...s}=t,a=ur(),{arrowRef:u,side:l,align:c,arrowUncentered:m,arrowStyles:d}=bn(),h=a.useState("open"),g=a.useState("instantType");return Gt("div",t,{state:{open:h,side:l,align:c,uncentered:m,instant:g},ref:[r,u],props:[{style:d,"aria-hidden":!0},s],stateAttributesMapping:ni})});var Yp=f(ve(),1);var Ll=f(Z(),1),qp=function(t){let{delay:r,closeDelay:o,timeout:n=400}=t,i=Yp.useMemo(()=>({open:r,close:o}),[r,o]);return(0,Ll.jsx)(kl.Provider,{value:r,children:(0,Ll.jsx)($a,{delay:i,timeoutMs:n,children:t.children})})};var Zp=f(ve(),1);var Xp=Zp.forwardRef(function(t,r){let{render:o,className:n,style:i,children:s,...a}=t,u=ur(),l=bn(),c=u.useState("instantType"),{children:m,state:d}=Cp({store:u,side:l.side,children:s}),h={activationDirection:d.activationDirection,transitioning:d.transitioning,instant:c};return Gt("div",t,{state:h,ref:r,props:[a,{children:m}],stateAttributesMapping:Sp})});var si=class extends es{constructor(){super(Op(),"Tooltip")}open(t){this.openByTrigger(t)}close(){this.closePopup()}get isOpen(){return this.attachedStore?.select("open")??!1}};function Kp(){return new si}function Vr(e){return Gt(e.defaultTagName??"div",e,e)}var $p=f(Te(),1),Nl="data-wp-hash";function Ml(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&jw(document)),e.__wpStyleRuntime}function Bw(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${Nl}]`))if(r.getAttribute(Nl)===t)return!0;return!1}function em(e,t,r){if(!e.head)return;let o=Ml(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(Bw(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(Nl,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function jw(e){let t=Ml();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)em(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function tm(e,t){let r=Ml();r.styles.set(e,t);for(let o of r.documents.keys())em(o,e,t)}typeof process>"u",tm("a495f9d138",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._83ed8a8da5dd50ea__text{margin:0}._14437cfb77831647__heading-2xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-2xl,32px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-2xl,32px);--_gcd-p-line-height:var(--wpds-typography-line-height-2xl,40px);font-size:var(--wpds-typography-font-size-2xl,32px);line-height:var(--wpds-typography-line-height-2xl,40px)}._14437cfb77831647__heading-2xl,._3c78b7fa9b4072dd__heading-xl{font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-emphasis,600)}._3c78b7fa9b4072dd__heading-xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-p-line-height:var(--wpds-typography-line-height-md,24px);font-size:var(--wpds-typography-font-size-xl,20px);line-height:var(--wpds-typography-line-height-md,24px)}.aa58f227716bcde2__heading-lg{--_gcd-heading-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-lg,15px)}.aa58f227716bcde2__heading-lg,.fc4da56d8dfe52c4__heading-md{font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:var(--wpds-typography-line-height-sm,20px)}.fc4da56d8dfe52c4__heading-md{--_gcd-heading-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-md,13px)}.a9b78c7c82e8dff7__heading-sm{--_gcd-heading-font-size:var(--wpds-typography-font-size-xs,11px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-xs,11px);--_gcd-p-line-height:var(--wpds-typography-line-height-xs,16px);font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-xs,11px);font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:var(--wpds-typography-line-height-xs,16px);text-transform:uppercase}._305ff559e52180d5__body-xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-p-line-height:var(--wpds-typography-line-height-xl,32px);font-size:var(--wpds-typography-font-size-xl,20px);line-height:var(--wpds-typography-line-height-xl,32px)}._305ff559e52180d5__body-xl,.ca1aa3fc2029e958__body-lg{font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-default,400)}.ca1aa3fc2029e958__body-lg{--_gcd-heading-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-p-line-height:var(--wpds-typography-line-height-md,24px);font-size:var(--wpds-typography-font-size-lg,15px);line-height:var(--wpds-typography-line-height-md,24px)}._131101940be12424__body-md{--_gcd-heading-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-md,13px);line-height:var(--wpds-typography-line-height-sm,20px)}._0e8d87a42c1f75fa__body-sm,._131101940be12424__body-md{font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-default,400)}._0e8d87a42c1f75fa__body-sm{--_gcd-heading-font-size:var(--wpds-typography-font-size-sm,12px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-sm,12px);--_gcd-p-line-height:var(--wpds-typography-line-height-xs,16px);font-size:var(--wpds-typography-font-size-sm,12px);line-height:var(--wpds-typography-line-height-xs,16px)}}}');var Jp={text:"_83ed8a8da5dd50ea__text","heading-2xl":"_14437cfb77831647__heading-2xl","heading-xl":"_3c78b7fa9b4072dd__heading-xl","heading-lg":"aa58f227716bcde2__heading-lg","heading-md":"fc4da56d8dfe52c4__heading-md","heading-sm":"a9b78c7c82e8dff7__heading-sm","body-xl":"_305ff559e52180d5__body-xl","body-lg":"ca1aa3fc2029e958__body-lg","body-md":"_131101940be12424__body-md","body-sm":"_0e8d87a42c1f75fa__body-sm"};typeof process>"u",tm("af6d9984a6","._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}");var Qp={button:"_6defc79820e382c6__button",input:"d2cff2e5dea83bd1__input",textarea:"_547d86373d02e108__textarea",div:"_8c15fd0ed9f28ba4__div",p:"_43cec3e1eec1066d__p",heading:"e97669c6d9a38497__heading",a:"_2c0831b0499dbd6e__a"},wn=(0,$p.forwardRef)(function({variant:t="body-md",render:r,className:o,...n},i){return Vr({render:r,defaultTagName:"span",ref:i,props:It(n,{className:We(Jp.text,Qp.heading,Qp.p,Jp[t],o)})})});var _s=f(Te(),1),ai=(0,_s.forwardRef)(({icon:e,size:t=24,...r},o)=>(0,_s.cloneElement)(e,{width:t,height:t,...r,ref:o}));var Rs=f(xn(),1),Vl=f(Z(),1),Uo=(0,Vl.jsx)(Rs.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,Vl.jsx)(Rs.Path,{d:"M14.6 7l-1.2-1L8 12l5.4 6 1.2-1-4.6-5z"})});var Es=f(xn(),1),Dl=f(Z(),1),Wo=(0,Dl.jsx)(Es.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,Dl.jsx)(Es.Path,{d:"M10.6 6L9.4 7l4.6 5-4.6 5 1.2 1 5.4-6z"})});var Ts=f(xn(),1),Bl=f(Z(),1),jl=(0,Bl.jsx)(Ts.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,Bl.jsx)(Ts.Path,{d:"M13 19h-2v-2h2v2zm0-6h-2v-2h2v2zm0-6h-2V5h2v2z"})});var Ps=f(xn(),1),zl=f(Z(),1),Os=(0,zl.jsx)(Ps.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,zl.jsx)(Ps.Path,{d:"M6.6 6L5.4 7l4.5 5-4.5 5 1.1 1 5.5-6-5.4-6zm6 0l-1.1 1 4.5 5-4.5 5 1.1 1 5.5-6-5.5-6z"})});var ks=f(xn(),1),Hl=f(Z(),1),Fs=(0,Hl.jsx)(ks.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,Hl.jsx)(ks.Path,{d:"M11.6 7l-1.1-1L5 12l5.5 6 1.1-1L7 12l4.6-5zm6 0l-1.1-1-5.5 6 5.5 6 1.1-1-4.6-5 4.6-5z"})});var Sn={};so(Sn,{Popup:()=>Cm,Portal:()=>As,Positioner:()=>Is,Provider:()=>Am,Root:()=>km,Trigger:()=>Em});var xm=f(Te(),1);var lm=f(Te(),1);var Wl="data-wp-hash";function Gl(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Hw(document)),e.__wpStyleRuntime}function zw(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${Wl}]`))if(r.getAttribute(Wl)===t)return!0;return!1}function im(e,t,r){if(!e.head)return;let o=Gl(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(zw(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(Wl,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function Hw(e){let t=Gl();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)im(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function Uw(e,t){let r=Gl();r.styles.set(e,t);for(let o of r.documents.keys())im(o,e,t)}typeof process>"u",Uw("be37f31c1e","._11fc52b637ff8a7e__slot{inset:0;isolation:isolate;pointer-events:none;position:fixed;z-index:1000000003}@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._11fc52b637ff8a7e__slot>*{pointer-events:auto}}}");var nm={slot:"_11fc52b637ff8a7e__slot"},sm="data-wp-compat-overlay-slot";function Ww(){return typeof document>"u"?null:document}function Gw(){let e;try{e=window.top?.wp}catch{}let t=e??window.wp;return typeof t?.components=="object"&&t.components!==null}var Dr=null;function Ul(e){return e.setAttribute("aria-hidden","false"),e}function Yw(e){let t=e.createElement("div");return t.setAttribute(sm,""),nm.slot&&t.classList.add(nm.slot),e.body.appendChild(t),t}function am(){if(typeof window>"u"||!Gw()&&window.__wpUiCompatOverlaySlotEnabled!==!0)return;let e=Ww();if(!e||!e.body)return;if(Dr&&Dr.ownerDocument===e&&Dr.isConnected)return Ul(Dr);let t=e.querySelector(`[${sm}]`);return t instanceof HTMLDivElement?(Dr=Ul(t),Dr):(Dr?.isConnected&&Dr.remove(),Dr=Ul(Yw(e)),Dr)}var cm=f(Z(),1),As=(0,lm.forwardRef)(function({container:t,...r},o){return(0,cm.jsx)(Xt.Portal,{container:t??am(),...r,ref:o})});var um=f(Te(),1),pm=f(Z(),1),Yl="data-wp-hash";function ql(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Zw(document)),e.__wpStyleRuntime}function qw(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${Yl}]`))if(r.getAttribute(Yl)===t)return!0;return!1}function fm(e,t,r){if(!e.head)return;let o=ql(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(qw(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(Yl,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function Zw(e){let t=ql();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)fm(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function dm(e,t){let r=ql();r.styles.set(e,t);for(let o of r.documents.keys())fm(o,e,t)}typeof process>"u",dm("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var Xw={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",dm("19fcc06039",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}');var Kw={positioner:"_480b748dd3510e64__positioner",popup:"_50096b232db7709d__popup"},Is=(0,um.forwardRef)(function({align:t="center",className:r,side:o="top",sideOffset:n=4,...i},s){return(0,pm.jsx)(Xt.Positioner,{ref:s,align:t,side:o,sideOffset:n,...i,className:We(Xw["box-sizing"],Kw.positioner,r)})});var mm=f(Te(),1);function Zl(e,t,r){return(0,mm.cloneElement)(e??t,{children:r})}var Jw=f(gm(),1);var vm=f(li(),1),{lock:dA,unlock:bm}=(0,vm.__dangerousOptInToUnstableAPIsOnlyForCoreModules)("I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.","@wordpress/ui");function Qw(){let e=Jw;if(e.ThemeProvider)return e.ThemeProvider;if(!e.privateApis)throw new Error("@wordpress/ui: @wordpress/theme must expose `ThemeProvider` or `privateApis.ThemeProvider`.");return bm(e.privateApis).ThemeProvider}var wm=Qw();var ci=f(Z(),1),Xl="data-wp-hash";function Kl(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&e1(document)),e.__wpStyleRuntime}function $w(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${Xl}]`))if(r.getAttribute(Xl)===t)return!0;return!1}function Sm(e,t,r){if(!e.head)return;let o=Kl(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if($w(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(Xl,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function e1(e){let t=Kl();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)Sm(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function t1(e,t){let r=Kl();r.styles.set(e,t);for(let o of r.documents.keys())Sm(o,e,t)}typeof process>"u",t1("19fcc06039",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}');var r1={positioner:"_480b748dd3510e64__positioner",popup:"_50096b232db7709d__popup"},o1={background:"#1e1e1e"},Cm=(0,xm.forwardRef)(function({portal:t,positioner:r,children:o,className:n,...i},s){let a=(0,ci.jsx)(wm,{color:o1,children:(0,ci.jsx)(Xt.Popup,{ref:s,className:We(r1.popup,n),...i,children:o})}),u=Zl(r,(0,ci.jsx)(Is,{}),a);return Zl(t,(0,ci.jsx)(As,{}),u)});var _m=f(Te(),1),Rm=f(Z(),1),Em=(0,_m.forwardRef)(function(t,r){return(0,Rm.jsx)(Xt.Trigger,{ref:r,...t})});var Tm=f(ge(),1),Pm=f(Z(),1);function Om({children:e}){return(0,Pm.jsx)(hs,{direction:(0,Tm.isRTL)()?"rtl":"ltr",children:e})}var Jl=f(Z(),1);function km(e){return(0,Jl.jsx)(Om,{children:(0,Jl.jsx)(Xt.Root,{...e})})}var Fm=f(Z(),1);function Am({...e}){return(0,Fm.jsx)(Xt.Provider,{...e})}var Im=f(Te(),1),Ql="data-wp-hash";function $l(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&i1(document)),e.__wpStyleRuntime}function n1(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${Ql}]`))if(r.getAttribute(Ql)===t)return!0;return!1}function Lm(e,t,r){if(!e.head)return;let o=$l(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(n1(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(Ql,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function i1(e){let t=$l();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)Lm(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function s1(e,t){let r=$l();r.styles.set(e,t);for(let o of r.documents.keys())Lm(o,e,t)}typeof process>"u",s1("fa606a57ae","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.f37b9e2e191ebd66__visually-hidden{word-wrap:normal;border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-break:normal}}}");var a1={"visually-hidden":"f37b9e2e191ebd66__visually-hidden"},ec=(0,Im.forwardRef)(function({render:t,...r},o){return Vr({render:t,ref:o,props:It({className:a1["visually-hidden"]},r,{"data-visually-hidden":""})})});var Nm=f(Te(),1),tc="data-wp-hash";function rc(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&c1(document)),e.__wpStyleRuntime}function l1(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${tc}]`))if(r.getAttribute(tc)===t)return!0;return!1}function Mm(e,t,r){if(!e.head)return;let o=rc(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(l1(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(tc,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function c1(e){let t=rc();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)Mm(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function u1(e,t){let r=rc();r.styles.set(e,t);for(let o of r.documents.keys())Mm(o,e,t)}typeof process>"u",u1("32aba35fe1","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._19ce0419607e1896__stack{display:flex}}}");var f1={stack:"_19ce0419607e1896__stack"},d1={xs:"var(--wpds-dimension-gap-xs, 4px)",sm:"var(--wpds-dimension-gap-sm, 8px)",md:"var(--wpds-dimension-gap-md, 12px)",lg:"var(--wpds-dimension-gap-lg, 16px)",xl:"var(--wpds-dimension-gap-xl, 24px)","2xl":"var(--wpds-dimension-gap-2xl, 32px)","3xl":"var(--wpds-dimension-gap-3xl, 40px)"},vo=(0,Nm.forwardRef)(function({direction:t,gap:r,align:o,justify:n,wrap:i,render:s,...a},u){let l={gap:r&&d1[r],alignItems:o,justifyContent:n,flexDirection:t,flexWrap:i};return Vr({render:s,ref:u,props:It(a,{style:l,className:f1.stack})})});var Vm=f(Te(),1),Dm=f(ge(),1),Cn=f(Z(),1),oc="data-wp-hash";function nc(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&m1(document)),e.__wpStyleRuntime}function p1(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${oc}]`))if(r.getAttribute(oc)===t)return!0;return!1}function Bm(e,t,r){if(!e.head)return;let o=nc(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(p1(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(oc,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function m1(e){let t=nc();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)Bm(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function Ns(e,t){let r=nc();r.styles.set(e,t);for(let o of r.documents.keys())Bm(o,e,t)}typeof process>"u",Ns("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var h1={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",Ns("96553466c8","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._64de9947bf305b7a__outset-ring--focus-within-visible:focus-within:has(:focus-visible),.af79fb116edb0dd7__outset-ring--focus:focus,.dfcfdc28396e5d98__outset-ring--focus-visible:focus-visible,.e5cd9ee879f6403a__outset-ring--focus-within:focus-within,:focus-visible ._81935a08e952f267__outset-ring--focus-parent-visible{--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within,.abc777e9713fa711__outset-ring--focus-except-active:focus{outline:none}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within:not(:has(:active)),.abc777e9713fa711__outset-ring--focus-except-active:focus:not(:active){--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}}}");var g1={"outset-ring--focus":"af79fb116edb0dd7__outset-ring--focus","outset-ring--focus-visible":"dfcfdc28396e5d98__outset-ring--focus-visible","outset-ring--focus-within":"e5cd9ee879f6403a__outset-ring--focus-within","outset-ring--focus-within-visible":"_64de9947bf305b7a__outset-ring--focus-within-visible","outset-ring--focus-parent-visible":"_81935a08e952f267__outset-ring--focus-parent-visible","outset-ring--focus-except-active":"abc777e9713fa711__outset-ring--focus-except-active","outset-ring--focus-within-except-active":"_3c9f5ee9fc9c136d__outset-ring--focus-within-except-active"};typeof process>"u",Ns("e8e6a9be37",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.d4250949359b05ce__link{text-decoration-thickness:from-font;text-underline-offset:.2em}.c6055659b8e2cd2c__is-brand,.c6055659b8e2cd2c__is-brand:visited{--_gcd-a-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9))}.c6055659b8e2cd2c__is-brand:active,.c6055659b8e2cd2c__is-brand:hover{--_gcd-a-color:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));color:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000))}._92e0dfcaeee15b88__is-neutral,._92e0dfcaeee15b88__is-neutral:visited{--_gcd-a-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);text-decoration-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d)}._92e0dfcaeee15b88__is-neutral:active,._92e0dfcaeee15b88__is-neutral:hover{--_gcd-a-color:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);color:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e)}.cf122a9bf1035d42__is-unstyled{--_gcd-a-color:inherit;color:inherit;text-decoration:none}._0cb411afac4c86c7__link-icon{display:inline-block;font-weight:var(--wpds-typography-font-weight-default,400);line-height:1;margin-inline-start:var(--wpds-dimension-padding-xs,4px);text-decoration:none}._0cb411afac4c86c7__link-icon:after{content:"\\2197"}._0cb411afac4c86c7__link-icon:dir(rtl):after{content:"\\2196"}}}');var Ls={link:"d4250949359b05ce__link","is-brand":"c6055659b8e2cd2c__is-brand","is-neutral":"_92e0dfcaeee15b88__is-neutral","is-unstyled":"cf122a9bf1035d42__is-unstyled","link-icon":"_0cb411afac4c86c7__link-icon"};typeof process>"u",Ns("af6d9984a6","._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}");var y1={button:"_6defc79820e382c6__button",input:"d2cff2e5dea83bd1__input",textarea:"_547d86373d02e108__textarea",div:"_8c15fd0ed9f28ba4__div",p:"_43cec3e1eec1066d__p",heading:"e97669c6d9a38497__heading",a:"_2c0831b0499dbd6e__a"},ic=(0,Vm.forwardRef)(function({children:t,variant:r="default",tone:o="brand",openInNewTab:n=!1,render:i,className:s,...a},u){return Vr({render:i,defaultTagName:"a",ref:u,props:It(a,{className:We(y1.a,h1["box-sizing"],g1["outset-ring--focus-except-active"],r!=="unstyled"&&Ls.link,r!=="unstyled"&&Ls[`is-${o}`],r==="unstyled"&&Ls["is-unstyled"],s),target:n?"_blank":void 0,children:(0,Cn.jsxs)(Cn.Fragment,{children:[t,n&&(0,Cn.jsx)("span",{className:Ls["link-icon"],role:"img","aria-label":(0,Dm.__)("(opens in a new tab)")})]})})})});var zm=f(Te(),1),sc="data-wp-hash";function ac(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&b1(document)),e.__wpStyleRuntime}function v1(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${sc}]`))if(r.getAttribute(sc)===t)return!0;return!1}function Hm(e,t,r){if(!e.head)return;let o=ac(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(v1(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(sc,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function b1(e){let t=ac();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)Hm(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function Um(e,t){let r=ac();r.styles.set(e,t);for(let o of r.documents.keys())Hm(o,e,t)}typeof process>"u",Um("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var w1={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",Um("ed2c39ec90","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.b20cc1690085c2f0__skeleton{background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);display:block;@media (forced-colors:active){border:var(--wpds-border-width-xs,1px) solid CanvasText}}._9b143194fdb45f93__pulse{@media not (prefers-reduced-motion){animation:e2b9fe0690281bc8__skeleton-pulse 1.5s ease-in-out infinite}}@keyframes e2b9fe0690281bc8__skeleton-pulse{0%,to{opacity:1}50%{opacity:.4}}}}");var jm={skeleton:"b20cc1690085c2f0__skeleton",pulse:"_9b143194fdb45f93__pulse","skeleton-pulse":"e2b9fe0690281bc8__skeleton-pulse"},ui=(0,zm.forwardRef)(function({render:t,...r},o){return Vr({render:t,ref:o,props:It({className:We(jm.skeleton,jm.pulse,w1["box-sizing"]),"aria-hidden":!0},r)})});var Wm=f(Te(),1),Gm=f(Z(),1),Ym=(0,Wm.forwardRef)(({children:e,className:t,ariaLabel:r,as:o="div",...n},i)=>(0,Gm.jsx)(o,{ref:i,className:We("admin-ui-navigable-region",t),"aria-label":r,role:"region",tabIndex:"-1",...n,children:e}));Ym.displayName="NavigableRegion";var qm=Ym;var Zm=f(ge(),1);var bo=f(Z(),1),cc="data-wp-hash";function uc(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&S1(document)),e.__wpStyleRuntime}function x1(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${cc}]`))if(r.getAttribute(cc)===t)return!0;return!1}function Xm(e,t,r){if(!e.head)return;let o=uc(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(x1(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(cc,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function S1(e){let t=uc();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)Xm(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function C1(e,t){let r=uc();r.styles.set(e,t);for(let o of r.documents.keys())Xm(o,e,t)}typeof process>"u",C1("72ef022400",".bfb5a2dd8cceebd3__list{--focus-ring-size:calc(var(--wpds-border-width-focus, var(--wp-admin-border-width-focus, 2px))*2);list-style:none;margin:calc(var(--focus-ring-size)*-1);overflow-x:auto;padding:var(--focus-ring-size);scroll-padding:var(--focus-ring-size)}.a4759b4cb2c8bd92__li{flex-shrink:0}._07da506d3f2d9afe__item{align-items:center;color:var(--wpds-color-foreground-interactive-neutral-weak,#707070);display:flex;font-weight:var(--wpds-typography-font-weight-default,400);min-block-size:44px;min-inline-size:44px;text-decoration:none}._07da506d3f2d9afe__item:hover,._07da506d3f2d9afe__item[aria-current=page]{color:var(--wpds-color-foreground-interactive-neutral-weak-active,#1e1e1e)}._07da506d3f2d9afe__item[aria-current=page]{font-weight:var(--wpds-typography-font-weight-emphasis,600)}");var lc={list:"bfb5a2dd8cceebd3__list",li:"a4759b4cb2c8bd92__li",item:"_07da506d3f2d9afe__item"},_1=({items:e,currentHref:t,ariaLabel:r=(0,Zm.__)("Sections"),linkComponent:o,className:n})=>{if(!e.length)return null;let i=o??"a";return(0,bo.jsx)("nav",{"aria-label":r,className:n,children:(0,bo.jsx)(vo,{render:(0,bo.jsx)("ul",{role:"list"}),direction:"row",align:"center",gap:"md",className:lc.list,children:e.map(s=>(0,bo.jsx)("li",{className:lc.li,children:(0,bo.jsx)(wn,{variant:"body-md",className:lc.item,render:(0,bo.jsx)(ic,{variant:"unstyled","aria-current":s.href===t?"page":void 0,render:(0,bo.jsx)(i,{href:s.href})}),children:s.label})},s.href))})})},Km=_1;var Qm=f(ue(),1),{Fill:$m,Slot:eh}=(0,Qm.createSlotFill)("SidebarToggle");var ir=f(Z(),1),fc="data-wp-hash";function dc(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&E1(document)),e.__wpStyleRuntime}function R1(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${fc}]`))if(r.getAttribute(fc)===t)return!0;return!1}function th(e,t,r){if(!e.head)return;let o=dc(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(R1(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(fc,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function E1(e){let t=dc();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)th(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function T1(e,t){let r=dc();r.styles.set(e,t);for(let o of r.documents.keys())th(o,e,t)}typeof process>"u",T1("1f3750277d","._956b6df0898efed0__page{text-wrap:pretty;background-color:var(--wpds-color-background-surface-neutral,#fcfcfc);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);display:flex;flex-flow:column;height:100%;position:relative;z-index:1}._0625b55e82a0d93d__header{background:var(--wpds-color-background-surface-neutral-strong,#fff);border-block-end:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral-weak,#f0f0f0);inset-block-start:0;padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px);position:sticky;z-index:1}.a43c44d5ae28b2e8__header-content{min-height:var(--wpds-dimension-size-md,32px)}.b7cb5b9daf3a3b25__header-actions{flex-shrink:0}._8bcd33103b451f30__header-lockup{min-width:0}._8113be94e7caf73c__header-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._9a776c7f70996f61__header-visual{display:grid;flex-shrink:0;grid-template-columns:1fr;grid-template-rows:1fr;height:var(--wpds-dimension-size-sm,24px);width:var(--wpds-dimension-size-sm,24px);>*{grid-column:1/-1;grid-row:1/-1;max-height:100%;max-width:100%}}.d5e0920cd15d35bc__sidebar-toggle-slot:empty{display:none}._60fea2f6bf5319cd__header-subtitle{color:var(--wpds-color-foreground-content-neutral-weak,#707070);padding-block-end:var(--wpds-dimension-padding-xs,4px)}._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation,._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation ._60fea2f6bf5319cd__header-subtitle{padding-block-end:0}._673c99dcbfb58211__header-navigation{margin-block-start:var(--wpds-dimension-gap-md,12px)}.be5e57d029ec4036__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;&._128806d0b26e3a50__has-padding{padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px)}}");var Br={page:"_956b6df0898efed0__page",header:"_0625b55e82a0d93d__header","header-content":"a43c44d5ae28b2e8__header-content","header-actions":"b7cb5b9daf3a3b25__header-actions","header-lockup":"_8bcd33103b451f30__header-lockup","header-title":"_8113be94e7caf73c__header-title","header-visual":"_9a776c7f70996f61__header-visual","sidebar-toggle-slot":"d5e0920cd15d35bc__sidebar-toggle-slot","header-subtitle":"_60fea2f6bf5319cd__header-subtitle","has-navigation":"_4b0f17e503d11619__has-navigation","header-navigation":"_673c99dcbfb58211__header-navigation",content:"be5e57d029ec4036__content","has-padding":"_128806d0b26e3a50__has-padding"};function rh({headingLevel:e=1,breadcrumbs:t,badges:r,visual:o,title:n,subTitle:i,actions:s,navigation:a,components:u,showSidebarToggle:l=!0}){let c=`h${e}`,m=!!a?.items?.length;return(0,ir.jsxs)(vo,{direction:"column",className:We(Br.header,m&&Br["has-navigation"]),children:[(0,ir.jsxs)(vo,{className:Br["header-content"],direction:"row",gap:"sm",justify:"space-between",children:[(0,ir.jsxs)(vo,{direction:"row",gap:"sm",align:"center",justify:"start",className:Br["header-lockup"],children:[l&&(0,ir.jsx)(eh,{bubblesVirtually:!0,className:Br["sidebar-toggle-slot"]}),o&&(0,ir.jsx)("div",{className:Br["header-visual"],"aria-hidden":"true",children:o}),n&&(0,ir.jsx)(wn,{className:Br["header-title"],render:(0,ir.jsx)(c,{}),variant:"heading-lg",children:n}),t,r]}),s&&(0,ir.jsx)(vo,{align:"center",className:Br["header-actions"],direction:"row",gap:"sm",children:s})]}),i&&(0,ir.jsx)(wn,{render:(0,ir.jsx)("p",{}),variant:"body-md",className:Br["header-subtitle"],children:i}),m&&(0,ir.jsx)(Km,{...a,linkComponent:u?.link,className:Br["header-navigation"]})]})}var fi=f(Z(),1),mc="data-wp-hash";function hc(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&O1(document)),e.__wpStyleRuntime}function P1(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${mc}]`))if(r.getAttribute(mc)===t)return!0;return!1}function oh(e,t,r){if(!e.head)return;let o=hc(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(P1(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(mc,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function O1(e){let t=hc();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)oh(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function k1(e,t){let r=hc();r.styles.set(e,t);for(let o of r.documents.keys())oh(o,e,t)}typeof process>"u",k1("1f3750277d","._956b6df0898efed0__page{text-wrap:pretty;background-color:var(--wpds-color-background-surface-neutral,#fcfcfc);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);display:flex;flex-flow:column;height:100%;position:relative;z-index:1}._0625b55e82a0d93d__header{background:var(--wpds-color-background-surface-neutral-strong,#fff);border-block-end:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral-weak,#f0f0f0);inset-block-start:0;padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px);position:sticky;z-index:1}.a43c44d5ae28b2e8__header-content{min-height:var(--wpds-dimension-size-md,32px)}.b7cb5b9daf3a3b25__header-actions{flex-shrink:0}._8bcd33103b451f30__header-lockup{min-width:0}._8113be94e7caf73c__header-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._9a776c7f70996f61__header-visual{display:grid;flex-shrink:0;grid-template-columns:1fr;grid-template-rows:1fr;height:var(--wpds-dimension-size-sm,24px);width:var(--wpds-dimension-size-sm,24px);>*{grid-column:1/-1;grid-row:1/-1;max-height:100%;max-width:100%}}.d5e0920cd15d35bc__sidebar-toggle-slot:empty{display:none}._60fea2f6bf5319cd__header-subtitle{color:var(--wpds-color-foreground-content-neutral-weak,#707070);padding-block-end:var(--wpds-dimension-padding-xs,4px)}._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation,._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation ._60fea2f6bf5319cd__header-subtitle{padding-block-end:0}._673c99dcbfb58211__header-navigation{margin-block-start:var(--wpds-dimension-gap-md,12px)}.be5e57d029ec4036__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;&._128806d0b26e3a50__has-padding{padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px)}}");var pc={page:"_956b6df0898efed0__page",header:"_0625b55e82a0d93d__header","header-content":"a43c44d5ae28b2e8__header-content","header-actions":"b7cb5b9daf3a3b25__header-actions","header-lockup":"_8bcd33103b451f30__header-lockup","header-title":"_8113be94e7caf73c__header-title","header-visual":"_9a776c7f70996f61__header-visual","sidebar-toggle-slot":"d5e0920cd15d35bc__sidebar-toggle-slot","header-subtitle":"_60fea2f6bf5319cd__header-subtitle","has-navigation":"_4b0f17e503d11619__has-navigation","header-navigation":"_673c99dcbfb58211__header-navigation",content:"be5e57d029ec4036__content","has-padding":"_128806d0b26e3a50__has-padding"};function nh({headingLevel:e,breadcrumbs:t,badges:r,visual:o,title:n,subTitle:i,children:s,className:a,actions:u,navigation:l,components:c,ariaLabel:m,hasPadding:d=!1,showSidebarToggle:h=!0}){let g=We(pc.page,a);return(0,fi.jsxs)(qm,{className:g,ariaLabel:m??(typeof n=="string"?n:""),children:[(n||t||r||u||o||!!l?.items?.length)&&(0,fi.jsx)(rh,{headingLevel:e,breadcrumbs:t,badges:r,visual:o,title:n,subTitle:i,actions:u,navigation:l,components:c,showSidebarToggle:h}),d?(0,fi.jsx)("div",{className:We(pc.content,pc["has-padding"]),children:s}):s]})}nh.SidebarToggleFill=$m;var gc=nh;var zn=f(ge()),Vv=f(ue()),Dv=f(sh()),Ea=f(sr()),Bv=f(Kt()),jv=f(Te());var Lv=f(ue(),1),Nv=f(_n(),1),RE=f(Kt(),1),EE=f(Dt(),1),Au=f(Te(),1),TE=f(yo(),1);function Rn(e,t,r){t=Array.isArray(t)?[...t]:[t],e=Array.isArray(e)?[...e]:{...e};let o=t.pop(),n=e;for(let i of t){let s=n[i];n=n[i]=Array.isArray(s)?[...s]:{...s}}return n[o]=r,e}var ht=(e,t,r)=>{let o=Array.isArray(t)?t:t.split("."),n=e;return o.forEach(i=>{n=n?.[i]}),n??r};var F1=["appearanceTools","useRootPaddingAwareAlignments","background.backgroundImage","background.backgroundRepeat","background.backgroundSize","background.backgroundPosition","background.gradient","border.color","border.radius","border.radiusSizes","border.style","border.width","shadow.presets","shadow.defaultPresets","color.background","color.button","color.caption","color.custom","color.customDuotone","color.customGradient","color.defaultDuotone","color.defaultGradients","color.defaultPalette","color.duotone","color.gradients","color.heading","color.link","color.palette","color.text","custom","dimensions.aspectRatio","dimensions.height","dimensions.minHeight","dimensions.minWidth","dimensions.width","dimensions.dimensionSizes","layout.contentSize","layout.definitions","layout.wideSize","lightbox.enabled","lightbox.allowEditing","position.fixed","position.sticky","spacing.customSpacingSize","spacing.defaultSpacingSizes","spacing.spacingSizes","spacing.spacingScale","spacing.blockGap","spacing.margin","spacing.padding","spacing.units","typography.fluid","typography.customFontSize","typography.defaultFontSizes","typography.dropCap","typography.fontFamilies","typography.fontSizes","typography.fontStyle","typography.fontWeight","typography.letterSpacing","typography.lineHeight","typography.textAlign","typography.textColumns","typography.textDecoration","typography.textIndent","typography.textTransform","typography.writingMode","viewport.mobile","viewport.tablet"];function yc(e,t,r){let o=r?".blocks."+r:"",n=t?"."+t:"",i=`settings${o}${n}`,s=`settings${n}`;if(t)return ht(e,i)??ht(e,s);let a={};return F1.forEach(u=>{let l=ht(e,`settings${o}.${u}`)??ht(e,`settings.${u}`);l!==void 0&&(a=Rn(a,u.split("."),l))}),a}function vc(e,t,r,o){let n=o?".blocks."+o:"",i=t?"."+t:"",s=`settings${n}${i}`;return Rn(e,s.split("."),r)}var hh=f(dh(),1);var A1="1600px",I1="320px",L1=1,N1=.25,M1=.75,V1="14px";function ph({minimumFontSize:e,maximumFontSize:t,fontSize:r,minimumViewportWidth:o=I1,maximumViewportWidth:n=A1,scaleFactor:i=L1,minimumFontSizeLimit:s}){if(s=jr(s)?s:V1,r){let v=jr(r);if(!v?.unit||!v?.value)return null;let _=jr(s,{coerceTo:v.unit});if(_?.value&&!e&&!t&&v?.value<=_?.value)return null;if(t||(t=`${v.value}${v.unit}`),!e){let k=v.unit==="px"?v.value:v.value*16,E=Math.min(Math.max(1-.075*Math.log2(k),N1),M1),T=di(v.value*E,3);_?.value&&T<_?.value?e=`${_.value}${_.unit}`:e=`${T}${v.unit}`}}let a=jr(e),u=a?.unit||"rem",l=jr(t,{coerceTo:u});if(!a||!l)return null;let c=jr(e,{coerceTo:"rem"}),m=jr(n,{coerceTo:u}),d=jr(o,{coerceTo:u});if(!m||!d||!c)return null;let h=m.value-d.value;if(!h)return null;let g=di(d.value/100,3),b=di(g,3)+u,w=100*((l.value-a.value)/h),C=di((w||1)*i,3),x=`${c.value}${c.unit} + ((1vw - ${b}) * ${C})`;return`clamp(${e}, ${x}, ${t})`}function jr(e,t={}){if(typeof e!="string"&&typeof e!="number")return null;isFinite(e)&&(e=`${e}px`);let{coerceTo:r,rootSizeValue:o,acceptableUnits:n}={coerceTo:"",rootSizeValue:16,acceptableUnits:["rem","px","em"],...t},i=n?.join("|"),s=new RegExp(`^(\\d*\\.?\\d+)(${i}){1,1}$`),a=e.toString().match(s);if(!a||a.length<3)return null;let[,u,l]=a,c=parseFloat(u);return r==="px"&&(l==="em"||l==="rem")&&(c=c*o,l=r),l==="px"&&(r==="em"||r==="rem")&&(c=c/o,l=r),(r==="em"||r==="rem")&&(l==="em"||l==="rem")&&(l=r),l?{value:di(c,3),unit:l}:null}function di(e,t=3){let r=Math.pow(10,t);return Math.round(e*r)/r}function bc(e){let t=e?.fluid;return t===!0||t&&typeof t=="object"&&Object.keys(t).length>0}function D1(e){let t=e?.typography??{},r=e?.layout,o=jr(r?.wideSize)?r?.wideSize:null;return bc(t)&&o?{fluid:{maxViewportWidth:o,...typeof t.fluid=="object"?t.fluid:{}}}:{fluid:t?.fluid}}function mh(e,t){let{size:r}=e;if(!r||r==="0"||e?.fluid===!1||!bc(t?.typography)&&!bc(e))return r;let o=D1(t)?.fluid??{},n=ph({minimumFontSize:typeof e?.fluid=="boolean"?void 0:e?.fluid?.min,maximumFontSize:typeof e?.fluid=="boolean"?void 0:e?.fluid?.max,fontSize:r,minimumFontSizeLimit:typeof o=="object"?o?.minFontSize:void 0,maximumViewportWidth:typeof o=="object"?o?.maxViewportWidth:void 0,minimumViewportWidth:typeof o=="object"?o?.minViewportWidth:void 0});return n||r}var B1=[{path:["color","palette"],valueKey:"color",cssVarInfix:"color",classes:[{classSuffix:"color",propertyName:"color"},{classSuffix:"background-color",propertyName:"background-color"},{classSuffix:"border-color",propertyName:"border-color"}]},{path:["color","gradients"],valueKey:"gradient",cssVarInfix:"gradient",classes:[{classSuffix:"gradient-background",propertyName:"background"}]},{path:["color","duotone"],valueKey:"colors",cssVarInfix:"duotone",valueFunc:({slug:e})=>`url( '#wp-duotone-${e}' )`,classes:[]},{path:["shadow","presets"],valueKey:"shadow",cssVarInfix:"shadow",classes:[]},{path:["typography","fontSizes"],valueFunc:(e,t)=>mh(e,t),valueKey:"size",cssVarInfix:"font-size",classes:[{classSuffix:"font-size",propertyName:"font-size"}]},{path:["typography","fontFamilies"],valueKey:"fontFamily",cssVarInfix:"font-family",classes:[{classSuffix:"font-family",propertyName:"font-family"}]},{path:["spacing","spacingSizes"],valueKey:"size",cssVarInfix:"spacing",valueFunc:({size:e})=>e,classes:[]},{path:["border","radiusSizes"],valueKey:"size",cssVarInfix:"border-radius",classes:[]},{path:["dimensions","dimensionSizes"],valueKey:"size",cssVarInfix:"dimension",classes:[]}];function j1(e,t){if(!e||!t)return e;if(typeof e=="object"&&"ref"in e&&e?.ref){let r=(0,hh.getCSSValueFromRawStyle)(ht(t,e.ref));return typeof r=="object"&&r!==null&&"ref"in r&&r?.ref?void 0:r===void 0?e:r}return e}function z1(e,t){if(!e||!t||!Array.isArray(t))return e;let r=t.find(o=>o?.name===e);return r?.href?r?.href:e}function gh(e,t){if(!e||!t)return e;let r=j1(e,t);return typeof r=="object"&&r!==null&&"url"in r&&r?.url&&(r.url=z1(r.url,t?._links?.["wp:theme-file"])),r}function yh(e,t,r=[],o="slug",n){let i=[t?ht(e,["blocks",t,...r]):void 0,ht(e,r)].filter(Boolean);for(let s of i)if(s){let a=["custom","theme","default"];for(let u of a){let l=s[u];if(l){let c=l.find(m=>m[o]===n);if(c)return o==="slug"||yh(e,t,r,"slug",c.slug)[o]===c[o]?c:void 0}}}}function H1(e,t,r,[o,n]=[]){let i=B1.find(a=>a.cssVarInfix===o);if(!i||!e.settings)return r;let s=yh(e.settings,t,i.path,"slug",n);if(s){let{valueKey:a}=i,u=s[a];return Ms(e,t,u)}return r}function U1(e,t,r,o=[]){let n=(t?ht(e?.settings??{},["blocks",t,"custom",...o]):void 0)??ht(e?.settings??{},["custom",...o]);return n?Ms(e,t,n):r}function Ms(e,t,r){if(!r||typeof r!="string")if(typeof r=="object"&&r!==null&&"ref"in r&&typeof r.ref=="string"){let l=ht(e,r.ref);if(!l||typeof l=="object"&&"ref"in l)return l;r=l}else return r;let o="var:",n="var(--wp--",i=")",s;if(r.startsWith(o))s=r.slice(o.length).split("|");else if(r.startsWith(n)&&r.endsWith(i))s=r.slice(n.length,-i.length).split("--");else return r;let[a,...u]=s;return a==="preset"?H1(e,t,r,u):a==="custom"?U1(e,t,r,u):r}function Vs(e,t,r,o=!0){let n=t?"."+t:"",i=r?`styles.blocks.${r}${n}`:`styles${n}`;if(!e)return;let s=ht(e,i),a=void 0;if(s===void 0&&a){let l=!0,c=e;for(let m of i.split(".")){if(!c||typeof c!="object"||!Object.hasOwn(c,m)){l=!1;break}c=c[m]}l||(s=ht(e,a))}return o?Ms(e,r,s):s}function wc(e,t,r,o){let n=t?"."+t:"",i=o?`styles.blocks.${o}${n}`:`styles${n}`;return Rn(e,i.split("."),r)}var xc=f(bh(),1);function pi(e,t){return typeof e!="object"||typeof t!="object"?e===t:(0,xc.default)(e?.styles,t?.styles)&&(0,xc.default)(e?.settings,t?.settings)}var Eh=f(Ch(),1);function _h(e){return Object.prototype.toString.call(e)==="[object Object]"}function Rh(e){var t,r;return _h(e)===!1?!1:(t=e.constructor,t===void 0?!0:(r=t.prototype,!(_h(r)===!1||r.hasOwnProperty("isPrototypeOf")===!1)))}function Go(e,t){return(0,Eh.default)(e,t,{isMergeableObject:Rh,customMerge:r=>{if(r==="backgroundImage")return(o,n)=>n??o}})}var ox={grad:.9,turn:360,rad:360/(2*Math.PI)},Jr=function(e){return typeof e=="string"?e.length>0:typeof e=="number"},bt=function(e,t,r){return t===void 0&&(t=0),r===void 0&&(r=Math.pow(10,t)),Math.round(r*e)/r+0},dr=function(e,t,r){return t===void 0&&(t=0),r===void 0&&(r=1),e>r?r:e>t?e:t},Lh=function(e){return(e=isFinite(e)?e%360:0)>0?e:e+360},Th=function(e){return{r:dr(e.r,0,255),g:dr(e.g,0,255),b:dr(e.b,0,255),a:dr(e.a)}},Sc=function(e){return{r:bt(e.r),g:bt(e.g),b:bt(e.b),a:bt(e.a,3)}},nx=/^#([0-9a-f]{3,8})$/i,Ds=function(e){var t=e.toString(16);return t.length<2?"0"+t:t},Nh=function(e){var t=e.r,r=e.g,o=e.b,n=e.a,i=Math.max(t,r,o),s=i-Math.min(t,r,o),a=s?i===t?(r-o)/s:i===r?2+(o-t)/s:4+(t-r)/s:0;return{h:60*(a<0?a+6:a),s:i?s/i*100:0,v:i/255*100,a:n}},Mh=function(e){var t=e.h,r=e.s,o=e.v,n=e.a;t=t/360*6,r/=100,o/=100;var i=Math.floor(t),s=o*(1-r),a=o*(1-(t-i)*r),u=o*(1-(1-t+i)*r),l=i%6;return{r:255*[o,a,s,s,u,o][l],g:255*[u,o,o,a,s,s][l],b:255*[s,s,u,o,o,a][l],a:n}},Ph=function(e){return{h:Lh(e.h),s:dr(e.s,0,100),l:dr(e.l,0,100),a:dr(e.a)}},Oh=function(e){return{h:bt(e.h),s:bt(e.s),l:bt(e.l),a:bt(e.a,3)}},kh=function(e){return Mh((r=(t=e).s,{h:t.h,s:(r*=((o=t.l)<50?o:100-o)/100)>0?2*r/(o+r)*100:0,v:o+r,a:t.a}));var t,r,o},hi=function(e){return{h:(t=Nh(e)).h,s:(n=(200-(r=t.s))*(o=t.v)/100)>0&&n<200?r*o/100/(n<=100?n:200-n)*100:0,l:n/2,a:t.a};var t,r,o,n},ix=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s*,\s*([+-]?\d*\.?\d+)%\s*,\s*([+-]?\d*\.?\d+)%\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,sx=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s+([+-]?\d*\.?\d+)%\s+([+-]?\d*\.?\d+)%\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,ax=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,lx=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,Rc={string:[[function(e){var t=nx.exec(e);return t?(e=t[1]).length<=4?{r:parseInt(e[0]+e[0],16),g:parseInt(e[1]+e[1],16),b:parseInt(e[2]+e[2],16),a:e.length===4?bt(parseInt(e[3]+e[3],16)/255,2):1}:e.length===6||e.length===8?{r:parseInt(e.substr(0,2),16),g:parseInt(e.substr(2,2),16),b:parseInt(e.substr(4,2),16),a:e.length===8?bt(parseInt(e.substr(6,2),16)/255,2):1}:null:null},"hex"],[function(e){var t=ax.exec(e)||lx.exec(e);return t?t[2]!==t[4]||t[4]!==t[6]?null:Th({r:Number(t[1])/(t[2]?100/255:1),g:Number(t[3])/(t[4]?100/255:1),b:Number(t[5])/(t[6]?100/255:1),a:t[7]===void 0?1:Number(t[7])/(t[8]?100:1)}):null},"rgb"],[function(e){var t=ix.exec(e)||sx.exec(e);if(!t)return null;var r,o,n=Ph({h:(r=t[1],o=t[2],o===void 0&&(o="deg"),Number(r)*(ox[o]||1)),s:Number(t[3]),l:Number(t[4]),a:t[5]===void 0?1:Number(t[5])/(t[6]?100:1)});return kh(n)},"hsl"]],object:[[function(e){var t=e.r,r=e.g,o=e.b,n=e.a,i=n===void 0?1:n;return Jr(t)&&Jr(r)&&Jr(o)?Th({r:Number(t),g:Number(r),b:Number(o),a:Number(i)}):null},"rgb"],[function(e){var t=e.h,r=e.s,o=e.l,n=e.a,i=n===void 0?1:n;if(!Jr(t)||!Jr(r)||!Jr(o))return null;var s=Ph({h:Number(t),s:Number(r),l:Number(o),a:Number(i)});return kh(s)},"hsl"],[function(e){var t=e.h,r=e.s,o=e.v,n=e.a,i=n===void 0?1:n;if(!Jr(t)||!Jr(r)||!Jr(o))return null;var s=(function(a){return{h:Lh(a.h),s:dr(a.s,0,100),v:dr(a.v,0,100),a:dr(a.a)}})({h:Number(t),s:Number(r),v:Number(o),a:Number(i)});return Mh(s)},"hsv"]]},Fh=function(e,t){for(var r=0;r=.5},e.prototype.toHex=function(){return t=Sc(this.rgba),r=t.r,o=t.g,n=t.b,s=(i=t.a)<1?Ds(bt(255*i)):"","#"+Ds(r)+Ds(o)+Ds(n)+s;var t,r,o,n,i,s},e.prototype.toRgb=function(){return Sc(this.rgba)},e.prototype.toRgbString=function(){return t=Sc(this.rgba),r=t.r,o=t.g,n=t.b,(i=t.a)<1?"rgba("+r+", "+o+", "+n+", "+i+")":"rgb("+r+", "+o+", "+n+")";var t,r,o,n,i},e.prototype.toHsl=function(){return Oh(hi(this.rgba))},e.prototype.toHslString=function(){return t=Oh(hi(this.rgba)),r=t.h,o=t.s,n=t.l,(i=t.a)<1?"hsla("+r+", "+o+"%, "+n+"%, "+i+")":"hsl("+r+", "+o+"%, "+n+"%)";var t,r,o,n,i},e.prototype.toHsv=function(){return t=Nh(this.rgba),{h:bt(t.h),s:bt(t.s),v:bt(t.v),a:bt(t.a,3)};var t},e.prototype.invert=function(){return fr({r:255-(t=this.rgba).r,g:255-t.g,b:255-t.b,a:t.a});var t},e.prototype.saturate=function(t){return t===void 0&&(t=.1),fr(Cc(this.rgba,t))},e.prototype.desaturate=function(t){return t===void 0&&(t=.1),fr(Cc(this.rgba,-t))},e.prototype.grayscale=function(){return fr(Cc(this.rgba,-1))},e.prototype.lighten=function(t){return t===void 0&&(t=.1),fr(Ah(this.rgba,t))},e.prototype.darken=function(t){return t===void 0&&(t=.1),fr(Ah(this.rgba,-t))},e.prototype.rotate=function(t){return t===void 0&&(t=15),this.hue(this.hue()+t)},e.prototype.alpha=function(t){return typeof t=="number"?fr({r:(r=this.rgba).r,g:r.g,b:r.b,a:t}):bt(this.rgba.a,3);var r},e.prototype.hue=function(t){var r=hi(this.rgba);return typeof t=="number"?fr({h:t,s:r.s,l:r.l,a:r.a}):bt(r.h)},e.prototype.isEqual=function(t){return this.toHex()===fr(t).toHex()},e})(),fr=function(e){return e instanceof Ec?e:new Ec(e)},Ih=[],Vh=function(e){e.forEach(function(t){Ih.indexOf(t)<0&&(t(Ec,Rc),Ih.push(t))})};function ux(e=[]){let t={r:[],g:[],b:[],a:[]};return e.forEach(r=>{let o=fr(r).toRgb();t.r.push(o.r/255),t.g.push(o.g/255),t.b.push(o.b/255),t.a.push(o.a)}),t}function Dh(e){return`${e}{filter:none}`}function Bh(e,t){return`${e}{filter:url(#${t})}`}function jh(e,t){let r=ux(t);return` -`}var yh={mobile:"480px",tablet:"782px"},vh=/^(\d+|\d*\.\d+)(px|em|rem)$/,_1=16;function P1(e){return"mobile"in e||"tablet"in e}function O1(e){return!e||typeof e!="object"?{}:P1(e)?e:e.settings?.viewport??{}}function k1(e){return typeof e=="string"&&vh.test(e.trim())}function yc(e){if(typeof e=="number")return e;if(typeof e!="string")return;let t=e.trim().match(vh);if(!t)return;let r=Number.parseFloat(t[1]);return t[2]==="px"?r:r*_1}function vc(e){let t=O1(e),r={},o={};Object.keys(yh).forEach(a=>{let u=a,l=t[u],c=yc(l);c!==void 0&&k1(l)&&(r[u]=l.trim(),o[u]=c)});let n=Object.keys(r);if(!n.length)return{...yh};if(n.length===1)return r;let s=r.mobile,i=r.tablet;return o.mobile>=o.tablet?{mobile:s}:{mobile:s,tablet:i}}function bh(e){let t=vc(e),r={};return t.mobile&&(r["@mobile"]=`@media (width <= ${t.mobile})`),t.tablet&&(r["@tablet"]=t.mobile?`@media (${t.mobile} < width <= ${t.tablet})`:`@media (width <= ${t.tablet})`),r}function Ai(e,t,r,{resolveRefs:o=!0}={}){if(!e?.styles?.blocks?.[t]?.variations?.[r])return;let n=i=>{Object.keys(i).forEach(a=>{let u=i[a];if(typeof u=="object"&&u!==null)if(u.ref!==void 0)if(typeof u.ref!="string"||u.ref.trim()==="")delete i[a];else{let l=vt(e,u.ref);l!=null?i[a]=l:delete i[a]}else n(u),Object.keys(u).length===0&&delete i[a]})},s=JSON.parse(JSON.stringify(e.styles.blocks[t].variations[r]));return o&&n(s),s}var xc="default";function Ch(e){let t=e?.viewport,r=e?.pseudoState;return(!t||t===xc)&&(!r||r===xc)}function F1(e){return Ch(e)?[]:[e.viewport,e.pseudoState].filter(t=>!!t&&t!==xc)}function A1(e,t){let r=F1(t);return r.length?vt(e,r):e}var I1=new Set(["blocks","variations","css"]),bc=Object.freeze({value:{},sources:{}}),L1={root:{layer:"root"},element:{layer:"element"},block:{layer:"block"},blockVariation:{layer:"blockVariation"}};function mo(e){let t=L1[e];return t?{...t}:null}function ho(e,t){return!e||!t?null:{styles:e,source:t}}function N1(e){return e.join(".")}function D1(e){return{...e}}function Rh(e){return e===""||e===null||typeof e=="object"&&!Array.isArray(e)&&Object.keys(e).length===0}function wc(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)&&typeof e.ref=="string"}function go(e){if(!e||typeof e!="object"||Array.isArray(e))return null;let t={};for(let r of Object.keys(e))if(!I1.has(r)){if(r==="elements"){e.elements&&typeof e.elements=="object"&&(t.elements=e.elements);continue}Rh(e[r])||(t[r]=e[r])}return Object.keys(t).length===0?null:t}var wh=new Set(["backgroundImage"]);function Eh(e,t,r,o,n,s=[]){if(!t||typeof t!="object"||Array.isArray(t))return e;for(let i of Object.keys(t)){let a=t[i];if(Rh(a))continue;if(wc(a)){if(a.ref.trim()==="")continue;let l=vt(r,a.ref);if(l==null||wc(l))continue;a=l}let u=[...s,i];if(!wh.has(i)&&a!==null&&typeof a=="object"&&!Array.isArray(a)&&!wc(a)){let l=e[i]&&typeof e[i]=="object"&&!Array.isArray(e[i])?e[i]:{};e[i]=Eh({...l},a,r,o,n,u)}else e[i]=wh.has(i)&&a!==null&&typeof a=="object"&&!Array.isArray(a)?{...a}:a,o&&n&&(n[N1(u)]=D1(o))}return e}function Ii(e,t){if(!e)return null;let r=A1(e,t);return r&&typeof r=="object"&&!Array.isArray(r)?r:null}var M1=["color.background","color.gradient","background","spacing","dimensions","border","shadow","filter"];function V1(e){return e.startsWith("elements.")?!1:M1.some(t=>e===t||e.startsWith(`${t}.`))}function Th(e,t){if(!e||typeof e!="object")return;let[r,...o]=t;if(o.length===0){delete e[r];return}let n=e[r];n&&typeof n=="object"&&(Th(n,o),Object.keys(n).length===0&&delete e[r])}function B1(e,t){for(let r of Object.keys(t))t[r].layer==="root"&&V1(r)&&(Th(e,r.split(".")),delete t[r])}function j1(e,t,r){let o=e?.background?.backgroundImage;if(!o)return;let n=Ym(o,{...t,_links:r??void 0});n!==void 0&&(e.background.backgroundImage=n)}function xh(e,{blockName:t,variationName:r=null,elements:o=null,viewport:n=null,pseudoState:s=null}={}){if(!e||!e.styles||!t)return bc;let i=e.styles,a={viewport:n,pseudoState:s},u=i,l=i.blocks?.[t]??null,c=(o??[]).map(x=>i.elements?.[x]??null).filter(x=>!!x),f=r?Ai(e,t,r)??null:null,m=[ho(go(u),mo("root")),...c.map(x=>ho(go(x),mo("element"))),l?ho(go(l),mo("block")):null,f?ho(go(f),mo("blockVariation")):null];Ch(a)||m.push(ho(go(Ii(u,a)),mo("root")),...c.map(x=>ho(go(Ii(x,a)),mo("element"))),l?ho(go(Ii(l,a)),mo("block")):null,f?ho(go(Ii(f,a)),mo("blockVariation")):null);let g=m.filter(Boolean);if(g.length===0)return bc;let d={},v=g.reduce((x,C)=>Eh(x,C.styles,e,C.source,d),{});return B1(v,d),j1(v,e,e._links??null),{value:v,sources:d}}var z1={},Sh=new WeakMap;function _h(e,t={}){let r=e?.styles;if(!r||typeof r!="object")return xh(e,t);let o=Sh.get(r);o||(o=new WeakMap,Sh.set(r,o));let n=e?._links??z1,s=o.get(n);s||(s=new Map,o.set(n,s));let i=`${t.elements?.join(",")??""}:${t.viewport??""}:${t.pseudoState??""}`,a=(t.blockName||"")+""+(t.variationName||"")+""+i;if(s.has(a))return s.get(a);let u=xh(e,t);return s.set(a,u),u}var Ph=h(as(),1),{lock:Oh,unlock:S5}=(0,Ph.__dangerousOptInToUnstableAPIsOnlyForCoreModules)("I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.","@wordpress/global-styles-engine");var En={};Oh(En,{getResponsiveMediaQueries:bh,getViewportBreakpoints:vc,getViewportBreakpointValueInPixels:yc,getDuotoneFilter:gh,getDuotoneStylesheet:hh,getDuotoneUnsetStylesheet:mh,resolveStyle:_h,getVariationStyle:Ai});var Sc=h(ke(),1);var kh=h(ke(),1),Tt=(0,kh.createContext)({user:{styles:{},settings:{}},base:{styles:{},settings:{}},merged:{styles:{},settings:{}},onChange:()=>{},fontLibraryEnabled:!1});var Fh=h(Y(),1);function ms({children:e,value:t,baseValue:r,onChange:o,fontLibraryEnabled:n}){let s=(0,Sc.useMemo)(()=>Bo(r,t),[r,t]),i=(0,Sc.useMemo)(()=>({user:t,base:r,merged:s,onChange:o,fontLibraryEnabled:n}),[t,r,s,o,n]);return(0,Fh.jsx)(Tt.Provider,{value:i,children:e})}var Jr=h(ce(),1),Zh=h(xe(),1);var tx=h(Xt(),1),rx=h(nr(),1);var Ah=h(Y(),1);function Cc({className:e,...t}){return(0,Ah.jsx)(is,{className:st(e,"global-styles-ui-icon-with-current-color"),...t})}var yo=h(ce(),1);var jo=h(Y(),1);function U1({icon:e,children:t,...r}){return(0,jo.jsxs)(yo.__experimentalItem,{...r,children:[e&&(0,jo.jsxs)(yo.__experimentalHStack,{justify:"flex-start",children:[(0,jo.jsx)(Cc,{icon:e,size:24}),(0,jo.jsx)(yo.FlexItem,{children:t})]}),!e&&t]})}function Xr(e){return(0,jo.jsx)(yo.Navigator.Button,{as:U1,...e})}var G1=h(ce(),1);var Y1=h(xe(),1),Bh=h(Dt(),1);var Rc=function(e){var t=e/255;return t<.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)},Ec=function(e){return .2126*Rc(e.r)+.7152*Rc(e.g)+.0722*Rc(e.b)};function Ih(e){e.prototype.luminance=function(){return t=Ec(this.rgba),(r=2)===void 0&&(r=0),o===void 0&&(o=Math.pow(10,r)),Math.round(o*t)/o+0;var t,r,o},e.prototype.contrast=function(t){t===void 0&&(t="#FFF");var r,o,n,s,i,a,u,l=t instanceof e?t:new e(t);return s=this.rgba,i=l.toRgb(),a=Ec(s),u=Ec(i),r=a>u?(a+.05)/(u+.05):(u+.05)/(a+.05),(o=2)===void 0&&(o=0),n===void 0&&(n=Math.pow(10,o)),Math.floor(n*r)/n+0},e.prototype.isReadable=function(t,r){return t===void 0&&(t="#FFF"),r===void 0&&(r={}),this.contrast(t)>=(a=(i=(o=r).size)===void 0?"normal":i,(s=(n=o.level)===void 0?"AA":n)==="AAA"&&a==="normal"?7:s==="AA"&&a==="large"?3:4.5);var o,n,s,i,a}}var Cr=h(ke(),1),Mh=h(Xt(),1),Vh=h(nr(),1),_c=h(xe(),1);var mt=h(xe(),1);var Lh=h(as(),1),{lock:Z5,unlock:Be}=(0,Lh.__dangerousOptInToUnstableAPIsOnlyForCoreModules)("I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.","@wordpress/global-styles-ui");var{getViewportBreakpoints:Q5}=Be(En),$5={link:[{value:":link",label:(0,mt.__)("Link")},{value:":any-link",label:(0,mt.__)("Any Link")},{value:":visited",label:(0,mt.__)("Visited")},{value:":hover",label:(0,mt.__)("Hover")},{value:":focus",label:(0,mt.__)("Focus")},{value:":focus-visible",label:(0,mt.__)("Focus-visible")},{value:":active",label:(0,mt.__)("Active")}],button:[{value:":link",label:(0,mt.__)("Link")},{value:":any-link",label:(0,mt.__)("Any Link")},{value:":visited",label:(0,mt.__)("Visited")},{value:":hover",label:(0,mt.__)("Hover")},{value:":focus",label:(0,mt.__)("Focus")},{value:":focus-visible",label:(0,mt.__)("Focus-visible")},{value:":active",label:(0,mt.__)("Active")}]},eI={"core/button":[{value:":hover",label:(0,mt.__)("Hover")},{value:":focus",label:(0,mt.__)("Focus")},{value:":focus-visible",label:(0,mt.__)("Focus-visible")},{value:":active",label:(0,mt.__)("Active")}]},tI=[{value:"@tablet",label:(0,mt.__)("Tablet")},{value:"@mobile",label:(0,mt.__)("Mobile")}];function Tc(e,t){if(!t?.length||typeof e!="object"||!e||!Object.keys(e).length)return e;for(let r in e)t.includes(r)?delete e[r]:typeof e[r]=="object"&&Tc(e[r],t);return e}var Li=(e,t)=>{if(!e||!t?.length)return{};let r={};return Object.keys(e).forEach(o=>{if(t.includes(o))r[o]=e[o];else if(typeof e[o]=="object"){let n=Li(e[o],t);Object.keys(n).length&&(r[o]=n)}}),r};function hs(e,t){let r=Li(structuredClone(e),t);return fs(r,e)}function Nh(e,t){if(!Array.isArray(e)||!t)return null;let o=t.replace("var(","").replace(")","")?.split("--").slice(-1)[0];return e.find(n=>n.slug===o)}function Dh(e){let t=e?.settings?.typography?.fontFamilies?.theme,r=e?.settings?.typography?.fontFamilies?.custom,o=[];t&&r?o=[...t,...r]:t?o=t:r&&(o=r);let n=e?.styles?.typography?.fontFamily,s=Nh(o,n),i=e?.styles?.elements?.heading?.typography?.fontFamily,a;return i?a=Nh(o,e?.styles?.elements?.heading?.typography?.fontFamily):a=s,[s,a]}ph([Ih]);function Xe(e,t,r="merged",o=!0,n){let{user:s,base:i,merged:a,onChange:u}=(0,Cr.useContext)(Tt),l=n?.split(".").filter(Boolean)??[],c=l.find(x=>x.startsWith(":")),f=l.filter(x=>!x.startsWith(":")).join("."),m=[e,f].filter(Boolean).join("."),g=a;r==="base"?g=i:r==="user"&&(g=s);let d=(0,Cr.useMemo)(()=>{let x=ki(g,m,t,o);return c?x?.[c]??{}:x},[g,m,t,o,c]),v=(0,Cr.useCallback)(x=>{let C=x;c&&(C={...ki(s,m,t,!1),[c]:x});let w=uc(s,m,C,t);u(w)},[s,u,m,t,c]);return[d,v]}function Je(e,t,r="merged"){let{user:o,base:n,merged:s,onChange:i}=(0,Cr.useContext)(Tt),a=s;r==="base"?a=n:r==="user"&&(a=o);let u=(0,Cr.useMemo)(()=>ac(a,e,t),[a,e,t]),l=(0,Cr.useCallback)(c=>{let f=lc(o,e,c,t);i(f)},[o,i,e,t]);return[u,l]}var H1=[];function W1({title:e,settings:t,styles:r}){return e===(0,_c.__)("Default")||Object.keys(t||{}).length>0||Object.keys(r||{}).length>0}function Ni(e=[]){let{variationsFromTheme:t}=(0,Mh.useSelect)(o=>({variationsFromTheme:o(Vh.store).__experimentalGetCurrentThemeGlobalStylesVariations?.()||H1}),[]),{user:r}=(0,Cr.useContext)(Tt);return(0,Cr.useMemo)(()=>{let o=structuredClone(r),n=Tc(o,e);n.title=(0,_c.__)("Default");let s=t.filter(a=>hs(a,e)).map(a=>Bo(n,a)),i=[n,...s];return i?.length?i.filter(W1):[]},[e,r,t])}var Pc=h(Y(),1),{useHasDimensionsPanel:dI,useHasTypographyPanel:pI,useHasColorPanel:mI,useSettingsForBlockElement:hI,useHasBackgroundPanel:gI}=Be(Bh.privateApis);var Nr=h(ce(),1);function Tn(){let[e="black"]=Xe("color.text"),[t="white"]=Xe("color.background"),[r=e]=Xe("elements.h1.color.text"),[o=r]=Xe("elements.link.color.text"),[n=o]=Xe("elements.button.color.background"),[s]=Je("color.palette.core")||[],[i]=Je("color.palette.theme")||[],[a]=Je("color.palette.custom")||[],u=(i??[]).concat(a??[]).concat(s??[]),l=u.filter(({color:m})=>m===e),c=u.filter(({color:m})=>m===n),f=l.concat(c).concat(u).filter(({color:m})=>m!==t).slice(0,2);return{paletteColors:u,highlightedColors:f}}var Uh=h(ke(),1),Hh=h(ce(),1),kc=h(xe(),1);function q1(e,t){return t.length===0?null:(t.sort((r,o)=>Math.abs(e-r)-Math.abs(e-o)),t[0])}function Z1(e){let t=[];return e.forEach(r=>{let o=String(r.fontWeight).split(" ");if(o.length===2){let n=parseInt(o[0]),s=parseInt(o[1]);for(let i=n;i<=s;i+=100)t.push(i)}else o.length===1&&t.push(parseInt(o[0]))}),t}function jh(e){let t=/^(?!generic\([ a-zA-Z\-]+\)$)(?!^[a-zA-Z\-]+$).+/,r=e.trim(),o=n=>(n=n.trim(),n.match(t)?(n=n.replace(/^["']|["']$/g,""),`"${n}"`):n);return r.includes(",")?r.split(",").map(o).filter(n=>n!=="").join(", "):o(r)}function Oc(e){if(!e)return"";let t=e.trim();return t.includes(",")&&(t=(t.split(",").find(r=>r.trim()!=="")??"").trim()),t=t.replace(/^["']|["']$/g,""),window.navigator.userAgent.toLowerCase().includes("firefox")&&(t=`"${t}"`),t}function _n(e){let t={fontFamily:jh(e.fontFamily)};if(!("fontFace"in e)||!Array.isArray(e.fontFace))return t.fontWeight="400",t.fontStyle="normal",t;if(e.fontFace){let r=e.fontFace.filter(o=>o?.fontStyle&&o.fontStyle.toLowerCase()==="normal");if(r.length>0){t.fontStyle="normal";let o=Z1(r),n=q1(400,o);t.fontWeight=String(n)||"400"}else t.fontStyle=e.fontFace.length&&e.fontFace[0].fontStyle||"normal",t.fontWeight=e.fontFace.length&&String(e.fontFace[0].fontWeight)||"400"}return t}function zh(e){return{fontFamily:jh(e.fontFamily),fontStyle:e.fontStyle||"normal",fontWeight:e.fontWeight||"400"}}var gs=h(Y(),1);function Di({fontSize:e,variation:t}){let{base:r}=(0,Uh.useContext)(Tt),o=r;t&&(o={...r,...t});let[n]=Xe("color.text"),[s,i]=Dh(o),a=s?_n(s):{},u=i?_n(i):{};return n&&(a.color=n,u.color=n),e&&(a.fontSize=e,u.fontSize=e),(0,gs.jsxs)(Hh.__unstableMotion.div,{animate:{scale:1,opacity:1},initial:{scale:.1,opacity:0},transition:{delay:.3,type:"tween"},style:{textAlign:"center",lineHeight:1},children:[(0,gs.jsx)("span",{style:u,children:(0,kc._x)("A","Uppercase letter A")}),(0,gs.jsx)("span",{style:a,children:(0,kc._x)("a","Lowercase letter A")})]})}var Wh=h(ce(),1);var Gh=h(Y(),1);function Yh({normalizedColorSwatchSize:e,ratio:t}){let{highlightedColors:r}=Tn(),o=e*t;return r.map(({slug:n,color:s},i)=>(0,Gh.jsx)(Wh.__unstableMotion.div,{style:{height:o,width:o,background:s,borderRadius:o/2},animate:{scale:1,opacity:1},initial:{scale:.1,opacity:0},transition:{delay:i===1?.2:.1}},`${n}-${i}`))}var qh=h(ce(),1),Pn=h(No(),1),zo=h(ke(),1);var Kr=h(Y(),1),Fc=248,Ac=152,X1={leading:!0,trailing:!0};function K1({children:e,label:t,isFocused:r,withHoverView:o}){let[n="white"]=Xe("color.background"),[s]=Xe("color.gradient"),i=(0,Pn.useReducedMotion)(),[a,u]=(0,zo.useState)(!1),[l,{width:c}]=(0,Pn.useResizeObserver)(),[f,m]=(0,zo.useState)(c),[g,d]=(0,zo.useState)(),v=(0,Pn.useThrottle)(m,250,X1);(0,zo.useLayoutEffect)(()=>{c&&v(c)},[c,v]),(0,zo.useLayoutEffect)(()=>{let b=f?f/Fc:1,R=b-(g||0);(Math.abs(R)>.1||!g)&&d(b)},[f,g]);let x=c?c/Fc:1,C=g||x,w=!!c;return(0,Kr.jsxs)(Kr.Fragment,{children:[(0,Kr.jsx)("div",{style:{position:"relative"},children:l}),!w&&(0,Kr.jsx)(ec,{className:"global-styles-ui-preview__wrapper",style:{aspectRatio:Fc/Ac}}),w&&(0,Kr.jsx)("div",{className:st("global-styles-ui-preview__wrapper",{"is-hoverable":o}),style:{height:Ac*C},onMouseEnter:()=>u(!0),onMouseLeave:()=>u(!1),tabIndex:-1,children:(0,Kr.jsx)(qh.__unstableMotion.div,{style:{height:Ac*C,width:"100%",background:s??n},initial:"start",animate:(a||r)&&!i&&t?"hover":"start",children:[].concat(e).map((b,R)=>b({ratio:C,key:R}))})})]})}var On=K1;var Kt=h(Y(),1),J1={start:{scale:1,opacity:1},hover:{scale:0,opacity:0}},Q1={hover:{opacity:1},start:{opacity:.5}},$1={hover:{scale:1,opacity:1},start:{scale:0,opacity:0}};function ex({label:e,isFocused:t,withHoverView:r,variation:o}){let[n]=Xe("typography.fontWeight"),[s="serif"]=Xe("typography.fontFamily"),[i=s]=Xe("elements.h1.typography.fontFamily"),[a=n]=Xe("elements.h1.typography.fontWeight"),[u="black"]=Xe("color.text"),[l=u]=Xe("elements.h1.color.text"),{paletteColors:c}=Tn();return(0,Kt.jsxs)(On,{label:e,isFocused:t,withHoverView:r,children:[({ratio:f,key:m})=>(0,Kt.jsx)(Nr.__unstableMotion.div,{variants:J1,style:{height:"100%",overflow:"hidden"},children:(0,Kt.jsxs)(Nr.__experimentalHStack,{spacing:10*f,justify:"center",style:{height:"100%",overflow:"hidden"},children:[(0,Kt.jsx)(Di,{fontSize:65*f,variation:o}),(0,Kt.jsx)(Nr.__experimentalVStack,{spacing:4*f,children:(0,Kt.jsx)(Yh,{normalizedColorSwatchSize:32,ratio:f})})]})},m),({key:f})=>(0,Kt.jsx)(Nr.__unstableMotion.div,{variants:r?Q1:void 0,style:{height:"100%",width:"100%",position:"absolute",top:0,overflow:"hidden",filter:"blur(60px)",opacity:.1},children:(0,Kt.jsx)(Nr.__experimentalHStack,{spacing:0,justify:"flex-start",style:{height:"100%",overflow:"hidden"},children:c.slice(0,4).map(({color:m},g)=>(0,Kt.jsx)("div",{style:{height:"100%",background:m,flexGrow:1}},g))})},f),({ratio:f,key:m})=>(0,Kt.jsx)(Nr.__unstableMotion.div,{variants:$1,style:{height:"100%",width:"100%",overflow:"hidden",position:"absolute",top:0},children:(0,Kt.jsx)(Nr.__experimentalVStack,{spacing:3*f,justify:"center",style:{height:"100%",overflow:"hidden",padding:10*f,boxSizing:"border-box"},children:e&&(0,Kt.jsx)("div",{style:{fontSize:40*f,fontFamily:i,color:l,fontWeight:a,lineHeight:"1em",textAlign:"center"},children:e})})},m)]})}var Ic=ex;var Xh=h(Y(),1);var Nc=h(Sn(),1),kn=h(xe(),1),Ho=h(ce(),1),Dc=h(Xt(),1),vo=h(ke(),1),Mi=h(Dt(),1),tg=h(No(),1);import{speak as ix}from"@wordpress/a11y";var Kh=h(Sn(),1),Jh=h(Xt(),1),ox=h(ce(),1);var nx=h(Y(),1);function sx(e,t){return e?.filter(r=>r.source==="block"||t.includes(r.name))||[]}function Lc(e){let t=(0,Jh.useSelect)(n=>{let{getBlockStyles:s}=n(Kh.store);return s(e)},[e]),[r]=Xe("variations",e),o=Object.keys(r??{});return sx(t,o)}var Uo=h(ce(),1),Qh=h(xe(),1);var $h=h(Dt(),1);var eg=h(Y(),1),{StateControl:ZI,StateControlBadges:XI}=Be($h.privateApis);var Dr=h(Y(),1),{useHasDimensionsPanel:ax,useHasTypographyPanel:lx,useHasBorderPanel:cx,useSettingsForBlockElement:ux,useHasColorPanel:fx,useHasBackgroundPanel:dx}=Be(Mi.privateApis);function px(){let e=(0,Dc.useSelect)(n=>n(Nc.store).getBlockTypes(),[]),t=(n,s)=>{let{core:i,noncore:a}=n;return(s.name.startsWith("core/")?i:a).push(s),n},{core:r,noncore:o}=e.reduce(t,{core:[],noncore:[]});return[...r,...o]}function mx(e){let[t]=Je("",e),r=ux(t,e),o=lx(r),n=fx(r),s=dx(r),i=cx(r),a=ax(r),u=i||a,l=!!Lc(e)?.length;return o||n||s||u||l}function hx({block:e}){return mx(e.name)?(0,Dr.jsx)(Xr,{path:"/blocks/"+encodeURIComponent(e.name),children:(0,Dr.jsxs)(Ho.__experimentalHStack,{justify:"flex-start",children:[(0,Dr.jsx)(Mi.BlockIcon,{icon:e.icon}),(0,Dr.jsx)(Ho.FlexItem,{children:e.title})]})}):null}function gx({filterValue:e}){let t=px(),r=(0,tg.useDebounce)(ix,500),{isMatchingSearchTerm:o}=(0,Dc.useSelect)(Nc.store),n=e?t.filter(i=>o(i,e)):t,s=(0,vo.useRef)(null);return(0,vo.useEffect)(()=>{if(!e)return;let i=s.current?.childElementCount||0,a=(0,kn.sprintf)((0,kn._n)("%d result found.","%d results found.",i),i);r(a,"polite")},[e,r]),(0,Dr.jsx)("div",{ref:s,className:"global-styles-ui-block-types-item-list",role:"list",children:n.length===0?(0,Dr.jsx)(Ho.__experimentalText,{align:"center",as:"p",children:(0,kn.__)("No blocks found.")}):n.map(i=>(0,Dr.jsx)(hx,{block:i},"menu-itemblock-"+i.name))})}var oL=(0,vo.memo)(gx);var xx=h(Sn(),1),sg=h(Dt(),1),Mc=h(ke(),1),Sx=h(Xt(),1),Cx=h(nr(),1),Vc=h(ce(),1),ig=h(xe(),1);var yx=h(Dt(),1),rg=h(Sn(),1),vx=h(ce(),1),bx=h(ke(),1);var wx=h(Y(),1),{getViewportBreakpoints:uL,getViewportBreakpointValueInPixels:fL}=Be(En);var og=h(ce(),1),ng=h(Y(),1);function ur({children:e,level:t=2}){return(0,ng.jsx)(og.__experimentalHeading,{className:"global-styles-ui-subtitle",level:t,children:e})}var Bc=h(Y(),1);var{useHasDimensionsPanel:TL,useHasTypographyPanel:_L,useHasBorderPanel:PL,useSettingsForBlockElement:OL,useHasColorPanel:kL,useHasFiltersPanel:FL,useHasImageSettingsPanel:AL,useHasBackgroundPanel:IL,BackgroundPanel:LL,BorderPanel:NL,ColorPanel:DL,TypographyPanel:ML,DimensionsPanel:VL,FiltersPanel:BL,ImageSettingsPanel:jL,AdvancedPanel:zL}=Be(sg.privateApis);var DE=h(xe(),1),ME=h(ce(),1),VE=h(ke(),1);var Rx=h(ce(),1);var Ex=h(Y(),1);var Tx=h(xe(),1),Vi=h(ce(),1);var ag=h(Y(),1);var zi=h(ce(),1);var lg=h(ce(),1);var Bi=h(Y(),1),_x=({variation:e,isFocused:t,withHoverView:r})=>(0,Bi.jsx)(On,{label:e.title,isFocused:t,withHoverView:r,children:({ratio:o,key:n})=>(0,Bi.jsx)(lg.__experimentalHStack,{spacing:10*o,justify:"center",style:{height:"100%",overflow:"hidden"},children:(0,Bi.jsx)(Di,{variation:e,fontSize:85*o})},n)}),cg=_x;var Wo=h(ke(),1),fg=h(jc(),1),ji=h(xe(),1);var bo=h(Y(),1);function Fn({variation:e,children:t,isPill:r=!1,properties:o,showTooltip:n=!1}){let[s,i]=(0,Wo.useState)(!1),{base:a,user:u,onChange:l}=(0,Wo.useContext)(Tt),c=(0,Wo.useMemo)(()=>{let x=Bo(a,e);return o&&(x=Li(x,o)),{user:e,base:a,merged:x,onChange:()=>{}}},[e,a,o]),f=()=>l(e),m=x=>{x.keyCode===fg.ENTER&&(x.preventDefault(),f())},g=(0,Wo.useMemo)(()=>fs(u,e),[u,e]),d=e?.title;e?.description&&(d=(0,ji.sprintf)((0,ji._x)("%1$s (%2$s)","variation label"),e?.title,e?.description));let v=(0,bo.jsx)("div",{className:st("global-styles-ui-variations_item",{"is-active":g}),role:"button",onClick:f,onKeyDown:m,tabIndex:0,"aria-label":d,"aria-current":g,onFocus:()=>i(!0),onBlur:()=>i(!1),children:(0,bo.jsx)("div",{className:st("global-styles-ui-variations_item-preview",{"is-pill":r}),children:t(s)})});return(0,bo.jsx)(Tt.Provider,{value:c,children:n?(0,bo.jsxs)(xn.Root,{children:[(0,bo.jsx)(xn.Trigger,{render:v}),(0,bo.jsx)(xn.Popup,{children:e?.title})]}):v})}var Go=h(Y(),1),dg=["typography"];function Ui({title:e,gap:t=2}){let r=Ni(dg);return r?.length<=1?null:(0,Go.jsxs)(zi.__experimentalVStack,{spacing:3,children:[e&&(0,Go.jsx)(ur,{level:3,children:e}),(0,Go.jsx)(zi.__experimentalGrid,{columns:3,gap:t,className:"global-styles-ui-style-variations-container",children:r.map((o,n)=>(0,Go.jsx)(Fn,{variation:o,properties:dg,showTooltip:!0,children:()=>(0,Go.jsx)(cg,{variation:o})},n))})]})}var LE=h(xe(),1),Cs=h(ce(),1);var NE=h(ke(),1);var Qr=h(ke(),1),Co=h(Xt(),1),So=h(nr(),1),Wc=h(xe(),1);var zc=h(mg(),1),hg=h(nr(),1),gg="/wp/v2/font-families";function yg(e){let{receiveEntityRecords:t}=e.dispatch(hg.store);t("postType","wp_font_family",[],void 0,!0)}async function vg(e,t){let o=await(0,zc.default)({path:gg,method:"POST",body:e});return yg(t),{id:o.id,...o.font_family_settings,fontFace:[]}}async function bg(e,t,r){let o={path:`${gg}/${e}/font-faces`,method:"POST",body:t},n=await(0,zc.default)(o);return yg(r),{id:n.id,...n.font_face_settings}}var An=function(){return An=Object.assign||function(t){for(var r,o=1,n=arguments.length;o{o.forEach(n=>{n.family===Oc(e?.fontFamily)&&n.weight===e?.fontWeight&&n.style===e?.fontStyle&&o.delete(n)})};if((t==="document"||t==="all")&&r(document.fonts),t==="iframe"||t==="all"){let o=document.querySelector('iframe[name="editor-canvas"]');o?.contentDocument&&r(o.contentDocument.fonts)}}function In(e){if(!e)return;let t;if(Array.isArray(e)?t=e[0]:t=e,!t.startsWith("file:."))return kx(t)||(t=encodeURI(t)),t}function Og(e){let t=new FormData,{fontFace:r,category:o,...n}=e,s={...n,slug:Hi(e.slug)};return t.append("font_family_settings",JSON.stringify(s)),t}function kg(e){return(e?.fontFace??[]).map((r,o)=>{let n={...r},s=new FormData;if(n.file){let i=Array.isArray(n.file)?n.file:[n.file],a=[];i.forEach((u,l)=>{let c=`file-${o}-${l}`;s.append(c,u,u.name),a.push(c)}),n.src=a.length===1?a[0]:a,delete n.file,s.append("font_face_settings",JSON.stringify(n))}else s.append("font_face_settings",JSON.stringify(n));return s})}async function Fg(e,t,r){let o=[];for(let s of t)try{let i=await bg(e,s,r);o.push({status:"fulfilled",value:i})}catch(i){o.push({status:"rejected",reason:i})}let n={errors:[],successes:[]};return o.forEach((s,i)=>{if(s.status==="fulfilled"&&s.value){let a=s.value;n.successes.push(a)}else s.reason&&n.errors.push({data:t[i],message:s.reason.message})}),n}async function Ag(e){e=Array.isArray(e)?e:[e];let t=await Promise.all(e.map(async r=>fetch(new Request(r)).then(o=>{if(!o.ok)throw new Error(`Error downloading font face asset from ${r}. Server responded with status: ${o.status}`);return o.blob()}).then(o=>{let n=r.split("/").pop();return new _g([o],n,{type:o.type})})));return t.length===1?t[0]:t}function Hc(e,t){return t.findIndex(r=>r.fontWeight===e.fontWeight&&r.fontStyle===e.fontStyle)!==-1}function Ig(e,t,r){t=Array.isArray(t)?[...t]:[t],e=Array.isArray(e)?[...e]:{...e};let o=t.pop(),n=e;for(let s of t){let i=n[s];n=n[s]=Array.isArray(i)?[...i]:{...i}}return n[o]=r,e}function Gi(e,t,r=[]){let o=u=>u.slug===e.slug,n=u=>u.find(o),s=u=>u?r.filter(l=>!o(l)):[...r,e],i=u=>{let l=f=>f.fontWeight===t.fontWeight&&f.fontStyle===t.fontStyle;if(!u)return[...r,{...e,fontFace:[t]}];let c=u.fontFace||[];return c.find(l)?c=c.filter(f=>!l(f)):c=[...c,t],c.length===0?r.filter(f=>!o(f)):r.map(f=>o(f)?{...f,fontFace:c}:f)},a=n(r);return t?i(a):s(a)}var Lg=h(Y(),1),Mt=(0,Qr.createContext)({});Mt.displayName="FontLibraryContext";function Ax({children:e}){let t=(0,Co.useRegistry)(),{saveEntityRecord:r,deleteEntityRecord:o}=(0,Co.useDispatch)(So.store),{globalStylesId:n}=(0,Co.useSelect)(E=>{let{__experimentalGetCurrentGlobalStylesId:L}=E(So.store);return{globalStylesId:L()}},[]),s=(0,So.useEntityRecord)("root","globalStyles",n),[i,a]=(0,Qr.useState)(!1),{records:u=[],isResolving:l}=(0,So.useEntityRecords)("postType","wp_font_family",{_embed:!0}),c=(u||[]).map(E=>({id:E.id,...E.font_family_settings||{},fontFace:E?._embedded?.font_faces?.map(L=>L.font_face_settings)||[]}))||[],[f,m]=Je("typography.fontFamilies"),g=async E=>{if(!s.record)return;let L=s.record,$=Ig(L??{},["settings","typography","fontFamilies"],E);await r("root","globalStyles",$)},[d,v]=(0,Qr.useState)(""),[x,C]=(0,Qr.useState)(void 0),w=f?.theme?f.theme.map(E=>wo(E,{source:"theme"})).sort((E,L)=>E.name.localeCompare(L.name)):[],b=f?.custom?f.custom.map(E=>wo(E,{source:"custom"})).sort((E,L)=>E.name.localeCompare(L.name)):[],R=c?c.map(E=>wo(E,{source:"custom"})).sort((E,L)=>E.name.localeCompare(L.name)):[];(0,Qr.useEffect)(()=>{d||C(void 0)},[d]);let A=E=>{if(!E){C(void 0);return}let $=(E.source==="theme"?w:R).find(F=>F.slug===E.slug);C({...$||E,source:E.source})},[T]=(0,Qr.useState)(new Set),_=E=>E.reduce(($,F)=>{let Z=F?.fontFace&&F.fontFace?.length>0?F?.fontFace.map(se=>`${se.fontStyle??""}${se.fontWeight??""}`):["normal400"];return $[F.slug]=Z,$},{}),P=E=>_(E==="theme"?w:b),N=(E,L,$,F)=>!L&&!$?!!P(F)[E]:!!P(F)[E]?.includes((L??"")+($??"")),q=(E,L)=>P(L)[E]||[];async function H(E){a(!0);try{let L=[],$=[];for(let Z of E){let se=!1,we=await(0,Co.resolveSelect)(So.store).getEntityRecords("postType","wp_font_family",{slug:Z.slug,per_page:1,_embed:!0}),ie=we&&we.length>0?we[0]:null,ve=ie?{id:ie.id,...ie.font_family_settings,fontFace:(ie?._embedded?.font_faces??[]).map(Ae=>Ae.font_face_settings)||[]}:null;ve||(se=!0,ve=await vg(Og(Z),t));let Ee=ve.fontFace&&Z.fontFace?ve.fontFace.filter(Ae=>Ae&&Z.fontFace&&Hc(Ae,Z.fontFace)):[];ve.fontFace&&Z.fontFace&&(Z.fontFace=Z.fontFace.filter(Ae=>!Hc(Ae,ve.fontFace)));let ee=[],Fe=[];if(Z?.fontFace?.length??!1){let Ae=await Fg(ve.id,kg(Z),t);ee=Ae?.successes,Fe=Ae?.errors}(ee?.length>0||Ee?.length>0)&&(ve.fontFace=[...ee],L.push(ve)),ve&&!Z?.fontFace?.length&&L.push(ve),se&&(Z?.fontFace?.length??0)>0&&ee?.length===0&&await o("postType","wp_font_family",ve.id,{force:!0}),$=$.concat(Fe)}let F=$.reduce((Z,se)=>Z.includes(se.message)?Z:[...Z,se.message],[]);if(L.length>0){let Z=W(L);await g(Z)}if(F.length>0){let Z=new Error((0,Wc.__)("There was an error installing fonts."));throw Z.installationErrors=F,Z}}finally{a(!1)}}async function S(E){if(!E?.id)throw new Error((0,Wc.__)("Font family to uninstall is not defined."));try{await o("postType","wp_font_family",E.id,{force:!0});let L=I(E);return await g(L),{deleted:!0}}catch(L){throw console.error("There was an error uninstalling the font family:",L),L}}let I=E=>{let $=(f?.[E.source??""]??[]).filter(Z=>Z.slug!==E.slug),F={...f,[E.source??""]:$};return m(F),E.fontFace&&E.fontFace.forEach(Z=>{ys(Z,"all")}),F},W=E=>{let L=O(E),$={...f,custom:Pg(f?.custom,L)};return m($),D(L),$},O=E=>E.map(({id:L,fontFace:$,...F})=>({...F,...$&&$.length>0?{fontFace:$.map(({id:Z,...se})=>se)}:{}})),D=E=>{E.forEach(L=>{L.fontFace&&L.fontFace.forEach($=>{let F=In($?.src??"");F&&xo($,F,"all")})})},J=(E,L)=>{let $=f?.[E.source??""]??[],F=Gi(E,L,$);m({...f,[E.source??""]:F});let Z=N(E.slug,L?.fontStyle??"",L?.fontWeight??"",E.source??"custom");if(L&&Z)ys(L,"all");else{let se=In(L?.src??"");L&&se&&xo(L,se,"all")}},M=async E=>{if(!E.src)return;let L=In(E.src);!L||T.has(L)||(xo(E,L,"document"),T.add(L))};return(0,Lg.jsx)(Mt.Provider,{value:{libraryFontSelected:x,handleSetLibraryFontSelected:A,fontFamilies:f??{},baseCustomFonts:R,isFontActivated:N,getFontFacesActivated:q,loadFontFaceAsset:M,installFonts:H,uninstallFontFamily:S,toggleActivateFont:J,getAvailableFontsOutline:_,modalTabOpen:d,setModalTabOpen:v,saveFontFamilies:g,isResolvingLibrary:l,isInstalling:i},children:e})}var Yi=Ax;var la=h(xe(),1),Xc=h(ce(),1),gy=h(nr(),1),AE=h(Xt(),1);var Ie=h(ce(),1),bs=h(nr(),1),Gc=h(Xt(),1),Br=h(ke(),1),at=h(xe(),1);var Nn=h(xe(),1),Zi=h(ke(),1),dr=h(ce(),1);var Ng=h(ce(),1),Mr=h(ke(),1);var qi=h(Y(),1);function Ix(e){if(e.preview)return e.preview;if(e.src)return Array.isArray(e.src)?e.src[0]:e.src}function Lx(e){return"fontStyle"in e&&e.fontStyle||"fontWeight"in e&&e.fontWeight?e:"fontFace"in e&&e.fontFace&&e.fontFace.length?e.fontFace.find(t=>t.fontStyle==="normal"&&t.fontWeight==="400")||e.fontFace[0]:{fontStyle:"normal",fontWeight:"400",fontFamily:e.fontFamily}}function Nx({font:e,text:t}){let r=(0,Mr.useRef)(null),o=Lx(e),n=_n(e);t=t||("name"in e?e.name:"");let s=e.preview,[i,a]=(0,Mr.useState)(!1),[u,l]=(0,Mr.useState)(!1),{loadFontFaceAsset:c}=(0,Mr.useContext)(Mt),f=s??Ix(o),m=f&&f.match(/\.(png|jpg|jpeg|gif|svg)$/i),g=zh(o),d={fontSize:"18px",lineHeight:1,opacity:u?"1":"0",...n,...g};return(0,Mr.useEffect)(()=>{let v=new window.IntersectionObserver(([x])=>{a(x.isIntersecting)},{});return r.current&&v.observe(r.current),()=>v.disconnect()},[r]),(0,Mr.useEffect)(()=>{(async()=>i&&(!m&&o.src&&await c(o),l(!0)))()},[o,i,c,m]),(0,qi.jsx)("div",{ref:r,children:m?(0,qi.jsx)("img",{src:f,loading:"lazy",alt:t,className:"font-library__font-variant_demo-image"}):(0,qi.jsx)(Ng.__experimentalText,{style:d,className:"font-library__font-variant_demo-text",children:t})})}var Ln=Nx;var Vr=h(Y(),1);function Dx({font:e,onClick:t,variantsText:r,navigatorPath:o,shouldFocus:n}){let s=e.fontFace?.length||1,i={cursor:t?"pointer":"default"},a=(0,dr.useNavigator)(),u=(0,Zi.useRef)(null);return(0,Zi.useEffect)(()=>{n&&u.current?.focus()},[n]),(0,Vr.jsx)(dr.Button,{ref:u,__next40pxDefaultSize:!0,onClick:()=>{t(),o&&a.goTo(o)},style:i,className:"font-library__font-card",children:(0,Vr.jsxs)(dr.Flex,{justify:"space-between",wrap:!1,children:[(0,Vr.jsx)(Ln,{font:e}),(0,Vr.jsxs)(dr.Flex,{justify:"flex-end",children:[(0,Vr.jsx)(dr.FlexItem,{children:(0,Vr.jsx)(dr.__experimentalText,{className:"font-library__font-card__count",children:r||(0,Nn.sprintf)((0,Nn._n)("%d variant","%d variants",s),s)})}),(0,Vr.jsx)(dr.FlexItem,{children:(0,Vr.jsx)(is,{icon:(0,Nn.isRTL)()?Do:Mo})})]})]})})}var vs=Dx;var Xi=h(ke(),1),Ki=h(ce(),1);var Yo=h(Y(),1);function Mx({face:e,font:t}){let{isFontActivated:r,toggleActivateFont:o}=(0,Xi.useContext)(Mt),n=(t?.fontFace?.length??0)>0?r(t.slug,e.fontStyle,e.fontWeight,t.source):r(t.slug,void 0,void 0,t.source),s=()=>{if((t?.fontFace?.length??0)>0){o(t,e);return}o(t)},i=t.name+" "+Wi(e),a=(0,Xi.useId)();return(0,Yo.jsx)("div",{className:"font-library__font-card",children:(0,Yo.jsxs)(Ki.Flex,{justify:"flex-start",align:"center",gap:"1rem",children:[(0,Yo.jsx)(Ki.CheckboxControl,{checked:n,onChange:s,id:a}),(0,Yo.jsx)("label",{htmlFor:a,children:(0,Yo.jsx)(Ln,{font:e,text:i,onClick:s})})]})})}var Dg=Mx;function Mg(e){switch(e){case"normal":return 400;case"bold":return 700;case"bolder":return 500;case"lighter":return 300;default:return parseInt(e,10)}}function Ji(e){return e.sort((t,r)=>t.fontStyle==="normal"&&r.fontStyle!=="normal"?-1:r.fontStyle==="normal"&&t.fontStyle!=="normal"?1:t.fontStyle===r.fontStyle?Mg(t.fontWeight?.toString()??"normal")-Mg(r.fontWeight?.toString()??"normal"):!t.fontStyle||!r.fontStyle?t.fontStyle?-1:1:t.fontStyle.localeCompare(r.fontStyle))}var Re=h(Y(),1);function Vg(e){if(!e)return"";let t={};for(let r of Object.keys(e).sort())t[r]=(e[r]??[]).map(o=>({slug:o.slug,fontFace:(o.fontFace??[]).map(n=>`${n.fontStyle}-${n.fontWeight}`).sort()})).sort((o,n)=>o.slug.localeCompare(n.slug));return JSON.stringify(t)}function Vx(){let{baseCustomFonts:e,libraryFontSelected:t,handleSetLibraryFontSelected:r,uninstallFontFamily:o,isResolvingLibrary:n,isInstalling:s,saveFontFamilies:i,getFontFacesActivated:a}=(0,Br.useContext)(Mt),[u,l]=Je("typography.fontFamilies"),[c,f]=(0,Br.useState)(void 0),[m,g]=(0,Br.useState)(!1),[d,v]=(0,Br.useState)(null),[x]=Je("typography.fontFamilies",void 0,"base"),C=(0,Gc.useSelect)(F=>{let{__experimentalGetCurrentGlobalStylesId:Z}=F(bs.store);return Z()},[]),w=(0,bs.useEntityRecord)("root","globalStyles",C),b=w?.edits?.settings?.typography?.fontFamilies,R=w?.record?.settings?.typography?.fontFamilies,A=(0,Br.useMemo)(()=>b===void 0?!1:Vg(b)!==Vg(R),[b,R]),T=u?.theme?u.theme.map(F=>wo(F,{source:"theme"})).sort((F,Z)=>F.name.localeCompare(Z.name)):[],_=new Set(T.map(F=>F.slug)),P=x?.theme?T.concat(x.theme.filter(F=>!_.has(F.slug)).map(F=>wo(F,{source:"theme"})).sort((F,Z)=>F.name.localeCompare(Z.name))):[],N=t?.source==="custom"&&t?.id,q=(0,Gc.useSelect)(F=>{let{canUser:Z}=F(bs.store);return N&&Z("delete",{kind:"postType",name:"wp_font_family",id:N})},[N]),H=!!t&&t?.source!=="theme"&&q,S=()=>{g(!0)},I=async()=>{v(null);try{await i(u),v({type:"success",message:(0,at.__)("Font family updated successfully.")})}catch(F){v({type:"error",message:(0,at.sprintf)((0,at.__)("There was an error updating the font family. %s"),F.message)})}},W=F=>F?!F.fontFace||!F.fontFace.length?[{fontFamily:F.fontFamily,fontStyle:"normal",fontWeight:"400"}]:Ji(F.fontFace):[],O=F=>{let Z=F?.fontFace&&(F?.fontFace?.length??0)>0?F.fontFace.length:1,se=a(F.slug,F.source).length;return(0,at.sprintf)((0,at.__)("%1$d of %2$d active"),se,Z)};(0,Br.useEffect)(()=>{r(t)},[]);let D=t?a(t.slug,t.source).length:0,J=t?.fontFace?.length??(t?.fontFamily?1:0),M=D>0&&D!==J,E=D===J,L=()=>{if(!t||!t?.source)return;let F=u?.[t.source]?.filter(se=>se.slug!==t.slug)??[],Z=E?F:[...F,t];l({...u,[t.source]:Z}),t.fontFace&&t.fontFace.forEach(se=>{if(E)ys(se,"all");else{let we=In(se?.src??"");we&&xo(se,we,"all")}})},$=P.length>0||e.length>0;return(0,Re.jsxs)("div",{className:"font-library__tabpanel-layout",children:[n&&(0,Re.jsx)("div",{className:"font-library__loading",children:(0,Re.jsx)(Ie.ProgressBar,{})}),!n&&(0,Re.jsxs)(Re.Fragment,{children:[(0,Re.jsxs)(Ie.Navigator,{initialPath:t?"/fontFamily":"/",children:[(0,Re.jsx)(Ie.Navigator.Screen,{path:"/",children:(0,Re.jsxs)(Ie.__experimentalVStack,{spacing:"8",children:[d&&(0,Re.jsx)(Ie.Notice,{status:d.type,onRemove:()=>v(null),children:d.message}),!$&&(0,Re.jsx)(Ie.__experimentalText,{as:"p",children:(0,at.__)("No fonts installed.")}),P.length>0&&(0,Re.jsxs)(Ie.__experimentalVStack,{children:[(0,Re.jsx)("h2",{className:"font-library__fonts-title",children:(0,at._x)("Theme","font source")}),(0,Re.jsx)("ul",{role:"list",className:"font-library__fonts-list",children:P.map(F=>(0,Re.jsx)("li",{className:"font-library__fonts-list-item",children:(0,Re.jsx)(vs,{font:F,navigatorPath:"/fontFamily",variantsText:O(F),shouldFocus:F.slug===c,onClick:()=>{v(null),r(F)}})},F.slug))})]}),e.length>0&&(0,Re.jsxs)(Ie.__experimentalVStack,{children:[(0,Re.jsx)("h2",{className:"font-library__fonts-title",children:(0,at._x)("Custom","font source")}),(0,Re.jsx)("ul",{role:"list",className:"font-library__fonts-list",children:e.map(F=>(0,Re.jsx)("li",{className:"font-library__fonts-list-item",children:(0,Re.jsx)(vs,{font:F,navigatorPath:"/fontFamily",variantsText:O(F),shouldFocus:F.slug===c,onClick:()=>{v(null),r(F)}})},F.slug))})]})]})}),(0,Re.jsxs)(Ie.Navigator.Screen,{path:"/fontFamily",children:[t&&(0,Re.jsx)(Bx,{font:t,isOpen:m,setIsOpen:g,setNotice:v,uninstallFontFamily:o,handleSetLibraryFontSelected:r}),(0,Re.jsxs)(Ie.Flex,{justify:"flex-start",children:[(0,Re.jsx)(Ie.Navigator.BackButton,{icon:(0,at.isRTL)()?Mo:Do,size:"small",onClick:()=>{f(t?.slug),r(void 0),v(null)},label:(0,at.__)("Back")}),(0,Re.jsx)(Ie.__experimentalHeading,{level:2,size:13,className:"global-styles-ui-header",children:t?.name})]}),d&&(0,Re.jsxs)(Re.Fragment,{children:[(0,Re.jsx)(Ie.__experimentalSpacer,{margin:1}),(0,Re.jsx)(Ie.Notice,{status:d.type,onRemove:()=>v(null),children:d.message}),(0,Re.jsx)(Ie.__experimentalSpacer,{margin:1})]}),(0,Re.jsx)(Ie.__experimentalSpacer,{margin:4}),(0,Re.jsx)(Ie.__experimentalText,{children:(0,at.__)("Choose font variants. Keep in mind that too many variants could make your site slower.")}),(0,Re.jsx)(Ie.__experimentalSpacer,{margin:4}),(0,Re.jsxs)(Ie.__experimentalVStack,{spacing:0,children:[(0,Re.jsx)(Ie.CheckboxControl,{className:"font-library__select-all",label:(0,at.__)("Select all"),checked:E,onChange:L,indeterminate:M}),(0,Re.jsx)(Ie.__experimentalSpacer,{margin:8}),(0,Re.jsx)("ul",{role:"list",className:"font-library__fonts-list",children:t&&W(t).map((F,Z)=>(0,Re.jsx)("li",{className:"font-library__fonts-list-item",children:(0,Re.jsx)(Dg,{font:t,face:F},`face${Z}`)},`face${Z}`))})]})]})]}),(0,Re.jsxs)(Ie.__experimentalHStack,{justify:"flex-end",className:"font-library__footer",children:[s&&(0,Re.jsx)(Ie.ProgressBar,{}),H&&(0,Re.jsx)(Ie.Button,{__next40pxDefaultSize:!0,isDestructive:!0,variant:"tertiary",onClick:S,children:(0,at.__)("Delete")}),(0,Re.jsx)(Ie.Button,{__next40pxDefaultSize:!0,variant:"primary",onClick:I,disabled:!A,accessibleWhenDisabled:!0,children:(0,at.__)("Update")})]})]})]})}function Bx({font:e,isOpen:t,setIsOpen:r,setNotice:o,uninstallFontFamily:n,handleSetLibraryFontSelected:s}){let i=(0,Ie.useNavigator)(),a=async()=>{o(null),r(!1);try{await n(e),i.goBack(),s(void 0),o({type:"success",message:(0,at.__)("Font family uninstalled successfully.")})}catch(l){o({type:"error",message:(0,at.__)("There was an error uninstalling the font family.")+l.message})}},u=()=>{r(!1)};return(0,Re.jsx)(Ie.__experimentalConfirmDialog,{isOpen:t,cancelButtonText:(0,at.__)("Cancel"),confirmButtonText:(0,at.__)("Delete"),onCancel:u,onConfirm:a,size:"medium",children:e&&(0,at.sprintf)((0,at.__)('Are you sure you want to delete "%s" font and all its variants and assets?'),e.name)})}var Qi=Vx;var bt=h(ke(),1),Ce=h(ce(),1),Yg=h(No(),1),rt=h(xe(),1);var qg=h(nr(),1);function Bg(e,t){let{category:r,search:o}=t,n=e||[];return r&&r!=="all"&&(n=n.filter(s=>s.categories&&s.categories.indexOf(r)!==-1)),o&&(n=n.filter(s=>s.font_family_settings&&s.font_family_settings.name.toLowerCase().includes(o.toLowerCase()))),n}function jg(e){return e.reduce((t,r)=>({...t,[r.slug]:(r?.fontFace||[]).reduce((o,n)=>({...o,[`${n.fontStyle}-${n.fontWeight}`]:!0}),{})}),{})}function zg(e,t,r){return t?!!r[e]?.[`${t.fontStyle}-${t.fontWeight}`]:!!r[e]}var ws=h(xe(),1),Vt=h(ce(),1),pr=h(Y(),1);function jx(){let e=()=>{window.localStorage.setItem("wp-font-library-google-fonts-permission","true"),window.dispatchEvent(new Event("storage"))};return(0,pr.jsx)("div",{className:"font-library__google-fonts-confirm",children:(0,pr.jsx)(Vt.Card,{children:(0,pr.jsxs)(Vt.CardBody,{children:[(0,pr.jsx)(Vt.__experimentalHeading,{level:2,children:(0,ws.__)("Connect to Google Fonts")}),(0,pr.jsx)(Vt.__experimentalSpacer,{margin:6}),(0,pr.jsx)(Vt.__experimentalText,{as:"p",children:(0,ws.__)("To install fonts from Google you must give permission to connect directly to Google servers. The fonts you install will be downloaded from Google and stored on your site. Your site will then use these locally-hosted fonts.")}),(0,pr.jsx)(Vt.__experimentalSpacer,{margin:3}),(0,pr.jsx)(Vt.__experimentalText,{as:"p",children:(0,ws.__)("You can alternatively upload files directly on the Upload tab.")}),(0,pr.jsx)(Vt.__experimentalSpacer,{margin:6}),(0,pr.jsx)(Vt.Button,{__next40pxDefaultSize:!0,variant:"primary",onClick:e,children:(0,ws.__)("Allow access to Google Fonts")})]})})})}var Ug=jx;var Hg=h(ke(),1),$i=h(ce(),1);var qo=h(Y(),1);function zx({face:e,font:t,handleToggleVariant:r,selected:o}){let n=()=>{if(t?.fontFace){r(t,e);return}r(t)},s=t.name+" "+Wi(e),i=(0,Hg.useId)();return(0,qo.jsx)("div",{className:"font-library__font-card",children:(0,qo.jsxs)($i.Flex,{justify:"flex-start",align:"center",gap:"1rem",children:[(0,qo.jsx)($i.CheckboxControl,{checked:o,onChange:n,id:i}),(0,qo.jsx)("label",{htmlFor:i,children:(0,qo.jsx)(Ln,{font:e,text:s,onClick:n})})]})})}var Wg=zx;var he=h(Y(),1),Ux={slug:"all",name:(0,rt._x)("All","font categories")},Gg="wp-font-library-google-fonts-permission",Hx=500;function Wx({slug:e}){let t=e==="google-fonts",r=()=>window.localStorage.getItem(Gg)==="true",[o,n]=(0,bt.useState)(null),[s,i]=(0,bt.useState)(void 0),[a,u]=(0,bt.useState)(null),[l,c]=(0,bt.useState)([]),[f,m]=(0,bt.useState)(1),[g,d]=(0,bt.useState)({}),[v,x]=(0,bt.useState)(t&&!r()),{installFonts:C,isInstalling:w}=(0,bt.useContext)(Mt),{record:b,isResolving:R}=(0,qg.useEntityRecord)("root","fontCollection",e);(0,bt.useEffect)(()=>{let ee=()=>{x(t&&!r())};return ee(),window.addEventListener("storage",ee),()=>window.removeEventListener("storage",ee)},[e,t]);let A=()=>{window.localStorage.setItem(Gg,"false"),window.dispatchEvent(new Event("storage"))};(0,bt.useEffect)(()=>{n(null)},[e]),(0,bt.useEffect)(()=>{c([])},[o]);let T=(0,bt.useMemo)(()=>b?.font_families??[],[b]),_=b?.categories??[],P=[Ux,..._],N=(0,bt.useMemo)(()=>Bg(T,g),[T,g]),q=Math.max(window.innerHeight,Hx),H=Math.floor((q-417)/61),S=Math.ceil(N.length/H),I=(f-1)*H,W=f*H,O=N.slice(I,W),D=ee=>{d({...g,category:ee}),m(1)},M=(0,Yg.debounce)(ee=>{d({...g,search:ee}),m(1)},300),E=(ee,Fe)=>{let Ae=Gi(ee,Fe,l);c(Ae)},L=jg(l),$=()=>{c([])},F=l.length>0?l[0]?.fontFace?.length??0:0,Z=F>0&&F!==o?.fontFace?.length,se=F===o?.fontFace?.length,we=()=>{let ee=[];!se&&o&&ee.push(o),c(ee)},ie=async()=>{u(null);let ee=l[0];try{ee?.fontFace&&await Promise.all(ee.fontFace.map(async Fe=>{Fe.src&&(Fe.file=await Ag(Fe.src))}))}catch{u({type:"error",message:(0,rt.__)("Error installing the fonts, could not be downloaded.")});return}try{await C([ee]),u({type:"success",message:(0,rt.__)("Fonts were installed successfully.")})}catch(Fe){u({type:"error",message:Fe.message})}$()},ve=ee=>ee?!ee.fontFace||!ee.fontFace.length?[{fontFamily:ee.fontFamily,fontStyle:"normal",fontWeight:"400"}]:Ji(ee.fontFace):[];if(v)return(0,he.jsx)(Ug,{});let Ee=e==="google-fonts"&&!v&&!o;return(0,he.jsxs)("div",{className:"font-library__tabpanel-layout",children:[R&&(0,he.jsx)("div",{className:"font-library__loading",children:(0,he.jsx)(Ce.ProgressBar,{})}),!R&&b&&(0,he.jsxs)(he.Fragment,{children:[(0,he.jsxs)(Ce.Navigator,{initialPath:"/",className:"font-library__tabpanel-layout",children:[(0,he.jsxs)(Ce.Navigator.Screen,{path:"/",children:[(0,he.jsxs)(Ce.__experimentalHStack,{justify:"space-between",children:[(0,he.jsxs)(Ce.__experimentalVStack,{children:[(0,he.jsx)(Ce.__experimentalHeading,{level:2,size:13,children:b.name}),(0,he.jsx)(Ce.__experimentalText,{children:b.description})]}),Ee&&(0,he.jsx)(Ce.DropdownMenu,{icon:Vl,label:(0,rt.__)("Actions"),popoverProps:{position:"bottom left"},controls:[{title:(0,rt.__)("Revoke access to Google Fonts"),onClick:A}]})]}),(0,he.jsx)(Ce.__experimentalSpacer,{margin:4}),(0,he.jsxs)(Ce.__experimentalHStack,{spacing:4,justify:"space-between",children:[(0,he.jsx)(Ce.SearchControl,{className:"font-library__search",value:g.search,placeholder:(0,rt.__)("Font name\u2026"),label:(0,rt.__)("Search"),onChange:M,hideLabelFromVision:!1}),(0,he.jsx)(Ce.SelectControl,{label:(0,rt.__)("Category"),value:g.category,onChange:D,children:P&&P.map(ee=>(0,he.jsx)("option",{value:ee.slug,children:ee.name},ee.slug))})]}),(0,he.jsx)(Ce.__experimentalSpacer,{margin:4}),!!b?.font_families?.length&&!N.length&&(0,he.jsx)(Ce.__experimentalText,{children:(0,rt.__)("No fonts found. Try with a different search term.")}),(0,he.jsx)("div",{className:"font-library__fonts-grid__main",children:(0,he.jsx)("ul",{role:"list",className:"font-library__fonts-list",children:O.map(ee=>(0,he.jsx)("li",{className:"font-library__fonts-list-item",children:(0,he.jsx)(vs,{font:ee.font_family_settings,navigatorPath:"/fontFamily",shouldFocus:ee.font_family_settings.slug===s,onClick:()=>{n(ee.font_family_settings)}})},ee.font_family_settings.slug))})})]}),(0,he.jsxs)(Ce.Navigator.Screen,{path:"/fontFamily",children:[(0,he.jsxs)(Ce.Flex,{justify:"flex-start",children:[(0,he.jsx)(Ce.Navigator.BackButton,{icon:(0,rt.isRTL)()?Mo:Do,size:"small",onClick:()=>{i(o?.slug),n(null),u(null)},label:(0,rt.__)("Back")}),(0,he.jsx)(Ce.__experimentalHeading,{level:2,size:13,className:"global-styles-ui-header",children:o?.name})]}),a&&(0,he.jsxs)(he.Fragment,{children:[(0,he.jsx)(Ce.__experimentalSpacer,{margin:1}),(0,he.jsx)(Ce.Notice,{status:a.type,onRemove:()=>u(null),children:a.message}),(0,he.jsx)(Ce.__experimentalSpacer,{margin:1})]}),(0,he.jsx)(Ce.__experimentalSpacer,{margin:4}),(0,he.jsx)(Ce.__experimentalText,{children:(0,rt.__)("Select font variants to install.")}),(0,he.jsx)(Ce.__experimentalSpacer,{margin:4}),(0,he.jsx)(Ce.CheckboxControl,{className:"font-library__select-all",label:(0,rt.__)("Select all"),checked:se,onChange:we,indeterminate:Z}),(0,he.jsx)(Ce.__experimentalVStack,{spacing:0,children:(0,he.jsx)("ul",{role:"list",className:"font-library__fonts-list",children:o&&ve(o).map((ee,Fe)=>(0,he.jsx)("li",{className:"font-library__fonts-list-item",children:(0,he.jsx)(Wg,{font:o,face:ee,handleToggleVariant:E,selected:zg(o.slug,o.fontFace?ee:null,L)})},`face${Fe}`))})}),(0,he.jsx)(Ce.__experimentalSpacer,{margin:16})]})]}),o&&(0,he.jsx)(Ce.Flex,{justify:"flex-end",className:"font-library__footer",children:(0,he.jsx)(Ce.Button,{__next40pxDefaultSize:!0,variant:"primary",onClick:ie,isBusy:w,disabled:l.length===0||w,accessibleWhenDisabled:!0,children:(0,rt.__)("Install")})}),!o&&(0,he.jsxs)(Ce.__experimentalHStack,{expanded:!1,className:"font-library__footer",justify:"end",spacing:6,children:[(0,he.jsx)(Ce.__experimentalHStack,{justify:"flex-start",expanded:!1,spacing:1,className:"font-library__page-selection",children:(0,bt.createInterpolateElement)((0,rt.sprintf)((0,rt._x)("
Page
%1$s
of %2$d
","paging"),"",S),{div:(0,he.jsx)("div",{"aria-hidden":!0}),CurrentPage:(0,he.jsx)(Ce.SelectControl,{"aria-label":(0,rt.__)("Current page"),value:f.toString(),options:[...Array(S)].map((ee,Fe)=>({label:(Fe+1).toString(),value:(Fe+1).toString()})),onChange:ee=>m(parseInt(ee)),size:"small",variant:"minimal"})})}),(0,he.jsxs)(Ce.__experimentalHStack,{expanded:!1,spacing:1,children:[(0,he.jsx)(Ce.Button,{onClick:()=>m(f-1),disabled:f===1,accessibleWhenDisabled:!0,label:(0,rt.__)("Previous page"),icon:(0,rt.isRTL)()?Ri:Ti,showTooltip:!0,size:"compact",tooltipPosition:"top"}),(0,he.jsx)(Ce.Button,{onClick:()=>m(f+1),disabled:f===S,accessibleWhenDisabled:!0,label:(0,rt.__)("Next page"),icon:(0,rt.isRTL)()?Ti:Ri,showTooltip:!0,size:"compact",tooltipPosition:"top"})]})]})]})]})}var ea=Wx;var Dn=h(xe(),1),Ft=h(ce(),1),Ss=h(ke(),1);var ta=(e=>typeof zt<"u"?zt:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof zt<"u"?zt:t)[r]}):e)(function(e){if(typeof zt<"u")return zt.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')}),Zg=(function(){var e,t,r;return(function(){function o(n,s,i){function a(c,f){if(!s[c]){if(!n[c]){var m=typeof ta=="function"&&ta;if(!f&&m)return m(c,!0);if(u)return u(c,!0);var g=new Error("Cannot find module '"+c+"'");throw g.code="MODULE_NOT_FOUND",g}var d=s[c]={exports:{}};n[c][0].call(d.exports,function(v){var x=n[c][1][v];return a(x||v)},d,d.exports,o,n,s,i)}return s[c].exports}for(var u=typeof ta=="function"&&ta,l=0;l0},c.prototype.readMoreInput=function(){if(!(this.bit_end_pos_>256))if(this.eos_){if(this.bit_pos_>this.bit_end_pos_)throw new Error("Unexpected end of input "+this.bit_pos_+" "+this.bit_end_pos_)}else{var f=this.buf_ptr_,m=this.input_.read(this.buf_,f,i);if(m<0)throw new Error("Unexpected end of input");if(m=8;)this.val_>>>=8,this.val_|=this.buf_[this.pos_&u]<<24,++this.pos_,this.bit_pos_=this.bit_pos_-8>>>0,this.bit_end_pos_=this.bit_end_pos_-8>>>0},c.prototype.readBits=function(f){32-this.bit_pos_>>this.bit_pos_&l[f];return this.bit_pos_+=f,m},n.exports=c},{}],2:[function(o,n,s){var i=0,a=1,u=2,l=3;s.lookup=new Uint8Array([0,0,0,0,0,0,0,0,0,4,4,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,12,16,12,12,20,12,16,24,28,12,12,32,12,36,12,44,44,44,44,44,44,44,44,44,44,32,32,24,40,28,12,12,48,52,52,52,48,52,52,52,48,52,52,52,52,52,48,52,52,52,52,52,48,52,52,52,52,52,24,12,28,12,12,12,56,60,60,60,56,60,60,60,56,60,60,60,60,60,56,60,60,60,60,60,56,60,60,60,60,60,24,12,28,12,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,56,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10,11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,14,15,15,15,15,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,22,22,22,22,23,23,23,23,24,24,24,24,25,25,25,25,26,26,26,26,27,27,27,27,28,28,28,28,29,29,29,29,30,30,30,30,31,31,31,31,32,32,32,32,33,33,33,33,34,34,34,34,35,35,35,35,36,36,36,36,37,37,37,37,38,38,38,38,39,39,39,39,40,40,40,40,41,41,41,41,42,42,42,42,43,43,43,43,44,44,44,44,45,45,45,45,46,46,46,46,47,47,47,47,48,48,48,48,49,49,49,49,50,50,50,50,51,51,51,51,52,52,52,52,53,53,53,53,54,54,54,54,55,55,55,55,56,56,56,56,57,57,57,57,58,58,58,58,59,59,59,59,60,60,60,60,61,61,61,61,62,62,62,62,63,63,63,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]),s.lookupOffsets=new Uint16Array([1024,1536,1280,1536,0,256,768,512])},{}],3:[function(o,n,s){var i=o("./streams").BrotliInput,a=o("./streams").BrotliOutput,u=o("./bit_reader"),l=o("./dictionary"),c=o("./huffman").HuffmanCode,f=o("./huffman").BrotliBuildHuffmanTable,m=o("./context"),g=o("./prefix"),d=o("./transform"),v=8,x=16,C=256,w=704,b=26,R=6,A=2,T=8,_=255,P=1080,N=18,q=new Uint8Array([1,2,3,4,0,5,17,6,16,7,8,9,10,11,12,13,14,15]),H=16,S=new Uint8Array([3,2,1,0,3,3,3,3,3,3,2,2,2,2,2,2]),I=new Int8Array([0,0,0,0,-1,1,-2,2,-3,3,-1,1,-2,2,-3,3]),W=new Uint16Array([256,402,436,468,500,534,566,598,630,662,694,726,758,790,822,854,886,920,952,984,1016,1048,1080]);function O(G){var z;return G.readBits(1)===0?16:(z=G.readBits(3),z>0?17+z:(z=G.readBits(3),z>0?8+z:17))}function D(G){if(G.readBits(1)){var z=G.readBits(3);return z===0?1:G.readBits(z)+(1<1&&fe===0)throw new Error("Invalid size byte");z.meta_block_length|=fe<4&&ue===0)throw new Error("Invalid size nibble");z.meta_block_length|=ue<>>X.bit_pos_&_,K=G[z].bits-T,K>0&&(X.bit_pos_+=T,z+=G[z].value,z+=X.val_>>>X.bit_pos_&(1<0;){var re=0,Ne;if(U.readMoreInput(),U.fillBitWindow(),re+=U.val_>>>U.bit_pos_&31,U.bit_pos_+=me[re].bits,Ne=me[re].value&255,Ne>Ne);else{var He=Ne-14,ot,ut,ze=0;if(Ne===x&&(ze=fe),de!==ze&&(ue=0,de=ze),ot=ue,ue>0&&(ue-=2,ue<<=He),ue+=U.readBits(He)+3,ut=ue-ot,K+ut>z)throw new Error("[ReadHuffmanCodeLengths] symbol + repeat_delta > num_symbols");for(var We=0;We0;++de){var ze=q[de],We=0,nt;U.fillBitWindow(),We+=U.val_>>>U.bit_pos_&15,U.bit_pos_+=ut[We].bits,nt=ut[We].value,Ne[ze]=nt,nt!==0&&(He-=32>>nt,++ot)}if(!(ot===1||He===0))throw new Error("[ReadHuffmanCode] invalid num_codes or space");L(Ne,G,ue,U)}if(K=f(z,X,T,ue,G),K===0)throw new Error("[ReadHuffmanCode] BuildHuffmanTable failed: ");return K}function F(G,z,X){var U,K;return U=E(G,z,X),K=g.kBlockLengthPrefixCode[U].nbits,g.kBlockLengthPrefixCode[U].offset+X.readBits(K)}function Z(G,z,X){var U;return G>>5]),this.htrees=new Uint32Array(z)}ie.prototype.decode=function(G){var z,X,U=0;for(z=0;z=G)throw new Error("[DecodeContextMap] i >= context_map_size");pe[ue]=0,++ue}else pe[ue]=me-K,++ue}return z.readBits(1)&&we(pe,G),X}function Ee(G,z,X,U,K,fe,ue){var de=X*2,pe=X,me=E(z,X*P,ue),V;me===0?V=K[de+(fe[pe]&1)]:me===1?V=K[de+(fe[pe]-1&1)]+1:V=me-2,V>=G&&(V-=G),U[X]=V,K[de+(fe[pe]&1)]=V,++fe[pe]}function ee(G,z,X,U,K,fe){var ue=K+1,de=X&K,pe=fe.pos_&u.IBUF_MASK,me;if(z<8||fe.bit_pos_+(z<<3)0;)fe.readMoreInput(),U[de++]=fe.readBits(8),de===ue&&(G.write(U,ue),de=0);return}if(fe.bit_end_pos_<32)throw new Error("[CopyUncompressedBlockToOutput] br.bit_end_pos_ < 32");for(;fe.bit_pos_<32;)U[de]=fe.val_>>>fe.bit_pos_,fe.bit_pos_+=8,++de,--z;if(me=fe.bit_end_pos_-fe.bit_pos_>>3,pe+me>u.IBUF_MASK){for(var V=u.IBUF_MASK+1-pe,re=0;re=ue){G.write(U,ue),de-=ue;for(var re=0;re=ue;){if(me=ue-de,fe.input_.read(U,de,me)z.buffer.length){var Ro=new Uint8Array(U+$e);Ro.set(z.buffer),z.buffer=Ro}if(K=Ur.input_end,jr=Ur.is_uncompressed,Ur.is_metadata){for(Fe(be);$e>0;--$e)be.readMoreInput(),be.readBits(8);continue}if($e!==0){if(jr){be.bit_pos_=be.bit_pos_+7&-8,ee(z,$e,U,V,me,be),U+=$e;continue}for(X=0;X<3;++X)qe[X]=D(be)+1,qe[X]>=2&&($(qe[X]+2,We,X*P,be),$(b,nt,X*P,be),Ct[X]=F(nt,X*P,be),Q[X]=1);for(be.readMoreInput(),y=be.readBits(2),oe=H+(be.readBits(4)<0;){var dt,It,Bt,Ko,xa,jt,$t,Hr,zn,Jo,Un;for(be.readMoreInput(),Ct[1]===0&&(Ee(qe[1],We,1,Le,k,Q,be),Ct[1]=F(nt,P,be),wt=ze[1].htrees[Le[1]]),--Ct[1],dt=E(ze[1].codes,wt,be),It=dt>>6,It>=2?(It-=2,$t=-1):$t=0,Bt=g.kInsertRangeLut[It]+(dt>>3&7),Ko=g.kCopyRangeLut[It]+(dt&7),xa=g.kInsertLengthPrefixCode[Bt].offset+be.readBits(g.kInsertLengthPrefixCode[Bt].nbits),jt=g.kCopyLengthPrefixCode[Ko].offset+be.readBits(g.kCopyLengthPrefixCode[Ko].nbits),ot=V[U-1&me],ut=V[U-2&me],Jo=0;Jo4?3:jt-2)&255,et=B[Qt+zn],$t=E(ze[2].codes,ze[2].htrees[et],be),$t>=oe){var Sa,Eu,Hn;$t-=oe,Eu=$t&Ve,$t>>=y,Sa=($t>>1)+1,Hn=(2+($t&1)<de)if(jt>=l.minDictionaryWordLength&&jt<=l.maxDictionaryWordLength){var Hn=l.offsetsByLength[jt],Tu=Hr-de-1,_u=l.sizeBitsByLength[jt],mv=(1<<_u)-1,hv=Tu&mv,Pu=Tu>>_u;if(Hn+=hv*jt,Pu=re){z.write(V,pe);for(var Os=0;Os0&&(Ne[He&3]=Hr,++He),jt>$e)throw new Error("Invalid backward reference. pos: "+U+" distance: "+Hr+" len: "+jt+" bytes left: "+$e);for(Jo=0;Jo>=1;return(f&g-1)+g}function l(f,m,g,d,v){do d-=g,f[m+d]=new i(v.bits,v.value);while(d>0)}function c(f,m,g){for(var d=1<0;--S[w])C=new i(w&255,H[b++]&65535),l(f,m+R,A,N,C),R=u(R,w);for(_=q-1,T=-1,w=g+1,A=2;w<=a;++w,A<<=1)for(;S[w]>0;--S[w])(R&_)!==T&&(m+=N,P=c(S,w,g),N=1<>g),A,N,C),R=u(R,w);return q}},{}],8:[function(o,n,s){"use strict";s.byteLength=g,s.toByteArray=v,s.fromByteArray=w;for(var i=[],a=[],u=typeof Uint8Array<"u"?Uint8Array:Array,l="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",c=0,f=l.length;c0)throw new Error("Invalid string. Length must be a multiple of 4");var A=b.indexOf("=");A===-1&&(A=R);var T=A===R?0:4-A%4;return[A,T]}function g(b){var R=m(b),A=R[0],T=R[1];return(A+T)*3/4-T}function d(b,R,A){return(R+A)*3/4-A}function v(b){for(var R,A=m(b),T=A[0],_=A[1],P=new u(d(b,T,_)),N=0,q=_>0?T-4:T,H=0;H>16&255,P[N++]=R>>8&255,P[N++]=R&255;return _===2&&(R=a[b.charCodeAt(H)]<<2|a[b.charCodeAt(H+1)]>>4,P[N++]=R&255),_===1&&(R=a[b.charCodeAt(H)]<<10|a[b.charCodeAt(H+1)]<<4|a[b.charCodeAt(H+2)]>>2,P[N++]=R>>8&255,P[N++]=R&255),P}function x(b){return i[b>>18&63]+i[b>>12&63]+i[b>>6&63]+i[b&63]}function C(b,R,A){for(var T,_=[],P=R;Pq?q:N+P));return T===1?(R=b[A-1],_.push(i[R>>2]+i[R<<4&63]+"==")):T===2&&(R=(b[A-2]<<8)+b[A-1],_.push(i[R>>10]+i[R>>4&63]+i[R<<2&63]+"=")),_.join("")}},{}],9:[function(o,n,s){function i(a,u){this.offset=a,this.nbits=u}s.kBlockLengthPrefixCode=[new i(1,2),new i(5,2),new i(9,2),new i(13,2),new i(17,3),new i(25,3),new i(33,3),new i(41,3),new i(49,4),new i(65,4),new i(81,4),new i(97,4),new i(113,5),new i(145,5),new i(177,5),new i(209,5),new i(241,6),new i(305,6),new i(369,7),new i(497,8),new i(753,9),new i(1265,10),new i(2289,11),new i(4337,12),new i(8433,13),new i(16625,24)],s.kInsertLengthPrefixCode=[new i(0,0),new i(1,0),new i(2,0),new i(3,0),new i(4,0),new i(5,0),new i(6,1),new i(8,1),new i(10,2),new i(14,2),new i(18,3),new i(26,3),new i(34,4),new i(50,4),new i(66,5),new i(98,5),new i(130,6),new i(194,7),new i(322,8),new i(578,9),new i(1090,10),new i(2114,12),new i(6210,14),new i(22594,24)],s.kCopyLengthPrefixCode=[new i(2,0),new i(3,0),new i(4,0),new i(5,0),new i(6,0),new i(7,0),new i(8,0),new i(9,0),new i(10,1),new i(12,1),new i(14,2),new i(18,2),new i(22,3),new i(30,3),new i(38,4),new i(54,4),new i(70,5),new i(102,5),new i(134,6),new i(198,7),new i(326,8),new i(582,9),new i(1094,10),new i(2118,24)],s.kInsertRangeLut=[0,0,8,8,0,16,8,16,16],s.kCopyRangeLut=[0,8,0,8,16,0,16,8,16]},{}],10:[function(o,n,s){function i(u){this.buffer=u,this.pos=0}i.prototype.read=function(u,l,c){this.pos+c>this.buffer.length&&(c=this.buffer.length-this.pos);for(var f=0;fthis.buffer.length)throw new Error("Output buffer is not large enough");return this.buffer.set(u.subarray(0,l),this.pos),this.pos+=l,l},s.BrotliOutput=a},{}],11:[function(o,n,s){var i=o("./dictionary"),a=0,u=1,l=2,c=3,f=4,m=5,g=6,d=7,v=8,x=9,C=10,w=11,b=12,R=13,A=14,T=15,_=16,P=17,N=18,q=19,H=20;function S(O,D,J){this.prefix=new Uint8Array(O.length),this.transform=D,this.suffix=new Uint8Array(J.length);for(var M=0;M'),new S("",a,` -`),new S("",c,""),new S("",a,"]"),new S("",a," for "),new S("",A,""),new S("",l,""),new S("",a," a "),new S("",a," that "),new S(" ",C,""),new S("",a,". "),new S(".",a,""),new S(" ",a,", "),new S("",T,""),new S("",a," with "),new S("",a,"'"),new S("",a," from "),new S("",a," by "),new S("",_,""),new S("",P,""),new S(" the ",a,""),new S("",f,""),new S("",a,". The "),new S("",w,""),new S("",a," on "),new S("",a," as "),new S("",a," is "),new S("",d,""),new S("",u,"ing "),new S("",a,` - `),new S("",a,":"),new S(" ",a,". "),new S("",a,"ed "),new S("",H,""),new S("",N,""),new S("",g,""),new S("",a,"("),new S("",C,", "),new S("",v,""),new S("",a," at "),new S("",a,"ly "),new S(" the ",a," of "),new S("",m,""),new S("",x,""),new S(" ",C,", "),new S("",C,'"'),new S(".",a,"("),new S("",w," "),new S("",C,'">'),new S("",a,'="'),new S(" ",a,"."),new S(".com/",a,""),new S(" the ",a," of the "),new S("",C,"'"),new S("",a,". This "),new S("",a,","),new S(".",a," "),new S("",C,"("),new S("",C,"."),new S("",a," not "),new S(" ",a,'="'),new S("",a,"er "),new S(" ",w," "),new S("",a,"al "),new S(" ",w,""),new S("",a,"='"),new S("",w,'"'),new S("",C,". "),new S(" ",a,"("),new S("",a,"ful "),new S(" ",C,". "),new S("",a,"ive "),new S("",a,"less "),new S("",w,"'"),new S("",a,"est "),new S(" ",C,"."),new S("",w,'">'),new S(" ",a,"='"),new S("",C,","),new S("",a,"ize "),new S("",w,"."),new S("\xC2\xA0",a,""),new S(" ",a,","),new S("",C,'="'),new S("",w,'="'),new S("",a,"ous "),new S("",w,", "),new S("",C,"='"),new S(" ",C,","),new S(" ",w,'="'),new S(" ",w,", "),new S("",w,","),new S("",w,"("),new S("",w,". "),new S(" ",w,"."),new S("",w,"='"),new S(" ",w,". "),new S(" ",C,'="'),new S(" ",w,"='"),new S(" ",C,"='")];s.kTransforms=I,s.kNumTransforms=I.length;function W(O,D){return O[D]<192?(O[D]>=97&&O[D]<=122&&(O[D]^=32),1):O[D]<224?(O[D+1]^=32,2):(O[D+2]^=5,3)}s.transformDictionaryWord=function(O,D,J,M,E){var L=I[E].prefix,$=I[E].suffix,F=I[E].transform,Z=FM&&(Z=M);for(var ve=0;ve0;){var Ee=W(O,ie);ie+=Ee,M-=Ee}for(var ee=0;ee<$.length;)O[D++]=$[ee++];return D-we}},{"./dictionary":6}],12:[function(o,n,s){n.exports=o("./dec/decode").BrotliDecompressBuffer},{"./dec/decode":3}]},{},[12])(12)})();var ra=(e=>typeof zt<"u"?zt:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof zt<"u"?zt:t)[r]}):e)(function(e){if(typeof zt<"u")return zt.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')}),Xg=(function(){var e,t,r;return(function(){function o(n,s,i){function a(c,f){if(!s[c]){if(!n[c]){var m=typeof ra=="function"&&ra;if(!f&&m)return m(c,!0);if(u)return u(c,!0);var g=new Error("Cannot find module '"+c+"'");throw g.code="MODULE_NOT_FOUND",g}var d=s[c]={exports:{}};n[c][0].call(d.exports,function(v){var x=n[c][1][v];return a(x||v)},d,d.exports,o,n,s,i)}return s[c].exports}for(var u=typeof ra=="function"&&ra,l=0;l=252?6:c>=248?5:c>=240?4:c>=224?3:c>=192?2:1;l[254]=l[254]=1,s.string2buf=function(m){var g,d,v,x,C,w=m.length,b=0;for(x=0;x>>6,g[C++]=128|d&63):d<65536?(g[C++]=224|d>>>12,g[C++]=128|d>>>6&63,g[C++]=128|d&63):(g[C++]=240|d>>>18,g[C++]=128|d>>>12&63,g[C++]=128|d>>>6&63,g[C++]=128|d&63);return g};function f(m,g){if(g<65534&&(m.subarray&&u||!m.subarray&&a))return String.fromCharCode.apply(null,i.shrinkBuf(m,g));for(var d="",v=0;v4){b[v++]=65533,d+=C-1;continue}for(x&=C===2?31:C===3?15:7;C>1&&d1){b[v++]=65533;continue}x<65536?b[v++]=x:(x-=65536,b[v++]=55296|x>>10&1023,b[v++]=56320|x&1023)}return f(b,v)},s.utf8border=function(m,g){var d;for(g=g||m.length,g>m.length&&(g=m.length),d=g-1;d>=0&&(m[d]&192)===128;)d--;return d<0||d===0?g:d+l[m[d]]>g?d:g}},{"./common":1}],3:[function(o,n,s){"use strict";function i(a,u,l,c){for(var f=a&65535|0,m=a>>>16&65535|0,g=0;l!==0;){g=l>2e3?2e3:l,l-=g;do f=f+u[c++]|0,m=m+f|0;while(--g);f%=65521,m%=65521}return f|m<<16|0}n.exports=i},{}],4:[function(o,n,s){"use strict";n.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],5:[function(o,n,s){"use strict";function i(){for(var l,c=[],f=0;f<256;f++){l=f;for(var m=0;m<8;m++)l=l&1?3988292384^l>>>1:l>>>1;c[f]=l}return c}var a=i();function u(l,c,f,m){var g=a,d=m+f;l^=-1;for(var v=m;v>>8^g[(l^c[v])&255];return l^-1}n.exports=u},{}],6:[function(o,n,s){"use strict";function i(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}n.exports=i},{}],7:[function(o,n,s){"use strict";var i=30,a=12;n.exports=function(l,c){var f,m,g,d,v,x,C,w,b,R,A,T,_,P,N,q,H,S,I,W,O,D,J,M,E;f=l.state,m=l.next_in,M=l.input,g=m+(l.avail_in-5),d=l.next_out,E=l.output,v=d-(c-l.avail_out),x=d+(l.avail_out-257),C=f.dmax,w=f.wsize,b=f.whave,R=f.wnext,A=f.window,T=f.hold,_=f.bits,P=f.lencode,N=f.distcode,q=(1<>>24,T>>>=I,_-=I,I=S>>>16&255,I===0)E[d++]=S&65535;else if(I&16){W=S&65535,I&=15,I&&(_>>=I,_-=I),_<15&&(T+=M[m++]<<_,_+=8,T+=M[m++]<<_,_+=8),S=N[T&H];r:for(;;){if(I=S>>>24,T>>>=I,_-=I,I=S>>>16&255,I&16){if(O=S&65535,I&=15,_C){l.msg="invalid distance too far back",f.mode=i;break e}if(T>>>=I,_-=I,I=d-v,O>I){if(I=O-I,I>b&&f.sane){l.msg="invalid distance too far back",f.mode=i;break e}if(D=0,J=A,R===0){if(D+=w-I,I2;)E[d++]=J[D++],E[d++]=J[D++],E[d++]=J[D++],W-=3;W&&(E[d++]=J[D++],W>1&&(E[d++]=J[D++]))}else{D=d-O;do E[d++]=E[D++],E[d++]=E[D++],E[d++]=E[D++],W-=3;while(W>2);W&&(E[d++]=E[D++],W>1&&(E[d++]=E[D++]))}}else if((I&64)===0){S=N[(S&65535)+(T&(1<>3,m-=W,_-=W<<3,T&=(1<<_)-1,l.next_in=m,l.next_out=d,l.avail_in=m>>24&255)+(k>>>8&65280)+((k&65280)<<8)+((k&255)<<24)}function Ne(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new i.Buf16(320),this.work=new i.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function He(k){var Q;return!k||!k.state?R:(Q=k.state,k.total_in=k.total_out=Q.total=0,k.msg="",Q.wrap&&(k.adler=Q.wrap&1),Q.mode=N,Q.last=0,Q.havedict=0,Q.dmax=32768,Q.head=null,Q.hold=0,Q.bits=0,Q.lencode=Q.lendyn=new i.Buf32(de),Q.distcode=Q.distdyn=new i.Buf32(pe),Q.sane=1,Q.back=-1,C)}function ot(k){var Q;return!k||!k.state?R:(Q=k.state,Q.wsize=0,Q.whave=0,Q.wnext=0,He(k))}function ut(k,Q){var y,oe;return!k||!k.state||(oe=k.state,Q<0?(y=0,Q=-Q):(y=(Q>>4)+1,Q<48&&(Q&=15)),Q&&(Q<8||Q>15))?R:(oe.window!==null&&oe.wbits!==Q&&(oe.window=null),oe.wrap=y,oe.wbits=Q,ot(k))}function ze(k,Q){var y,oe;return k?(oe=new Ne,k.state=oe,oe.window=null,y=ut(k,Q),y!==C&&(k.state=null),y):R}function We(k){return ze(k,V)}var nt=!0,be,Rr;function gr(k){if(nt){var Q;for(be=new i.Buf32(512),Rr=new i.Buf32(32),Q=0;Q<144;)k.lens[Q++]=8;for(;Q<256;)k.lens[Q++]=9;for(;Q<280;)k.lens[Q++]=7;for(;Q<288;)k.lens[Q++]=8;for(c(m,k.lens,0,288,be,0,k.work,{bits:9}),Q=0;Q<32;)k.lens[Q++]=5;c(g,k.lens,0,32,Rr,0,k.work,{bits:5}),nt=!1}k.lencode=be,k.lenbits=9,k.distcode=Rr,k.distbits=5}function $e(k,Q,y,oe){var Ve,te=k.state;return te.window===null&&(te.wsize=1<=te.wsize?(i.arraySet(te.window,Q,y-te.wsize,te.wsize,0),te.wnext=0,te.whave=te.wsize):(Ve=te.wsize-te.wnext,Ve>oe&&(Ve=oe),i.arraySet(te.window,Q,y-oe,Ve,te.wnext),oe-=Ve,oe?(i.arraySet(te.window,Q,y-oe,oe,0),te.wnext=oe,te.whave=te.wsize):(te.wnext+=Ve,te.wnext===te.wsize&&(te.wnext=0),te.whave>>8&255,y.check=u(y.check,dt,2,0),B=0,j=0,y.mode=q;break}if(y.flags=0,y.head&&(y.head.done=!1),!(y.wrap&1)||(((B&255)<<8)+(B>>8))%31){k.msg="incorrect header check",y.mode=K;break}if((B&15)!==P){k.msg="unknown compression method",y.mode=K;break}if(B>>>=4,j-=4,lt=(B&15)+8,y.wbits===0)y.wbits=lt;else if(lt>y.wbits){k.msg="invalid window size",y.mode=K;break}y.dmax=1<>8&1),y.flags&512&&(dt[0]=B&255,dt[1]=B>>>8&255,y.check=u(y.check,dt,2,0)),B=0,j=0,y.mode=H;case H:for(;j<32;){if(ne===0)break e;ne--,B+=oe[te++]<>>8&255,dt[2]=B>>>16&255,dt[3]=B>>>24&255,y.check=u(y.check,dt,4,0)),B=0,j=0,y.mode=S;case S:for(;j<16;){if(ne===0)break e;ne--,B+=oe[te++]<>8),y.flags&512&&(dt[0]=B&255,dt[1]=B>>>8&255,y.check=u(y.check,dt,2,0)),B=0,j=0,y.mode=I;case I:if(y.flags&1024){for(;j<16;){if(ne===0)break e;ne--,B+=oe[te++]<>>8&255,y.check=u(y.check,dt,2,0)),B=0,j=0}else y.head&&(y.head.extra=null);y.mode=W;case W:if(y.flags&1024&&(le=y.length,le>ne&&(le=ne),le&&(y.head&&(lt=y.head.extra_len-y.length,y.head.extra||(y.head.extra=new Array(y.head.extra_len)),i.arraySet(y.head.extra,oe,te,le,lt)),y.flags&512&&(y.check=u(y.check,oe,le,te)),ne-=le,te+=le,y.length-=le),y.length))break e;y.length=0,y.mode=O;case O:if(y.flags&2048){if(ne===0)break e;le=0;do lt=oe[te+le++],y.head&<&&y.length<65536&&(y.head.name+=String.fromCharCode(lt));while(lt&&le>9&1,y.head.done=!0),k.adler=y.check=0,y.mode=L;break;case M:for(;j<32;){if(ne===0)break e;ne--,B+=oe[te++]<>>=j&7,j-=j&7,y.mode=z;break}for(;j<3;){if(ne===0)break e;ne--,B+=oe[te++]<>>=1,j-=1,B&3){case 0:y.mode=F;break;case 1:if(gr(y),y.mode=Ee,Q===x){B>>>=2,j-=2;break e}break;case 2:y.mode=we;break;case 3:k.msg="invalid block type",y.mode=K}B>>>=2,j-=2;break;case F:for(B>>>=j&7,j-=j&7;j<32;){if(ne===0)break e;ne--,B+=oe[te++]<>>16^65535)){k.msg="invalid stored block lengths",y.mode=K;break}if(y.length=B&65535,B=0,j=0,y.mode=Z,Q===x)break e;case Z:y.mode=se;case se:if(le=y.length,le){if(le>ne&&(le=ne),le>Qe&&(le=Qe),le===0)break e;i.arraySet(Ve,oe,te,le,ht),ne-=le,te+=le,Qe-=le,ht+=le,y.length-=le;break}y.mode=L;break;case we:for(;j<14;){if(ne===0)break e;ne--,B+=oe[te++]<>>=5,j-=5,y.ndist=(B&31)+1,B>>>=5,j-=5,y.ncode=(B&15)+4,B>>>=4,j-=4,y.nlen>286||y.ndist>30){k.msg="too many length or distance symbols",y.mode=K;break}y.have=0,y.mode=ie;case ie:for(;y.have>>=3,j-=3}for(;y.have<19;)y.lens[Ko[y.have++]]=0;if(y.lencode=y.lendyn,y.lenbits=7,It={bits:y.lenbits},At=c(f,y.lens,0,19,y.lencode,0,y.work,It),y.lenbits=It.bits,At){k.msg="invalid code lengths set",y.mode=K;break}y.have=0,y.mode=ve;case ve:for(;y.have>>24,ft=et>>>16&255,gt=et&65535,!(Me<=j);){if(ne===0)break e;ne--,B+=oe[te++]<>>=Me,j-=Me,y.lens[y.have++]=gt;else{if(gt===16){for(Bt=Me+2;j>>=Me,j-=Me,y.have===0){k.msg="invalid bit length repeat",y.mode=K;break}lt=y.lens[y.have-1],le=3+(B&3),B>>>=2,j-=2}else if(gt===17){for(Bt=Me+3;j>>=Me,j-=Me,lt=0,le=3+(B&7),B>>>=3,j-=3}else{for(Bt=Me+7;j>>=Me,j-=Me,lt=0,le=11+(B&127),B>>>=7,j-=7}if(y.have+le>y.nlen+y.ndist){k.msg="invalid bit length repeat",y.mode=K;break}for(;le--;)y.lens[y.have++]=lt}}if(y.mode===K)break;if(y.lens[256]===0){k.msg="invalid code -- missing end-of-block",y.mode=K;break}if(y.lenbits=9,It={bits:y.lenbits},At=c(m,y.lens,0,y.nlen,y.lencode,0,y.work,It),y.lenbits=It.bits,At){k.msg="invalid literal/lengths set",y.mode=K;break}if(y.distbits=6,y.distcode=y.distdyn,It={bits:y.distbits},At=c(g,y.lens,y.nlen,y.ndist,y.distcode,0,y.work,It),y.distbits=It.bits,At){k.msg="invalid distances set",y.mode=K;break}if(y.mode=Ee,Q===x)break e;case Ee:y.mode=ee;case ee:if(ne>=6&&Qe>=258){k.next_out=ht,k.avail_out=Qe,k.next_in=te,k.avail_in=ne,y.hold=B,y.bits=j,l(k,Ge),ht=k.next_out,Ve=k.output,Qe=k.avail_out,te=k.next_in,oe=k.input,ne=k.avail_in,B=y.hold,j=y.bits,y.mode===L&&(y.back=-1);break}for(y.back=0;et=y.lencode[B&(1<>>24,ft=et>>>16&255,gt=et&65535,!(Me<=j);){if(ne===0)break e;ne--,B+=oe[te++]<>wt)],Me=et>>>24,ft=et>>>16&255,gt=et&65535,!(wt+Me<=j);){if(ne===0)break e;ne--,B+=oe[te++]<>>=wt,j-=wt,y.back+=wt}if(B>>>=Me,j-=Me,y.back+=Me,y.length=gt,ft===0){y.mode=G;break}if(ft&32){y.back=-1,y.mode=L;break}if(ft&64){k.msg="invalid literal/length code",y.mode=K;break}y.extra=ft&15,y.mode=Fe;case Fe:if(y.extra){for(Bt=y.extra;j>>=y.extra,j-=y.extra,y.back+=y.extra}y.was=y.length,y.mode=Ae;case Ae:for(;et=y.distcode[B&(1<>>24,ft=et>>>16&255,gt=et&65535,!(Me<=j);){if(ne===0)break e;ne--,B+=oe[te++]<>wt)],Me=et>>>24,ft=et>>>16&255,gt=et&65535,!(wt+Me<=j);){if(ne===0)break e;ne--,B+=oe[te++]<>>=wt,j-=wt,y.back+=wt}if(B>>>=Me,j-=Me,y.back+=Me,ft&64){k.msg="invalid distance code",y.mode=K;break}y.offset=gt,y.extra=ft&15,y.mode=Oe;case Oe:if(y.extra){for(Bt=y.extra;j>>=y.extra,j-=y.extra,y.back+=y.extra}if(y.offset>y.dmax){k.msg="invalid distance too far back",y.mode=K;break}y.mode=Ue;case Ue:if(Qe===0)break e;if(le=Ge-Qe,y.offset>le){if(le=y.offset-le,le>y.whave&&y.sane){k.msg="invalid distance too far back",y.mode=K;break}le>y.wnext?(le-=y.wnext,zr=y.wsize-le):zr=y.wnext-le,le>y.length&&(le=y.length),Qt=y.window}else Qt=Ve,zr=ht-y.offset,le=y.length;le>Qe&&(le=Qe),Qe-=le,y.length-=le;do Ve[ht++]=Qt[zr++];while(--le);y.length===0&&(y.mode=ee);break;case G:if(Qe===0)break e;Ve[ht++]=y.length,Qe--,y.mode=ee;break;case z:if(y.wrap){for(;j<32;){if(ne===0)break e;ne--,B|=oe[te++]<=1&&ee[W]===0;W--);if(O>W&&(O=W),W===0)return T[_++]=1<<24|64<<16|0,T[_++]=1<<24|64<<16|0,N.bits=1,0;for(I=1;I0&&(w===c||W!==1))return-1;for(Fe[1]=0,H=1;Hu||w===m&&E>l)return 1;for(;;){Ue=H-J,P[S]Ee?(G=Ae[Oe+P[S]],z=ie[ve+P[S]]):(G=96,z=0),$=1<>J)+F]=Ue<<24|G<<16|z|0;while(F!==0);for($=1<>=1;if($!==0?(L&=$-1,L+=$):L=0,S++,--ee[H]===0){if(H===W)break;H=b[R+P[S]]}if(H>O&&(L&se)!==Z){for(J===0&&(J=O),we+=I,D=H-J,M=1<u||w===m&&E>l)return 1;Z=L&se,T[Z]=O<<24|D<<16|we-_|0}}return L!==0&&(T[we+L]=H-J<<24|64<<16|0),N.bits=O,0}},{"../utils/common":1}],10:[function(o,n,s){"use strict";n.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],11:[function(o,n,s){"use strict";function i(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}n.exports=i},{}],"/lib/inflate.js":[function(o,n,s){"use strict";var i=o("./zlib/inflate"),a=o("./utils/common"),u=o("./utils/strings"),l=o("./zlib/constants"),c=o("./zlib/messages"),f=o("./zlib/zstream"),m=o("./zlib/gzheader"),g=Object.prototype.toString;function d(C){if(!(this instanceof d))return new d(C);this.options=a.assign({chunkSize:16384,windowBits:0,to:""},C||{});var w=this.options;w.raw&&w.windowBits>=0&&w.windowBits<16&&(w.windowBits=-w.windowBits,w.windowBits===0&&(w.windowBits=-15)),w.windowBits>=0&&w.windowBits<16&&!(C&&C.windowBits)&&(w.windowBits+=32),w.windowBits>15&&w.windowBits<48&&(w.windowBits&15)===0&&(w.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new f,this.strm.avail_out=0;var b=i.inflateInit2(this.strm,w.windowBits);if(b!==l.Z_OK)throw new Error(c[b]);if(this.header=new m,i.inflateGetHeader(this.strm,this.header),w.dictionary&&(typeof w.dictionary=="string"?w.dictionary=u.string2buf(w.dictionary):g.call(w.dictionary)==="[object ArrayBuffer]"&&(w.dictionary=new Uint8Array(w.dictionary)),w.raw&&(b=i.inflateSetDictionary(this.strm,w.dictionary),b!==l.Z_OK)))throw new Error(c[b])}d.prototype.push=function(C,w){var b=this.strm,R=this.options.chunkSize,A=this.options.dictionary,T,_,P,N,q,H=!1;if(this.ended)return!1;_=w===~~w?w:w===!0?l.Z_FINISH:l.Z_NO_FLUSH,typeof C=="string"?b.input=u.binstring2buf(C):g.call(C)==="[object ArrayBuffer]"?b.input=new Uint8Array(C):b.input=C,b.next_in=0,b.avail_in=b.input.length;do{if(b.avail_out===0&&(b.output=new a.Buf8(R),b.next_out=0,b.avail_out=R),T=i.inflate(b,l.Z_NO_FLUSH),T===l.Z_NEED_DICT&&A&&(T=i.inflateSetDictionary(this.strm,A)),T===l.Z_BUF_ERROR&&H===!0&&(T=l.Z_OK,H=!1),T!==l.Z_STREAM_END&&T!==l.Z_OK)return this.onEnd(T),this.ended=!0,!1;b.next_out&&(b.avail_out===0||T===l.Z_STREAM_END||b.avail_in===0&&(_===l.Z_FINISH||_===l.Z_SYNC_FLUSH))&&(this.options.to==="string"?(P=u.utf8border(b.output,b.next_out),N=b.next_out-P,q=u.buf2string(b.output,P),b.next_out=N,b.avail_out=R-N,N&&a.arraySet(b.output,b.output,P,N,0),this.onData(q)):this.onData(a.shrinkBuf(b.output,b.next_out))),b.avail_in===0&&b.avail_out===0&&(H=!0)}while((b.avail_in>0||b.avail_out===0)&&T!==l.Z_STREAM_END);return T===l.Z_STREAM_END&&(_=l.Z_FINISH),_===l.Z_FINISH?(T=i.inflateEnd(this.strm),this.onEnd(T),this.ended=!0,T===l.Z_OK):(_===l.Z_SYNC_FLUSH&&(this.onEnd(l.Z_OK),b.avail_out=0),!0)},d.prototype.onData=function(C){this.chunks.push(C)},d.prototype.onEnd=function(C){C===l.Z_OK&&(this.options.to==="string"?this.result=this.chunks.join(""):this.result=a.flattenChunks(this.chunks)),this.chunks=[],this.err=C,this.msg=this.strm.msg};function v(C,w){var b=new d(w);if(b.push(C,!0),b.err)throw b.msg||c[b.err];return b.result}function x(C,w){return w=w||{},w.raw=!0,v(C,w)}s.Inflate=d,s.inflate=v,s.inflateRaw=x,s.ungzip=v},{"./utils/common":1,"./utils/strings":2,"./zlib/constants":4,"./zlib/gzheader":6,"./zlib/inflate":8,"./zlib/messages":10,"./zlib/zstream":11}]},{},[])("/lib/inflate.js")})();var TD=globalThis.fetch,oa=class{constructor(e,t={},r){this.type=e,this.detail=t,this.msg=r,Object.defineProperty(this,"__mayPropagate",{enumerable:!1,writable:!0}),this.__mayPropagate=!0}preventDefault(){}stopPropagation(){this.__mayPropagate=!1}valueOf(){return this}toString(){return this.msg?`[${this.type} event]: ${this.msg}`:`[${this.type} event]`}},Gx=class{constructor(){this.listeners={}}addEventListener(e,t,r){let o=this.listeners[e]||[];r?o.unshift(t):o.push(t),this.listeners[e]=o}removeEventListener(e,t){let r=this.listeners[e]||[],o=r.findIndex(n=>n===t);o>-1&&(r.splice(o,1),this.listeners[e]=r)}dispatch(e){let t=this.listeners[e.type];if(t)for(let r=0,o=t.length;rString.fromCharCode(t)).join("")}var Zx=class{constructor(e,t,r){this.name=(r||e.tag||"").trim(),this.length=e.length,this.start=e.offset,this.offset=0,this.data=t,["getInt8","getUint8","getInt16","getUint16","getInt32","getUint32","getBigInt64","getBigUint64"].forEach(o=>{let n=o.replace(/get(Big)?/,"").toLowerCase(),s=parseInt(o.replace(/[^\d]/g,""))/8;Object.defineProperty(this,n,{get:()=>this.getValue(o,s)})})}get currentPosition(){return this.start+this.offset}set currentPosition(e){this.start=e,this.offset=0}skip(e=0,t=8){this.offset+=e*t/8}getValue(e,t){let r=this.start+this.offset;this.offset+=t;try{return this.data[e](r)}catch(o){throw console.error("parser",e,t,this),console.error("parser",this.start,this.offset),o}}flags(e){if(e===8||e===16||e===32||e===64)return this[`uint${e}`].toString(2).padStart(e,0).split("").map(t=>t==="1");console.error("Error parsing flags: flag types can only be 1, 2, 4, or 8 bytes long"),console.trace()}get tag(){let e=this.uint32;return qx([e>>24&255,e>>16&255,e>>8&255,e&255])}get fixed(){let e=this.int16,t=Math.round(1e3*this.uint16/65356);return e+t/1e3}get legacyFixed(){let e=this.uint16,t=this.uint16.toString(16).padStart(4,0);return parseFloat(`${e}.${t}`)}get uint24(){return(this.uint8<<16)+(this.uint8<<8)+this.uint8}get uint128(){let e=0;for(let t=0;t<5;t++){let r=this.uint8;if(e=e*128+(r&127),r<128)break}return e}get longdatetime(){return new Date(Yx+1e3*parseInt(this.int64.toString()))}get fword(){return this.int16}get ufword(){return this.uint16}get Offset16(){return this.uint16}get Offset32(){return this.uint32}get F2DOT14(){let e=p.uint16,t=[0,1,-2,-1][e>>14],r=e&16383;return t+r/16384}verifyLength(){this.offset!=this.length&&console.error(`unexpected parsed table size (${this.offset}) for "${this.name}" (expected ${this.length})`)}readBytes(e=0,t=0,r=8,o=!1){if(e=e||this.length,e===0)return[];t&&(this.currentPosition=t);let n=`${o?"":"u"}int${r}`,s=[];for(;e--;)s.push(this[n]);return s}},ct=class{constructor(e){Object.defineProperty(this,"parser",{enumerable:!1,get:()=>e});let r=e.currentPosition;Object.defineProperty(this,"start",{enumerable:!1,get:()=>r})}load(e){Object.keys(e).forEach(t=>{let r=Object.getOwnPropertyDescriptor(e,t);r.get?this[t]=r.get.bind(this):r.value!==void 0&&(this[t]=r.value)}),this.parser.length&&this.parser.verifyLength()}},Pe=class extends ct{constructor(e,t,r){let{parser:o,start:n}=super(new Zx(e,t,r));Object.defineProperty(this,"p",{enumerable:!1,get:()=>o}),Object.defineProperty(this,"tableStart",{enumerable:!1,get:()=>n})}};function ae(e,t,r){let o;Object.defineProperty(e,t,{get:()=>o||(o=r(),o),enumerable:!0})}var Xx=class extends Pe{constructor(e,t,r){let{p:o}=super({offset:0,length:12},t,"sfnt");this.version=o.uint32,this.numTables=o.uint16,this.searchRange=o.uint16,this.entrySelector=o.uint16,this.rangeShift=o.uint16,o.verifyLength(),this.directory=[...new Array(this.numTables)].map(n=>new Kx(o)),this.tables={},this.directory.forEach(n=>{let s=()=>r(this.tables,{tag:n.tag,offset:n.offset,length:n.length},t);ae(this.tables,n.tag.trim(),s)})}},Kx=class{constructor(e){this.tag=e.tag,this.checksum=e.uint32,this.offset=e.uint32,this.length=e.uint32}},Kg=Xg.inflate||void 0,Jg=void 0,Jx=class extends Pe{constructor(e,t,r){let{p:o}=super({offset:0,length:44},t,"woff");this.signature=o.tag,this.flavor=o.uint32,this.length=o.uint32,this.numTables=o.uint16,o.uint16,this.totalSfntSize=o.uint32,this.majorVersion=o.uint16,this.minorVersion=o.uint16,this.metaOffset=o.uint32,this.metaLength=o.uint32,this.metaOrigLength=o.uint32,this.privOffset=o.uint32,this.privLength=o.uint32,o.verifyLength(),this.directory=[...new Array(this.numTables)].map(n=>new Qx(o)),$x(this,t,r)}},Qx=class{constructor(e){this.tag=e.tag,this.offset=e.uint32,this.compLength=e.uint32,this.origLength=e.uint32,this.origChecksum=e.uint32}};function $x(e,t,r){e.tables={},e.directory.forEach(o=>{ae(e.tables,o.tag.trim(),()=>{let n=0,s=t;if(o.compLength!==o.origLength){let i=t.buffer.slice(o.offset,o.offset+o.compLength),a;if(Kg)a=Kg(new Uint8Array(i));else if(Jg)a=Jg(new Uint8Array(i));else{let u="no brotli decoder available to decode WOFF2 font";throw font.onerror&&font.onerror(u),new Error(u)}s=new DataView(a.buffer)}else n=o.offset;return r(e.tables,{tag:o.tag,offset:n,length:o.origLength},s)})})}var Qg=Zg,$g=void 0,eS=class extends Pe{constructor(e,t,r){let{p:o}=super({offset:0,length:48},t,"woff2");this.signature=o.tag,this.flavor=o.uint32,this.length=o.uint32,this.numTables=o.uint16,o.uint16,this.totalSfntSize=o.uint32,this.totalCompressedSize=o.uint32,this.majorVersion=o.uint16,this.minorVersion=o.uint16,this.metaOffset=o.uint32,this.metaLength=o.uint32,this.metaOrigLength=o.uint32,this.privOffset=o.uint32,this.privLength=o.uint32,o.verifyLength(),this.directory=[...new Array(this.numTables)].map(a=>new tS(o));let n=o.currentPosition;this.directory[0].offset=0,this.directory.forEach((a,u)=>{let l=this.directory[u+1];l&&(l.offset=a.offset+(a.transformLength!==void 0?a.transformLength:a.origLength))});let s,i=t.buffer.slice(n);if(Qg)s=Qg(new Uint8Array(i));else if($g)s=new Uint8Array($g(i));else{let a="no brotli decoder available to decode WOFF2 font";throw e.onerror&&e.onerror(a),new Error(a)}rS(this,s,r)}},tS=class{constructor(e){this.flags=e.uint8;let t=this.tagNumber=this.flags&63;t===63?this.tag=e.tag:this.tag=oS(t);let o=(this.transformVersion=(this.flags&192)>>6)!==0;(this.tag==="glyf"||this.tag==="loca")&&(o=this.transformVersion!==3),this.origLength=e.uint128,o&&(this.transformLength=e.uint128)}};function rS(e,t,r){e.tables={},e.directory.forEach(o=>{ae(e.tables,o.tag.trim(),()=>{let n=o.offset,s=n+(o.transformLength?o.transformLength:o.origLength),i=new DataView(t.slice(n,s).buffer);try{return r(e.tables,{tag:o.tag,offset:0,length:o.origLength},i)}catch(a){console.error(a)}})})}function oS(e){return["cmap","head","hhea","hmtx","maxp","name","OS/2","post","cvt ","fpgm","glyf","loca","prep","CFF ","VORG","EBDT","EBLC","gasp","hdmx","kern","LTSH","PCLT","VDMX","vhea","vmtx","BASE","GDEF","GPOS","GSUB","EBSC","JSTF","MATH","CBDT","CBLC","COLR","CPAL","SVG ","sbix","acnt","avar","bdat","bloc","bsln","cvar","fdsc","feat","fmtx","fvar","gvar","hsty","just","lcar","mort","morx","opbd","prop","trak","Zapf","Silf","Glat","Gloc","Feat","Sill"][e&63]}var iy={},ay=!1;Promise.all([Promise.resolve().then(function(){return FS}),Promise.resolve().then(function(){return IS}),Promise.resolve().then(function(){return NS}),Promise.resolve().then(function(){return VS}),Promise.resolve().then(function(){return jS}),Promise.resolve().then(function(){return GS}),Promise.resolve().then(function(){return qS}),Promise.resolve().then(function(){return XS}),Promise.resolve().then(function(){return sC}),Promise.resolve().then(function(){return gC}),Promise.resolve().then(function(){return oR}),Promise.resolve().then(function(){return sR}),Promise.resolve().then(function(){return cR}),Promise.resolve().then(function(){return pR}),Promise.resolve().then(function(){return hR}),Promise.resolve().then(function(){return yR}),Promise.resolve().then(function(){return wR}),Promise.resolve().then(function(){return SR}),Promise.resolve().then(function(){return RR}),Promise.resolve().then(function(){return TR}),Promise.resolve().then(function(){return PR}),Promise.resolve().then(function(){return kR}),Promise.resolve().then(function(){return IR}),Promise.resolve().then(function(){return DR}),Promise.resolve().then(function(){return MR}),Promise.resolve().then(function(){return BR}),Promise.resolve().then(function(){return zR}),Promise.resolve().then(function(){return HR}),Promise.resolve().then(function(){return GR}),Promise.resolve().then(function(){return ZR}),Promise.resolve().then(function(){return eE}),Promise.resolve().then(function(){return nE}),Promise.resolve().then(function(){return aE}),Promise.resolve().then(function(){return fE}),Promise.resolve().then(function(){return pE}),Promise.resolve().then(function(){return hE}),Promise.resolve().then(function(){return vE}),Promise.resolve().then(function(){return wE}),Promise.resolve().then(function(){return EE}),Promise.resolve().then(function(){return _E}),Promise.resolve().then(function(){return kE})]).then(e=>{e.forEach(t=>{let r=Object.keys(t)[0];iy[r]=t[r]}),ay=!0});function nS(e,t,r){let o=t.tag.replace(/[^\w\d]/g,""),n=iy[o];return n?new n(t,r,e):(console.warn(`lib-font has no definition for ${o}. The table was skipped.`),{})}function sS(){let e=0;function t(r,o){if(!ay)return e>10?o(new Error("loading took too long")):(e++,setTimeout(()=>t(r),250));r(nS)}return new Promise((r,o)=>t(r))}function iS(e,t){let r=e.lastIndexOf("."),o=(e.substring(r+1)||"").toLowerCase(),n={ttf:"truetype",otf:"opentype",woff:"woff",woff2:"woff2"}[o];if(n)return n;let s={eot:"The .eot format is not supported: it died in January 12, 2016, when Microsoft retired all versions of IE that didn't already support WOFF.",svg:"The .svg format is not supported: SVG fonts (not to be confused with OpenType with embedded SVG) were so bad we took the entire fonts chapter out of the SVG specification again.",fon:"The .fon format is not supported: this is an ancient Windows bitmap font format.",ttc:"Based on the current CSS specification, font collections are not (yet?) supported."}[o];if(s||(s=`${e} is not a known webfont format.`),t)throw new Error(s);console.warn(`Could not load font: ${s}`)}async function aS(e,t,r={}){if(!globalThis.document)return;let o=iS(t,r.errorOnStyle);if(!o)return;let n=document.createElement("style");n.className="injected-by-Font-js";let s=[];return r.styleRules&&(s=Object.entries(r.styleRules).map(([i,a])=>`${i}: ${a};`)),n.textContent=` +`}var zh={mobile:"480px",tablet:"782px"},Hh=/^(\d+|\d*\.\d+)(px|em|rem)$/,fx=16;function dx(e){return"mobile"in e||"tablet"in e}function px(e){return!e||typeof e!="object"?{}:dx(e)?e:e.settings?.viewport??{}}function mx(e){return typeof e=="string"&&Hh.test(e.trim())}function Tc(e){if(typeof e=="number")return e;if(typeof e!="string")return;let t=e.trim().match(Hh);if(!t)return;let r=Number.parseFloat(t[1]);return t[2]==="px"?r:r*fx}function Pc(e){let t=px(e),r={},o={};Object.keys(zh).forEach(a=>{let u=a,l=t[u],c=Tc(l);c!==void 0&&mx(l)&&(r[u]=l.trim(),o[u]=c)});let n=Object.keys(r);if(!n.length)return{...zh};if(n.length===1)return r;let i=r.mobile,s=r.tablet;return o.mobile>=o.tablet?{mobile:i}:{mobile:i,tablet:s}}function Uh(e){let t=Pc(e),r={};return t.mobile&&(r["@mobile"]=`@media (width <= ${t.mobile})`),t.tablet&&(r["@tablet"]=t.mobile?`@media (${t.mobile} < width <= ${t.tablet})`:`@media (width <= ${t.tablet})`),r}function Bs(e,t,r,{resolveRefs:o=!0}={}){if(!e?.styles?.blocks?.[t]?.variations?.[r])return;let n=s=>{Object.keys(s).forEach(a=>{let u=s[a];if(typeof u=="object"&&u!==null)if(u.ref!==void 0)if(typeof u.ref!="string"||u.ref.trim()==="")delete s[a];else{let l=ht(e,u.ref);l!=null?s[a]=l:delete s[a]}else n(u),Object.keys(u).length===0&&delete s[a]})},i=JSON.parse(JSON.stringify(e.styles.blocks[t].variations[r]));return o&&n(i),i}var Fc="default";function qh(e){let t=e?.viewport,r=e?.pseudoState;return(!t||t===Fc)&&(!r||r===Fc)}function hx(e){return qh(e)?[]:[e.viewport,e.pseudoState].filter(t=>!!t&&t!==Fc)}function gx(e,t){let r=hx(t);return r.length?ht(e,r):e}var yx=new Set(["blocks","variations","css"]),Oc=Object.freeze({value:{},sources:{}}),vx={root:{layer:"root"},element:{layer:"element"},block:{layer:"block"},blockVariation:{layer:"blockVariation"}};function wo(e){let t=vx[e];return t?{...t}:null}function xo(e,t){return!e||!t?null:{styles:e,source:t}}function bx(e){return e.join(".")}function wx(e){return{...e}}function Zh(e){return e===""||e===null||typeof e=="object"&&!Array.isArray(e)&&Object.keys(e).length===0}function kc(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)&&typeof e.ref=="string"}function So(e){if(!e||typeof e!="object"||Array.isArray(e))return null;let t={};for(let r of Object.keys(e))if(!yx.has(r)){if(r==="elements"){e.elements&&typeof e.elements=="object"&&(t.elements=e.elements);continue}Zh(e[r])||(t[r]=e[r])}return Object.keys(t).length===0?null:t}var Wh=new Set(["backgroundImage"]);function Xh(e,t,r,o,n,i=[]){if(!t||typeof t!="object"||Array.isArray(t))return e;for(let s of Object.keys(t)){let a=t[s];if(Zh(a))continue;if(kc(a)){if(a.ref.trim()==="")continue;let l=ht(r,a.ref);if(l==null||kc(l))continue;a=l}let u=[...i,s];if(!Wh.has(s)&&a!==null&&typeof a=="object"&&!Array.isArray(a)&&!kc(a)){let l=e[s]&&typeof e[s]=="object"&&!Array.isArray(e[s])?e[s]:{};e[s]=Xh({...l},a,r,o,n,u)}else e[s]=Wh.has(s)&&a!==null&&typeof a=="object"&&!Array.isArray(a)?{...a}:a,o&&n&&(n[bx(u)]=wx(o))}return e}function js(e,t){if(!e)return null;let r=gx(e,t);return r&&typeof r=="object"&&!Array.isArray(r)?r:null}var xx=["color.background","color.gradient","background","spacing","dimensions","border","shadow","filter"];function Sx(e){return e.startsWith("elements.")?!1:xx.some(t=>e===t||e.startsWith(`${t}.`))}function Kh(e,t){if(!e||typeof e!="object")return;let[r,...o]=t;if(o.length===0){delete e[r];return}let n=e[r];n&&typeof n=="object"&&(Kh(n,o),Object.keys(n).length===0&&delete e[r])}function Cx(e,t){for(let r of Object.keys(t))t[r].layer==="root"&&Sx(r)&&(Kh(e,r.split(".")),delete t[r])}function _x(e,t,r){let o=e?.background?.backgroundImage;if(!o)return;let n=gh(o,{...t,_links:r??void 0});n!==void 0&&(e.background.backgroundImage=n)}function Gh(e,{blockName:t,variationName:r=null,elements:o=null,viewport:n=null,pseudoState:i=null}={}){if(!e||!e.styles||!t)return Oc;let s=e.styles,a={viewport:n,pseudoState:i},u=s,l=s.blocks?.[t]??null,c=(o??[]).map(w=>s.elements?.[w]??null).filter(w=>!!w),m=r?Bs(e,t,r)??null:null,d=[xo(So(u),wo("root")),...c.map(w=>xo(So(w),wo("element"))),l?xo(So(l),wo("block")):null,m?xo(So(m),wo("blockVariation")):null];qh(a)||d.push(xo(So(js(u,a)),wo("root")),...c.map(w=>xo(So(js(w,a)),wo("element"))),l?xo(So(js(l,a)),wo("block")):null,m?xo(So(js(m,a)),wo("blockVariation")):null);let h=d.filter(Boolean);if(h.length===0)return Oc;let g={},b=h.reduce((w,C)=>Xh(w,C.styles,e,C.source,g),{});return Cx(b,g),_x(b,e,e._links??null),{value:b,sources:g}}var Rx={},Yh=new WeakMap;function Jh(e,t={}){let r=e?.styles;if(!r||typeof r!="object")return Gh(e,t);let o=Yh.get(r);o||(o=new WeakMap,Yh.set(r,o));let n=e?._links??Rx,i=o.get(n);i||(i=new Map,o.set(n,i));let s=`${t.elements?.join(",")??""}:${t.viewport??""}:${t.pseudoState??""}`,a=(t.blockName||"")+""+(t.variationName||"")+""+s;if(i.has(a))return i.get(a);let u=Gh(e,t);return i.set(a,u),u}var Qh=f(li(),1),{lock:$h,unlock:vI}=(0,Qh.__dangerousOptInToUnstableAPIsOnlyForCoreModules)("I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.","@wordpress/global-styles-engine");var Tn={};$h(Tn,{getResponsiveMediaQueries:Uh,getViewportBreakpoints:Pc,getViewportBreakpointValueInPixels:Tc,getDuotoneFilter:jh,getDuotoneStylesheet:Bh,getDuotoneUnsetStylesheet:Dh,resolveStyle:Jh,getVariationStyle:Bs});var Ac=f(Te(),1);var eg=f(Te(),1),gt=(0,eg.createContext)({user:{styles:{},settings:{}},base:{styles:{},settings:{}},merged:{styles:{},settings:{}},onChange:()=>{},fontLibraryEnabled:!1});var tg=f(Z(),1);function gi({children:e,value:t,baseValue:r,onChange:o,fontLibraryEnabled:n}){let i=(0,Ac.useMemo)(()=>Go(r,t),[r,t]),s=(0,Ac.useMemo)(()=>({user:t,base:r,merged:i,onChange:o,fontLibraryEnabled:n}),[t,r,i,o,n]);return(0,tg.jsx)(gt.Provider,{value:s,children:e})}var eo=f(ue(),1),bg=f(ge(),1);var Bx=f(Kt(),1),jx=f(sr(),1);var rg=f(Z(),1);function Ic({className:e,...t}){return(0,rg.jsx)(ai,{className:We(e,"global-styles-ui-icon-with-current-color"),...t})}var Co=f(ue(),1);var Yo=f(Z(),1);function Ex({icon:e,children:t,...r}){return(0,Yo.jsxs)(Co.__experimentalItem,{...r,children:[e&&(0,Yo.jsxs)(Co.__experimentalHStack,{justify:"flex-start",children:[(0,Yo.jsx)(Ic,{icon:e,size:24}),(0,Yo.jsx)(Co.FlexItem,{children:t})]}),!e&&t]})}function Qr(e){return(0,Yo.jsx)(Co.Navigator.Button,{as:Ex,...e})}var Ox=f(ue(),1);var kx=f(ge(),1),cg=f(Dt(),1);var Lc=function(e){var t=e/255;return t<.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)},Nc=function(e){return .2126*Lc(e.r)+.7152*Lc(e.g)+.0722*Lc(e.b)};function og(e){e.prototype.luminance=function(){return t=Nc(this.rgba),(r=2)===void 0&&(r=0),o===void 0&&(o=Math.pow(10,r)),Math.round(o*t)/o+0;var t,r,o},e.prototype.contrast=function(t){t===void 0&&(t="#FFF");var r,o,n,i,s,a,u,l=t instanceof e?t:new e(t);return i=this.rgba,s=l.toRgb(),a=Nc(i),u=Nc(s),r=a>u?(a+.05)/(u+.05):(u+.05)/(a+.05),(o=2)===void 0&&(o=0),n===void 0&&(n=Math.pow(10,o)),Math.floor(n*r)/n+0},e.prototype.isReadable=function(t,r){return t===void 0&&(t="#FFF"),r===void 0&&(r={}),this.contrast(t)>=(a=(s=(o=r).size)===void 0?"normal":s,(i=(n=o.level)===void 0?"AA":n)==="AAA"&&a==="normal"?7:i==="AA"&&a==="large"?3:4.5);var o,n,i,s,a}}var Rr=f(Te(),1),ag=f(Kt(),1),lg=f(sr(),1),Vc=f(ge(),1);var dt=f(ge(),1);var ng=f(li(),1),{lock:WI,unlock:Ve}=(0,ng.__dangerousOptInToUnstableAPIsOnlyForCoreModules)("I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.","@wordpress/global-styles-ui");var{getViewportBreakpoints:ZI}=Ve(Tn),XI={link:[{value:":link",label:(0,dt.__)("Link")},{value:":any-link",label:(0,dt.__)("Any Link")},{value:":visited",label:(0,dt.__)("Visited")},{value:":hover",label:(0,dt.__)("Hover")},{value:":focus",label:(0,dt.__)("Focus")},{value:":focus-visible",label:(0,dt.__)("Focus-visible")},{value:":active",label:(0,dt.__)("Active")}],button:[{value:":link",label:(0,dt.__)("Link")},{value:":any-link",label:(0,dt.__)("Any Link")},{value:":visited",label:(0,dt.__)("Visited")},{value:":hover",label:(0,dt.__)("Hover")},{value:":focus",label:(0,dt.__)("Focus")},{value:":focus-visible",label:(0,dt.__)("Focus-visible")},{value:":active",label:(0,dt.__)("Active")}]},KI={"core/button":[{value:":hover",label:(0,dt.__)("Hover")},{value:":focus",label:(0,dt.__)("Focus")},{value:":focus-visible",label:(0,dt.__)("Focus-visible")},{value:":active",label:(0,dt.__)("Active")}]},JI=[{value:"@tablet",label:(0,dt.__)("Tablet")},{value:"@mobile",label:(0,dt.__)("Mobile")}];function Mc(e,t){if(!t?.length||typeof e!="object"||!e||!Object.keys(e).length)return e;for(let r in e)t.includes(r)?delete e[r]:typeof e[r]=="object"&&Mc(e[r],t);return e}var zs=(e,t)=>{if(!e||!t?.length)return{};let r={};return Object.keys(e).forEach(o=>{if(t.includes(o))r[o]=e[o];else if(typeof e[o]=="object"){let n=zs(e[o],t);Object.keys(n).length&&(r[o]=n)}}),r};function yi(e,t){let r=zs(structuredClone(e),t);return pi(r,e)}function ig(e,t){if(!Array.isArray(e)||!t)return null;let o=t.replace("var(","").replace(")","")?.split("--").slice(-1)[0];return e.find(n=>n.slug===o)}function sg(e){let t=e?.settings?.typography?.fontFamilies?.theme,r=e?.settings?.typography?.fontFamilies?.custom,o=[];t&&r?o=[...t,...r]:t?o=t:r&&(o=r);let n=e?.styles?.typography?.fontFamily,i=ig(o,n),s=e?.styles?.elements?.heading?.typography?.fontFamily,a;return s?a=ig(o,e?.styles?.elements?.heading?.typography?.fontFamily):a=i,[i,a]}Vh([og]);function qe(e,t,r="merged",o=!0,n){let{user:i,base:s,merged:a,onChange:u}=(0,Rr.useContext)(gt),l=n?.split(".").filter(Boolean)??[],c=l.find(w=>w.startsWith(":")),m=l.filter(w=>!w.startsWith(":")).join("."),d=[e,m].filter(Boolean).join("."),h=a;r==="base"?h=s:r==="user"&&(h=i);let g=(0,Rr.useMemo)(()=>{let w=Vs(h,d,t,o);return c?w?.[c]??{}:w},[h,d,t,o,c]),b=(0,Rr.useCallback)(w=>{let C=w;c&&(C={...Vs(i,d,t,!1),[c]:w});let x=wc(i,d,C,t);u(x)},[i,u,d,t,c]);return[g,b]}function Ke(e,t,r="merged"){let{user:o,base:n,merged:i,onChange:s}=(0,Rr.useContext)(gt),a=i;r==="base"?a=n:r==="user"&&(a=o);let u=(0,Rr.useMemo)(()=>yc(a,e,t),[a,e,t]),l=(0,Rr.useCallback)(c=>{let m=vc(o,e,c,t);s(m)},[o,s,e,t]);return[u,l]}var Tx=[];function Px({title:e,settings:t,styles:r}){return e===(0,Vc.__)("Default")||Object.keys(t||{}).length>0||Object.keys(r||{}).length>0}function Hs(e=[]){let{variationsFromTheme:t}=(0,ag.useSelect)(o=>({variationsFromTheme:o(lg.store).__experimentalGetCurrentThemeGlobalStylesVariations?.()||Tx}),[]),{user:r}=(0,Rr.useContext)(gt);return(0,Rr.useMemo)(()=>{let o=structuredClone(r),n=Mc(o,e);n.title=(0,Vc.__)("Default");let i=t.filter(a=>yi(a,e)).map(a=>Go(n,a)),s=[n,...i];return s?.length?s.filter(Px):[]},[e,r,t])}var Dc=f(Z(),1),{useHasDimensionsPanel:lL,useHasTypographyPanel:cL,useHasColorPanel:uL,useSettingsForBlockElement:fL,useHasBackgroundPanel:dL}=Ve(cg.privateApis);var zr=f(ue(),1);function Pn(){let[e="black"]=qe("color.text"),[t="white"]=qe("color.background"),[r=e]=qe("elements.h1.color.text"),[o=r]=qe("elements.link.color.text"),[n=o]=qe("elements.button.color.background"),[i]=Ke("color.palette.core")||[],[s]=Ke("color.palette.theme")||[],[a]=Ke("color.palette.custom")||[],u=(s??[]).concat(a??[]).concat(i??[]),l=u.filter(({color:d})=>d===e),c=u.filter(({color:d})=>d===n),m=l.concat(c).concat(u).filter(({color:d})=>d!==t).slice(0,2);return{paletteColors:u,highlightedColors:m}}var pg=f(Te(),1),mg=f(ue(),1),zc=f(ge(),1);function Fx(e,t){return t.length===0?null:(t.sort((r,o)=>Math.abs(e-r)-Math.abs(e-o)),t[0])}var Ax={normal:400,bold:700};function ug(e){return e!==void 0&&Number.isFinite(e)&&e>=1&&e<=1e3}function Bc(e){let t=String(e??"").trim().toLowerCase().split(/\s+/).filter(Boolean).map(n=>Ax[n]??Number(n)),[r,o]=t;return ug(r)?t.length!==2||!ug(o)?String(r):String(Math.min(Math.max(400,r),o)):"400"}function fg(e){let t=/^(?!generic\([ a-zA-Z\-]+\)$)(?!^[a-zA-Z\-]+$).+/,r=e.trim(),o=n=>(n=n.trim(),n.match(t)?(n=n.replace(/^["']|["']$/g,""),`"${n}"`):n);return r.includes(",")?r.split(",").map(o).filter(n=>n!=="").join(", "):o(r)}function jc(e){if(!e)return"";let t=e.trim();return t.includes(",")&&(t=(t.split(",").find(r=>r.trim()!=="")??"").trim()),t=t.replace(/^["']|["']$/g,""),window.navigator.userAgent.toLowerCase().includes("firefox")&&(t=`"${t}"`),t}function On(e){let t={fontFamily:fg(e.fontFamily)};if(!("fontFace"in e)||!Array.isArray(e.fontFace))return t.fontWeight="400",t.fontStyle="normal",t;if(e.fontFace){let r=e.fontFace.filter(o=>o?.fontStyle&&o.fontStyle.toLowerCase()==="normal");if(r.length>0){t.fontStyle="normal";let o=r.map(n=>Number(Bc(n.fontWeight)));t.fontWeight=String(Fx(400,o)??400)}else t.fontStyle=e.fontFace.length&&e.fontFace[0].fontStyle||"normal",t.fontWeight=e.fontFace.length&&Bc(e.fontFace[0].fontWeight)||"400"}return t}function dg(e){return{fontFamily:fg(e.fontFamily),fontStyle:e.fontStyle||"normal",fontWeight:Bc(e.fontWeight)}}var vi=f(Z(),1);function Us({fontSize:e,variation:t}){let{base:r}=(0,pg.useContext)(gt),o=r;t&&(o={...r,...t});let[n]=qe("color.text"),[i,s]=sg(o),a=i?On(i):{},u=s?On(s):{};return n&&(a.color=n,u.color=n),e&&(a.fontSize=e,u.fontSize=e),(0,vi.jsxs)(mg.__unstableMotion.div,{animate:{scale:1,opacity:1},initial:{scale:.1,opacity:0},transition:{delay:.3,type:"tween"},style:{textAlign:"center",lineHeight:1},children:[(0,vi.jsx)("span",{style:u,children:(0,zc._x)("A","Uppercase letter A")}),(0,vi.jsx)("span",{style:a,children:(0,zc._x)("a","Lowercase letter A")})]})}var hg=f(ue(),1);var gg=f(Z(),1);function yg({normalizedColorSwatchSize:e,ratio:t}){let{highlightedColors:r}=Pn(),o=e*t;return r.map(({slug:n,color:i},s)=>(0,gg.jsx)(hg.__unstableMotion.div,{style:{height:o,width:o,background:i,borderRadius:o/2},animate:{scale:1,opacity:1},initial:{scale:.1,opacity:0},transition:{delay:s===1?.2:.1}},`${n}-${s}`))}var vg=f(ue(),1),kn=f(yo(),1),qo=f(Te(),1);var $r=f(Z(),1),Hc=248,Uc=152,Ix={leading:!0,trailing:!0};function Lx({children:e,label:t,isFocused:r,withHoverView:o}){let[n="white"]=qe("color.background"),[i]=qe("color.gradient"),s=(0,kn.useReducedMotion)(),[a,u]=(0,qo.useState)(!1),[l,{width:c}]=(0,kn.useResizeObserver)(),[m,d]=(0,qo.useState)(c),[h,g]=(0,qo.useState)(),b=(0,kn.useThrottle)(d,250,Ix);(0,qo.useLayoutEffect)(()=>{c&&b(c)},[c,b]),(0,qo.useLayoutEffect)(()=>{let v=m?m/Hc:1,_=v-(h||0);(Math.abs(_)>.1||!h)&&g(v)},[m,h]);let w=c?c/Hc:1,C=h||w,x=!!c;return(0,$r.jsxs)($r.Fragment,{children:[(0,$r.jsx)("div",{style:{position:"relative"},children:l}),!x&&(0,$r.jsx)(ui,{className:"global-styles-ui-preview__wrapper",style:{aspectRatio:Hc/Uc}}),x&&(0,$r.jsx)("div",{className:We("global-styles-ui-preview__wrapper",{"is-hoverable":o}),style:{height:Uc*C},onMouseEnter:()=>u(!0),onMouseLeave:()=>u(!1),tabIndex:-1,children:(0,$r.jsx)(vg.__unstableMotion.div,{style:{height:Uc*C,width:"100%",background:i??n},initial:"start",animate:(a||r)&&!s&&t?"hover":"start",children:[].concat(e).map((v,_)=>v({ratio:C,key:_}))})})]})}var Fn=Lx;var Jt=f(Z(),1),Nx={start:{scale:1,opacity:1},hover:{scale:0,opacity:0}},Mx={hover:{opacity:1},start:{opacity:.5}},Vx={hover:{scale:1,opacity:1},start:{scale:0,opacity:0}};function Dx({label:e,isFocused:t,withHoverView:r,variation:o}){let[n]=qe("typography.fontWeight"),[i="serif"]=qe("typography.fontFamily"),[s=i]=qe("elements.h1.typography.fontFamily"),[a=n]=qe("elements.h1.typography.fontWeight"),[u="black"]=qe("color.text"),[l=u]=qe("elements.h1.color.text"),{paletteColors:c}=Pn();return(0,Jt.jsxs)(Fn,{label:e,isFocused:t,withHoverView:r,children:[({ratio:m,key:d})=>(0,Jt.jsx)(zr.__unstableMotion.div,{variants:Nx,style:{height:"100%",overflow:"hidden"},children:(0,Jt.jsxs)(zr.__experimentalHStack,{spacing:10*m,justify:"center",style:{height:"100%",overflow:"hidden"},children:[(0,Jt.jsx)(Us,{fontSize:65*m,variation:o}),(0,Jt.jsx)(zr.__experimentalVStack,{spacing:4*m,children:(0,Jt.jsx)(yg,{normalizedColorSwatchSize:32,ratio:m})})]})},d),({key:m})=>(0,Jt.jsx)(zr.__unstableMotion.div,{variants:r?Mx:void 0,style:{height:"100%",width:"100%",position:"absolute",top:0,overflow:"hidden",filter:"blur(60px)",opacity:.1},children:(0,Jt.jsx)(zr.__experimentalHStack,{spacing:0,justify:"flex-start",style:{height:"100%",overflow:"hidden"},children:c.slice(0,4).map(({color:d},h)=>(0,Jt.jsx)("div",{style:{height:"100%",background:d,flexGrow:1}},h))})},m),({ratio:m,key:d})=>(0,Jt.jsx)(zr.__unstableMotion.div,{variants:Vx,style:{height:"100%",width:"100%",overflow:"hidden",position:"absolute",top:0},children:(0,Jt.jsx)(zr.__experimentalVStack,{spacing:3*m,justify:"center",style:{height:"100%",overflow:"hidden",padding:10*m,boxSizing:"border-box"},children:e&&(0,Jt.jsx)("div",{style:{fontSize:40*m,fontFamily:s,color:l,fontWeight:a,lineHeight:"1em",textAlign:"center"},children:e})})},d)]})}var Wc=Dx;var wg=f(Z(),1);var qc=f(_n(),1),Ro=f(ge(),1),Hr=f(ue(),1);var Zc=f(Kt(),1),pr=f(Te(),1),Ws=f(Dt(),1),Eg=f(yo(),1);import{speak as Wx}from"@wordpress/a11y";var xg=f(_n(),1),Sg=f(Kt(),1),zx=f(ue(),1);var Hx=f(Z(),1);function Ux(e,t){return e?.filter(r=>r.source==="block"||t.includes(r.name))||[]}function Gc(e){let t=(0,Sg.useSelect)(n=>{let{getBlockStyles:i}=n(xg.store);return i(e)},[e]),[r]=qe("variations",e),o=Object.keys(r??{});return Ux(t,o)}var _o=f(ue(),1),Cg=f(ge(),1);var _g=f(Dt(),1);var Rg=f(Z(),1),{StateControl:WL,StateControlBadges:GL}=Ve(_g.privateApis);var Bt=f(Z(),1),{useHasDimensionsPanel:Gx,useHasTypographyPanel:Yx,useHasBorderPanel:qx,useSettingsForBlockElement:Zx,useHasColorPanel:Xx,useHasBackgroundPanel:Kx}=Ve(Ws.privateApis),{Menu:tN}=Ve(Hr.privateApis);function Yc(e){return e==null?!1:Array.isArray(e)?e.length>0:typeof e=="object"?Object.values(e).some(Yc):!0}function Jx(e,t){return Yc(e?.styles?.blocks?.[t])||Yc(e?.settings?.blocks?.[t])}function Qx(){let e=(0,Zc.useSelect)(n=>n(qc.store).getBlockTypes(),[]),t=(n,i)=>{let{core:s,noncore:a}=n;return(i.name.startsWith("core/")?s:a).push(i),n},{core:r,noncore:o}=e.reduce(t,{core:[],noncore:[]});return[...r,...o]}function $x(e){let[t]=Ke("",e),r=Zx(t,e),o=Yx(r),n=Xx(r),i=Kx(r),s=qx(r),a=Gx(r),u=s||a,l=!!Gc(e)?.length;return o||n||i||u||l}function eS({block:e,isCustomized:t}){return $x(e.name)?(0,Bt.jsx)(Qr,{path:"/blocks/"+encodeURIComponent(e.name),children:(0,Bt.jsxs)(Hr.__experimentalHStack,{justify:"flex-start",spacing:2,children:[(0,Bt.jsx)(Ws.BlockIcon,{className:"global-styles-ui-block-types-item__icon",icon:e.icon}),(0,Bt.jsx)(Hr.FlexItem,{children:e.title}),t&&(0,Bt.jsxs)(Bt.Fragment,{children:[(0,Bt.jsx)(ec,{children:(0,Ro.__)("Has custom styles")}),(0,Bt.jsx)("span",{"aria-hidden":"true",className:"global-styles-ui-block-types-item__indicator"})]})]})}):null}function tS({filterValue:e,styleFilter:t}){let r=t==="customized"&&!e?(0,Ro.__)("You haven't customized any blocks yet."):(0,Ro.__)("No blocks found.");return(0,Bt.jsx)(Hr.__experimentalText,{align:"center",as:"p",className:"global-styles-ui-block-types-item-list__no-results",children:r})}function rS({filterValue:e,styleFilter:t}){let r=Qx(),o=(0,Eg.useDebounce)(Wx,500),{isMatchingSearchTerm:n}=(0,Zc.useSelect)(qc.store),{user:i}=(0,pr.useContext)(gt),s=(0,pr.useMemo)(()=>{let m=new Set;return[...Object.keys(i?.styles?.blocks??{}),...Object.keys(i?.settings?.blocks??{})].forEach(h=>{Jx(i,h)&&m.add(h)}),m},[i]),a=e?r.filter(m=>n(m,e)):r,u=t==="customized"?a.filter(m=>s.has(m.name)):a,l=(0,pr.useRef)(null),c=u.length>0;return(0,pr.useEffect)(()=>{if(!e&&t==="all")return;let m=c&&l.current?.childElementCount||0,d=(0,Ro.sprintf)((0,Ro._n)("%d result found.","%d results found.",m),m);o(d,"polite")},[e,t,c,o]),(0,Bt.jsx)("div",{ref:l,className:"global-styles-ui-block-types-item-list",role:"list",children:u.length===0?(0,Bt.jsx)(tS,{filterValue:e,styleFilter:t}):u.map(m=>(0,Bt.jsx)(eS,{block:m,isCustomized:s.has(m.name)},"menu-itemblock-"+m.name))})}var rN=(0,pr.memo)(rS);var aS=f(_n(),1),kg=f(Dt(),1),Xc=f(Te(),1),lS=f(Kt(),1),cS=f(sr(),1),Kc=f(ue(),1),Fg=f(ge(),1);var oS=f(Dt(),1),Tg=f(_n(),1),nS=f(ue(),1),iS=f(Te(),1);var sS=f(Z(),1),{getViewportBreakpoints:cN,getViewportBreakpointValueInPixels:uN}=Ve(Tn);var Pg=f(ue(),1),Og=f(Z(),1);function Er({children:e,level:t=2}){return(0,Og.jsx)(Pg.__experimentalHeading,{className:"global-styles-ui-subtitle",level:t,children:e})}var Jc=f(Z(),1);var{useHasDimensionsPanel:RN,useHasTypographyPanel:EN,useHasBorderPanel:TN,useSettingsForBlockElement:PN,useHasColorPanel:ON,useHasFiltersPanel:kN,useHasImageSettingsPanel:FN,useHasBackgroundPanel:AN,BackgroundPanel:IN,BorderPanel:LN,ColorPanel:NN,TypographyPanel:MN,DimensionsPanel:VN,FiltersPanel:DN,ImageSettingsPanel:BN,AdvancedPanel:jN}=Ve(kg.privateApis);var S2=f(ge(),1),C2=f(ue(),1),_2=f(Te(),1);var uS=f(ue(),1);var fS=f(Z(),1);var dS=f(ge(),1),Gs=f(ue(),1);var Ag=f(Z(),1);var Zs=f(ue(),1);var Ig=f(ue(),1);var Ys=f(Z(),1),pS=({variation:e,isFocused:t,withHoverView:r})=>(0,Ys.jsx)(Fn,{label:e.title,isFocused:t,withHoverView:r,children:({ratio:o,key:n})=>(0,Ys.jsx)(Ig.__experimentalHStack,{spacing:10*o,justify:"center",style:{height:"100%",overflow:"hidden"},children:(0,Ys.jsx)(Us,{variation:e,fontSize:85*o})},n)}),Lg=pS;var Zo=f(Te(),1),Mg=f(Qc(),1),qs=f(ge(),1);var Eo=f(Z(),1);function An({variation:e,children:t,isPill:r=!1,properties:o,showTooltip:n=!1}){let[i,s]=(0,Zo.useState)(!1),{base:a,user:u,onChange:l}=(0,Zo.useContext)(gt),c=(0,Zo.useMemo)(()=>{let w=Go(a,e);return o&&(w=zs(w,o)),{user:e,base:a,merged:w,onChange:()=>{}}},[e,a,o]),m=()=>l(e),d=w=>{w.keyCode===Mg.ENTER&&(w.preventDefault(),m())},h=(0,Zo.useMemo)(()=>pi(u,e),[u,e]),g=e?.title;e?.description&&(g=(0,qs.sprintf)((0,qs._x)("%1$s (%2$s)","variation label"),e?.title,e?.description));let b=(0,Eo.jsx)("div",{className:We("global-styles-ui-variations_item",{"is-active":h}),role:"button",onClick:m,onKeyDown:d,tabIndex:0,"aria-label":g,"aria-current":h,onFocus:()=>s(!0),onBlur:()=>s(!1),children:(0,Eo.jsx)("div",{className:We("global-styles-ui-variations_item-preview",{"is-pill":r}),children:t(i)})});return(0,Eo.jsx)(gt.Provider,{value:c,children:n?(0,Eo.jsxs)(Sn.Root,{children:[(0,Eo.jsx)(Sn.Trigger,{render:b}),(0,Eo.jsx)(Sn.Popup,{children:e?.title})]}):b})}var Xo=f(Z(),1),Vg=["typography"];function Xs({title:e,gap:t=2}){let r=Hs(Vg);return r?.length<=1?null:(0,Xo.jsxs)(Zs.__experimentalVStack,{spacing:3,children:[e&&(0,Xo.jsx)(Er,{level:3,children:e}),(0,Xo.jsx)(Zs.__experimentalGrid,{columns:3,gap:t,className:"global-styles-ui-style-variations-container",children:r.map((o,n)=>(0,Xo.jsx)(An,{variation:o,properties:Vg,showTooltip:!0,children:()=>(0,Xo.jsx)(Lg,{variation:o})},n))})]})}var w2=f(ge(),1),Ri=f(ue(),1);var x2=f(Te(),1);var to=f(Te(),1),ko=f(Kt(),1),Oo=f(sr(),1),ru=f(ge(),1);var $c=f(Bg(),1),jg=f(sr(),1),zg="/wp/v2/font-families";function Hg(e){let{receiveEntityRecords:t}=e.dispatch(jg.store);t("postType","wp_font_family",[],void 0,!0)}async function Ug(e,t){let o=await(0,$c.default)({path:zg,method:"POST",body:e});return Hg(t),{id:o.id,...o.font_family_settings,fontFace:[]}}async function Wg(e,t,r){let o={path:`${zg}/${e}/font-faces`,method:"POST",body:t},n=await(0,$c.default)(o);return Hg(r),{id:n.id,...n.font_face_settings}}var In=function(){return In=Object.assign||function(t){for(var r,o=1,n=arguments.length;o{o.forEach(n=>{n.family===jc(e?.fontFamily)&&n.weight===e?.fontWeight&&n.style===e?.fontStyle&&o.delete(n)})};if((t==="document"||t==="all")&&r(document.fonts),t==="iframe"||t==="all"){let o=document.querySelector('iframe[name="editor-canvas"]');o?.contentDocument&&r(o.contentDocument.fonts)}}function Ln(e){if(!e)return;let t;if(Array.isArray(e)?t=e[0]:t=e,!t.startsWith("file:."))return gS(t)||(t=encodeURI(t)),t}function ey(e){let t=new FormData,{fontFace:r,category:o,...n}=e,i={...n,slug:Ks(e.slug)};return t.append("font_family_settings",JSON.stringify(i)),t}function ty(e){return(e?.fontFace??[]).map((r,o)=>{let n={...r},i=new FormData;if(n.file){let s=Array.isArray(n.file)?n.file:[n.file],a=[];s.forEach((u,l)=>{let c=`file-${o}-${l}`;i.append(c,u,u.name),a.push(c)}),n.src=a.length===1?a[0]:a,delete n.file,i.append("font_face_settings",JSON.stringify(n))}else i.append("font_face_settings",JSON.stringify(n));return i})}async function ry(e,t,r){let o=[];for(let i of t)try{let s=await Wg(e,i,r);o.push({status:"fulfilled",value:s})}catch(s){o.push({status:"rejected",reason:s})}let n={errors:[],successes:[]};return o.forEach((i,s)=>{if(i.status==="fulfilled"&&i.value){let a=i.value;n.successes.push(a)}else i.reason&&n.errors.push({data:t[s],message:i.reason.message})}),n}async function oy(e){e=Array.isArray(e)?e:[e];let t=await Promise.all(e.map(async r=>fetch(new Request(r)).then(o=>{if(!o.ok)throw new Error(`Error downloading font face asset from ${r}. Server responded with status: ${o.status}`);return o.blob()}).then(o=>{let n=r.split("/").pop();return new Qg([o],n,{type:o.type})})));return t.length===1?t[0]:t}function tu(e,t){return t.findIndex(r=>r.fontWeight===e.fontWeight&&r.fontStyle===e.fontStyle)!==-1}function ny(e,t,r){t=Array.isArray(t)?[...t]:[t],e=Array.isArray(e)?[...e]:{...e};let o=t.pop(),n=e;for(let i of t){let s=n[i];n=n[i]=Array.isArray(s)?[...s]:{...s}}return n[o]=r,e}function Qs(e,t,r=[]){let o=u=>u.slug===e.slug,n=u=>u.find(o),i=u=>u?r.filter(l=>!o(l)):[...r,e],s=u=>{let l=m=>m.fontWeight===t.fontWeight&&m.fontStyle===t.fontStyle;if(!u)return[...r,{...e,fontFace:[t]}];let c=u.fontFace||[];return c.find(l)?c=c.filter(m=>!l(m)):c=[...c,t],c.length===0?r.filter(m=>!o(m)):r.map(m=>o(m)?{...m,fontFace:c}:m)},a=n(r);return t?s(a):i(a)}var iy=f(Z(),1),jt=(0,to.createContext)({});jt.displayName="FontLibraryContext";function vS({children:e}){let t=(0,ko.useRegistry)(),{saveEntityRecord:r,deleteEntityRecord:o}=(0,ko.useDispatch)(Oo.store),{globalStylesId:n}=(0,ko.useSelect)(R=>{let{__experimentalGetCurrentGlobalStylesId:B}=R(Oo.store);return{globalStylesId:B()}},[]),i=(0,Oo.useEntityRecord)("root","globalStyles",n),[s,a]=(0,to.useState)(!1),{records:u=[],isResolving:l}=(0,Oo.useEntityRecords)("postType","wp_font_family",{_embed:!0}),c=(u||[]).map(R=>({id:R.id,...R.font_family_settings||{},fontFace:R?._embedded?.font_faces?.map(B=>B.font_face_settings)||[]}))||[],[m,d]=Ke("typography.fontFamilies"),h=async R=>{if(!i.record)return;let B=i.record,re=ny(B??{},["settings","typography","fontFamilies"],R);await r("root","globalStyles",re)},[g,b]=(0,to.useState)(""),[w,C]=(0,to.useState)(void 0),x=m?.theme?m.theme.map(R=>To(R,{source:"theme"})).sort((R,B)=>R.name.localeCompare(B.name)):[],v=m?.custom?m.custom.map(R=>To(R,{source:"custom"})).sort((R,B)=>R.name.localeCompare(B.name)):[],_=c?c.map(R=>To(R,{source:"custom"})).sort((R,B)=>R.name.localeCompare(B.name)):[];(0,to.useEffect)(()=>{g||C(void 0)},[g]);let k=R=>{if(!R){C(void 0);return}let re=(R.source==="theme"?x:_).find(P=>P.slug===R.slug);C({...re||R,source:R.source})},[E]=(0,to.useState)(new Set),T=R=>R.reduce((re,P)=>{let W=P?.fontFace&&P.fontFace?.length>0?P?.fontFace.map(ne=>`${ne.fontStyle??""}${ne.fontWeight??""}`):["normal400"];return re[P.slug]=W,re},{}),O=R=>T(R==="theme"?x:v),I=(R,B,re,P)=>!B&&!re?!!O(P)[R]:!!O(P)[R]?.includes((B??"")+(re??"")),J=(R,B)=>O(B)[R]||[];async function D(R){a(!0);try{let B=[],re=[];for(let W of R){let ne=!1,xe=await(0,ko.resolveSelect)(Oo.store).getEntityRecords("postType","wp_font_family",{slug:W.slug,per_page:1,_embed:!0}),se=xe&&xe.length>0?xe[0]:null,be=se?{id:se.id,...se.font_family_settings,fontFace:(se?._embedded?.font_faces??[]).map(Fe=>Fe.font_face_settings)||[]}:null;be||(ne=!0,be=await Ug(ey(W),t));let ye=be.fontFace&&W.fontFace?be.fontFace.filter(Fe=>Fe&&W.fontFace&&tu(Fe,W.fontFace)):[];be.fontFace&&W.fontFace&&(W.fontFace=W.fontFace.filter(Fe=>!tu(Fe,be.fontFace)));let $=[],_e=[];if(W?.fontFace?.length??!1){let Fe=await ry(be.id,ty(W),t);$=Fe?.successes,_e=Fe?.errors}($?.length>0||ye?.length>0)&&(be.fontFace=[...$],B.push(be)),be&&!W?.fontFace?.length&&B.push(be),ne&&(W?.fontFace?.length??0)>0&&$?.length===0&&await o("postType","wp_font_family",be.id,{force:!0}),re=re.concat(_e)}let P=re.reduce((W,ne)=>W.includes(ne.message)?W:[...W,ne.message],[]);if(B.length>0){let W=Y(B);await h(W)}if(P.length>0){let W=new Error((0,ru.__)("There was an error installing fonts."));throw W.installationErrors=P,W}}finally{a(!1)}}async function S(R){if(!R?.id)throw new Error((0,ru.__)("Font family to uninstall is not defined."));try{await o("postType","wp_font_family",R.id,{force:!0});let B=L(R);return await h(B),{deleted:!0}}catch(B){throw console.error("There was an error uninstalling the font family:",B),B}}let L=R=>{let re=(m?.[R.source??""]??[]).filter(W=>W.slug!==R.slug),P={...m,[R.source??""]:re};return d(P),R.fontFace&&R.fontFace.forEach(W=>{bi(W,"all")}),P},Y=R=>{let B=A(R),re={...m,custom:$g(m?.custom,B)};return d(re),N(B),re},A=R=>R.map(({id:B,fontFace:re,...P})=>({...P,...re&&re.length>0?{fontFace:re.map(({id:W,...ne})=>ne)}:{}})),N=R=>{R.forEach(B=>{B.fontFace&&B.fontFace.forEach(re=>{let P=Ln(re?.src??"");P&&Po(re,P,"all")})})},q=(R,B)=>{let re=m?.[R.source??""]??[],P=Qs(R,B,re);d({...m,[R.source??""]:P});let W=I(R.slug,B?.fontStyle??"",B?.fontWeight??"",R.source??"custom");if(B&&W)bi(B,"all");else{let ne=Ln(B?.src??"");B&&ne&&Po(B,ne,"all")}},U=async R=>{if(!R.src)return;let B=Ln(R.src);!B||E.has(B)||(Po(R,B,"document"),E.add(B))};return(0,iy.jsx)(jt.Provider,{value:{libraryFontSelected:w,handleSetLibraryFontSelected:k,fontFamilies:m??{},baseCustomFonts:_,isFontActivated:I,getFontFacesActivated:J,loadFontFaceAsset:U,installFonts:D,uninstallFontFamily:S,toggleActivateFont:q,getAvailableFontsOutline:T,modalTabOpen:g,setModalTabOpen:b,saveFontFamilies:h,isResolvingLibrary:l,isInstalling:s},children:e})}var $s=vS;var ma=f(ge(),1),au=f(ue(),1),zy=f(sr(),1),v2=f(Kt(),1);var Ie=f(ue(),1),xi=f(sr(),1),ou=f(Kt(),1),Wr=f(Te(),1),st=f(ge(),1);var Mn=f(ge(),1),ea=f(Te(),1),hr=f(ue(),1);var Tr=f(Te(),1);var ro=f(Z(),1),sy=new Set;function bS(e){if(e.preview)return e.preview;if(e.src)return Array.isArray(e.src)?e.src[0]:e.src}function wS(e){return"fontStyle"in e&&e.fontStyle||"fontWeight"in e&&e.fontWeight?e:"fontFace"in e&&e.fontFace&&e.fontFace.length?e.fontFace.find(t=>t.fontStyle==="normal"&&t.fontWeight==="400")||e.fontFace[0]:{fontStyle:"normal",fontWeight:"400",fontFamily:e.fontFamily}}function xS({font:e,text:t}){let r=(0,Tr.useRef)(null),o=wS(e),n=On(e);t=t||("name"in e?e.name:"");let s=e.preview??bS(o),a=!!(s&&/\.(png|jpg|jpeg|gif|svg)$/i.test(s)),[u,l]=(0,Tr.useState)(!1),[c,m]=(0,Tr.useState)(!1),[d,h]=(0,Tr.useState)(),{loadFontFaceAsset:g}=(0,Tr.useContext)(jt),b=a?!!s&&(sy.has(s)||d===s):c,w=Math.min(Math.max(t.length*12,48),300),C=dg(o),x={fontSize:"18px",lineHeight:1,opacity:b?"1":"0",...n,...C};return(0,Tr.useEffect)(()=>{if(a)return;let v=new window.IntersectionObserver(([_])=>{l(_.isIntersecting)},{});return r.current&&v.observe(r.current),()=>v.disconnect()},[a]),(0,Tr.useEffect)(()=>{(async()=>u&&!a&&(o.src&&await g(o),m(!0)))()},[o,u,g,a]),(0,ro.jsx)("div",{ref:r,className:"font-library__font-demo",children:a?(0,ro.jsxs)(ro.Fragment,{children:[!b&&(0,ro.jsx)(ui,{className:"font-library__font-variant-demo-skeleton",style:{width:w}}),(0,ro.jsx)("img",{src:s,loading:"lazy",alt:t,onLoad:()=>{s&&sy.add(s),h(s)},onError:()=>h(s),className:We("font-library__font-variant_demo-image",{"is-loading":!b})})]}):(0,ro.jsx)("span",{style:x,className:"font-library__font-variant_demo-text",children:t})})}var Nn=xS;var Ur=f(Z(),1);function SS({font:e,onClick:t,variantsText:r,navigatorPath:o,shouldFocus:n}){let i=e.fontFace?.length||1,s={cursor:t?"pointer":"default"},a=(0,hr.useNavigator)(),u=(0,ea.useRef)(null);return(0,ea.useEffect)(()=>{n&&u.current?.focus()},[n]),(0,Ur.jsx)(hr.Button,{ref:u,__next40pxDefaultSize:!0,onClick:()=>{t(),o&&a.goTo(o)},style:s,className:"font-library__font-card",children:(0,Ur.jsxs)(hr.Flex,{justify:"space-between",wrap:!1,children:[(0,Ur.jsx)(Nn,{font:e}),(0,Ur.jsxs)(hr.Flex,{justify:"flex-end",children:[(0,Ur.jsx)(hr.FlexItem,{children:(0,Ur.jsx)(hr.__experimentalText,{className:"font-library__font-card__count",children:r||(0,Mn.sprintf)((0,Mn._n)("%d variant","%d variants",i),i)})}),(0,Ur.jsx)(hr.FlexItem,{children:(0,Ur.jsx)(ai,{icon:(0,Mn.isRTL)()?Uo:Wo})})]})]})})}var wi=SS;var ta=f(Te(),1),ra=f(ue(),1);var Ko=f(Z(),1);function CS({face:e,font:t}){let{isFontActivated:r,toggleActivateFont:o}=(0,ta.useContext)(jt),n=(t?.fontFace?.length??0)>0?r(t.slug,e.fontStyle,e.fontWeight,t.source):r(t.slug,void 0,void 0,t.source),i=()=>{if((t?.fontFace?.length??0)>0){o(t,e);return}o(t)},s=t.name+" "+Js(e),a=(0,ta.useId)();return(0,Ko.jsx)("div",{className:"font-library__font-card",children:(0,Ko.jsxs)(ra.Flex,{justify:"flex-start",align:"center",gap:"1rem",children:[(0,Ko.jsx)(ra.CheckboxControl,{checked:n,onChange:i,id:a}),(0,Ko.jsx)("label",{htmlFor:a,children:(0,Ko.jsx)(Nn,{font:e,text:s,onClick:i})})]})})}var ay=CS;function ly(e){switch(e){case"normal":return 400;case"bold":return 700;case"bolder":return 500;case"lighter":return 300;default:return parseInt(e,10)}}function oa(e){return e.sort((t,r)=>t.fontStyle==="normal"&&r.fontStyle!=="normal"?-1:r.fontStyle==="normal"&&t.fontStyle!=="normal"?1:t.fontStyle===r.fontStyle?ly(t.fontWeight?.toString()??"normal")-ly(r.fontWeight?.toString()??"normal"):!t.fontStyle||!r.fontStyle?t.fontStyle?-1:1:t.fontStyle.localeCompare(r.fontStyle))}var Ee=f(Z(),1);function cy(e){if(!e)return"";let t={};for(let r of Object.keys(e).sort())t[r]=(e[r]??[]).map(o=>({slug:o.slug,fontFace:(o.fontFace??[]).map(n=>`${n.fontStyle}-${n.fontWeight}`).sort()})).sort((o,n)=>o.slug.localeCompare(n.slug));return JSON.stringify(t)}function _S(){let{baseCustomFonts:e,libraryFontSelected:t,handleSetLibraryFontSelected:r,uninstallFontFamily:o,isResolvingLibrary:n,isInstalling:i,saveFontFamilies:s,getFontFacesActivated:a}=(0,Wr.useContext)(jt),[u,l]=Ke("typography.fontFamilies"),[c,m]=(0,Wr.useState)(void 0),[d,h]=(0,Wr.useState)(!1),[g,b]=(0,Wr.useState)(null),[w]=Ke("typography.fontFamilies",void 0,"base"),C=(0,ou.useSelect)(P=>{let{__experimentalGetCurrentGlobalStylesId:W}=P(xi.store);return W()},[]),x=(0,xi.useEntityRecord)("root","globalStyles",C),v=x?.edits?.settings?.typography?.fontFamilies,_=x?.record?.settings?.typography?.fontFamilies,k=(0,Wr.useMemo)(()=>v===void 0?!1:cy(v)!==cy(_),[v,_]),E=u?.theme?u.theme.map(P=>To(P,{source:"theme"})).sort((P,W)=>P.name.localeCompare(W.name)):[],T=new Set(E.map(P=>P.slug)),O=w?.theme?E.concat(w.theme.filter(P=>!T.has(P.slug)).map(P=>To(P,{source:"theme"})).sort((P,W)=>P.name.localeCompare(W.name))):[],I=t?.source==="custom"&&t?.id,J=(0,ou.useSelect)(P=>{let{canUser:W}=P(xi.store);return I&&W("delete",{kind:"postType",name:"wp_font_family",id:I})},[I]),D=!!t&&t?.source!=="theme"&&J,S=()=>{h(!0)},L=async()=>{b(null);try{await s(u),b({type:"success",message:(0,st.__)("Font family updated successfully.")})}catch(P){b({type:"error",message:(0,st.sprintf)((0,st.__)("There was an error updating the font family. %s"),P.message)})}},Y=P=>P?!P.fontFace||!P.fontFace.length?[{fontFamily:P.fontFamily,fontStyle:"normal",fontWeight:"400"}]:oa(P.fontFace):[],A=P=>{let W=P?.fontFace&&(P?.fontFace?.length??0)>0?P.fontFace.length:1,ne=a(P.slug,P.source).length;return(0,st.sprintf)((0,st.__)("%1$d of %2$d active"),ne,W)};(0,Wr.useEffect)(()=>{r(t)},[]);let N=t?a(t.slug,t.source).length:0,q=t?.fontFace?.length??(t?.fontFamily?1:0),U=N>0&&N!==q,R=N===q,B=()=>{if(!t||!t?.source)return;let P=u?.[t.source]?.filter(ne=>ne.slug!==t.slug)??[],W=R?P:[...P,t];l({...u,[t.source]:W}),t.fontFace&&t.fontFace.forEach(ne=>{if(R)bi(ne,"all");else{let xe=Ln(ne?.src??"");xe&&Po(ne,xe,"all")}})},re=O.length>0||e.length>0;return(0,Ee.jsxs)("div",{className:"font-library__tabpanel-layout",children:[n&&(0,Ee.jsx)("div",{className:"font-library__loading",children:(0,Ee.jsx)(Ie.ProgressBar,{})}),!n&&(0,Ee.jsxs)(Ee.Fragment,{children:[(0,Ee.jsxs)(Ie.Navigator,{initialPath:t?"/fontFamily":"/",children:[(0,Ee.jsx)(Ie.Navigator.Screen,{path:"/",children:(0,Ee.jsxs)(Ie.__experimentalVStack,{spacing:"8",children:[g&&(0,Ee.jsx)(Ie.Notice,{status:g.type,onRemove:()=>b(null),children:g.message}),!re&&(0,Ee.jsx)(Ie.__experimentalText,{as:"p",children:(0,st.__)("No fonts installed.")}),O.length>0&&(0,Ee.jsxs)(Ie.__experimentalVStack,{children:[(0,Ee.jsx)("h2",{className:"font-library__fonts-title",children:(0,st._x)("Theme","font source")}),(0,Ee.jsx)("ul",{role:"list",className:"font-library__fonts-list",children:O.map(P=>(0,Ee.jsx)("li",{className:"font-library__fonts-list-item",children:(0,Ee.jsx)(wi,{font:P,navigatorPath:"/fontFamily",variantsText:A(P),shouldFocus:P.slug===c,onClick:()=>{b(null),r(P)}})},P.slug))})]}),e.length>0&&(0,Ee.jsxs)(Ie.__experimentalVStack,{children:[(0,Ee.jsx)("h2",{className:"font-library__fonts-title",children:(0,st._x)("Custom","font source")}),(0,Ee.jsx)("ul",{role:"list",className:"font-library__fonts-list",children:e.map(P=>(0,Ee.jsx)("li",{className:"font-library__fonts-list-item",children:(0,Ee.jsx)(wi,{font:P,navigatorPath:"/fontFamily",variantsText:A(P),shouldFocus:P.slug===c,onClick:()=>{b(null),r(P)}})},P.slug))})]})]})}),(0,Ee.jsxs)(Ie.Navigator.Screen,{path:"/fontFamily",children:[t&&(0,Ee.jsx)(RS,{font:t,isOpen:d,setIsOpen:h,setNotice:b,uninstallFontFamily:o,handleSetLibraryFontSelected:r}),(0,Ee.jsxs)(Ie.Flex,{justify:"flex-start",children:[(0,Ee.jsx)(Ie.Navigator.BackButton,{icon:(0,st.isRTL)()?Wo:Uo,size:"small",onClick:()=>{m(t?.slug),r(void 0),b(null)},label:(0,st.__)("Back")}),(0,Ee.jsx)(Ie.__experimentalHeading,{level:2,size:13,className:"global-styles-ui-header",children:t?.name})]}),g&&(0,Ee.jsxs)(Ee.Fragment,{children:[(0,Ee.jsx)(Ie.__experimentalSpacer,{margin:1}),(0,Ee.jsx)(Ie.Notice,{status:g.type,onRemove:()=>b(null),children:g.message}),(0,Ee.jsx)(Ie.__experimentalSpacer,{margin:1})]}),(0,Ee.jsx)(Ie.__experimentalSpacer,{margin:4}),(0,Ee.jsx)(Ie.__experimentalText,{children:(0,st.__)("Choose font variants. Keep in mind that too many variants could make your site slower.")}),(0,Ee.jsx)(Ie.__experimentalSpacer,{margin:4}),(0,Ee.jsxs)(Ie.__experimentalVStack,{spacing:0,children:[(0,Ee.jsx)(Ie.CheckboxControl,{className:"font-library__select-all",label:(0,st.__)("Select all"),checked:R,onChange:B,indeterminate:U}),(0,Ee.jsx)(Ie.__experimentalSpacer,{margin:8}),(0,Ee.jsx)("ul",{role:"list",className:"font-library__fonts-list",children:t&&Y(t).map((P,W)=>(0,Ee.jsx)("li",{className:"font-library__fonts-list-item",children:(0,Ee.jsx)(ay,{font:t,face:P},`face${W}`)},`face${W}`))})]})]})]}),(0,Ee.jsxs)(Ie.__experimentalHStack,{justify:"flex-end",className:"font-library__footer",children:[i&&(0,Ee.jsx)(Ie.ProgressBar,{}),D&&(0,Ee.jsx)(Ie.Button,{__next40pxDefaultSize:!0,isDestructive:!0,variant:"tertiary",onClick:S,children:(0,st.__)("Delete")}),(0,Ee.jsx)(Ie.Button,{__next40pxDefaultSize:!0,variant:"primary",onClick:L,disabled:!k,accessibleWhenDisabled:!0,children:(0,st.__)("Update")})]})]})]})}function RS({font:e,isOpen:t,setIsOpen:r,setNotice:o,uninstallFontFamily:n,handleSetLibraryFontSelected:i}){let s=(0,Ie.useNavigator)(),a=async()=>{o(null),r(!1);try{await n(e),s.goBack(),i(void 0),o({type:"success",message:(0,st.__)("Font family uninstalled successfully.")})}catch(l){o({type:"error",message:(0,st.__)("There was an error uninstalling the font family.")+l.message})}},u=()=>{r(!1)};return(0,Ee.jsx)(Ie.__experimentalConfirmDialog,{isOpen:t,cancelButtonText:(0,st.__)("Cancel"),confirmButtonText:(0,st.__)("Delete"),onCancel:u,onConfirm:a,size:"medium",children:e&&(0,st.sprintf)((0,st.__)('Are you sure you want to delete "%s" font and all its variants and assets?'),e.name)})}var na=_S;var yt=f(Te(),1),Ce=f(ue(),1),yy=f(yo(),1),rt=f(ge(),1);var vy=f(sr(),1);function uy(e,t){let{category:r,search:o}=t,n=e||[];return r&&r!=="all"&&(n=n.filter(i=>i.categories&&i.categories.indexOf(r)!==-1)),o&&(n=n.filter(i=>i.font_family_settings&&i.font_family_settings.name.toLowerCase().includes(o.toLowerCase()))),n}function fy(e){return e.reduce((t,r)=>({...t,[r.slug]:(r?.fontFace||[]).reduce((o,n)=>({...o,[`${n.fontStyle}-${n.fontWeight}`]:!0}),{})}),{})}function dy(e,t,r){return t?!!r[e]?.[`${t.fontStyle}-${t.fontWeight}`]:!!r[e]}var Si=f(ge(),1),zt=f(ue(),1),gr=f(Z(),1);function ES(){let e=()=>{window.localStorage.setItem("wp-font-library-google-fonts-permission","true"),window.dispatchEvent(new Event("storage"))};return(0,gr.jsx)("div",{className:"font-library__google-fonts-confirm",children:(0,gr.jsx)(zt.Card,{children:(0,gr.jsxs)(zt.CardBody,{children:[(0,gr.jsx)(zt.__experimentalHeading,{level:2,children:(0,Si.__)("Connect to Google Fonts")}),(0,gr.jsx)(zt.__experimentalSpacer,{margin:6}),(0,gr.jsx)(zt.__experimentalText,{as:"p",children:(0,Si.__)("To install fonts from Google you must give permission to connect directly to Google servers. The fonts you install will be downloaded from Google and stored on your site. Your site will then use these locally-hosted fonts.")}),(0,gr.jsx)(zt.__experimentalSpacer,{margin:3}),(0,gr.jsx)(zt.__experimentalText,{as:"p",children:(0,Si.__)("You can alternatively upload files directly on the Upload tab.")}),(0,gr.jsx)(zt.__experimentalSpacer,{margin:6}),(0,gr.jsx)(zt.Button,{__next40pxDefaultSize:!0,variant:"primary",onClick:e,children:(0,Si.__)("Allow access to Google Fonts")})]})})})}var py=ES;var my=f(Te(),1),ia=f(ue(),1);var Jo=f(Z(),1);function TS({face:e,font:t,handleToggleVariant:r,selected:o}){let n=()=>{if(t?.fontFace){r(t,e);return}r(t)},i=t.name+" "+Js(e),s=(0,my.useId)();return(0,Jo.jsx)("div",{className:"font-library__font-card",children:(0,Jo.jsxs)(ia.Flex,{justify:"flex-start",align:"center",gap:"1rem",children:[(0,Jo.jsx)(ia.CheckboxControl,{checked:o,onChange:n,id:s}),(0,Jo.jsx)("label",{htmlFor:s,children:(0,Jo.jsx)(Nn,{font:e,text:i,onClick:n})})]})})}var hy=TS;var de=f(Z(),1),PS={slug:"all",name:(0,rt._x)("All","font categories")},gy="wp-font-library-google-fonts-permission",OS=500;function kS({slug:e}){let t=e==="google-fonts",r=()=>window.localStorage.getItem(gy)==="true",[o,n]=(0,yt.useState)(null),[i,s]=(0,yt.useState)(void 0),[a,u]=(0,yt.useState)(null),[l,c]=(0,yt.useState)([]),[m,d]=(0,yt.useState)(1),[h,g]=(0,yt.useState)({}),[b,w]=(0,yt.useState)(t&&!r()),{installFonts:C,isInstalling:x}=(0,yt.useContext)(jt),{record:v,isResolving:_}=(0,vy.useEntityRecord)("root","fontCollection",e);(0,yt.useEffect)(()=>{let $=()=>{w(t&&!r())};return $(),window.addEventListener("storage",$),()=>window.removeEventListener("storage",$)},[e,t]);let k=()=>{window.localStorage.setItem(gy,"false"),window.dispatchEvent(new Event("storage"))};(0,yt.useEffect)(()=>{n(null)},[e]),(0,yt.useEffect)(()=>{c([])},[o]);let E=(0,yt.useMemo)(()=>v?.font_families??[],[v]),T=v?.categories??[],O=[PS,...T],I=(0,yt.useMemo)(()=>uy(E,h),[E,h]),J=Math.max(window.innerHeight,OS),D=Math.floor((J-417)/61),S=Math.ceil(I.length/D),L=(m-1)*D,Y=m*D,A=I.slice(L,Y),N=$=>{g({...h,category:$}),d(1)},U=(0,yy.debounce)($=>{g({...h,search:$}),d(1)},300),R=($,_e)=>{let Fe=Qs($,_e,l);c(Fe)},B=fy(l),re=()=>{c([])},P=l.length>0?l[0]?.fontFace?.length??0:0,W=P>0&&P!==o?.fontFace?.length,ne=P===o?.fontFace?.length,xe=()=>{let $=[];!ne&&o&&$.push(o),c($)},se=async()=>{u(null);let $=l[0];try{$?.fontFace&&await Promise.all($.fontFace.map(async _e=>{_e.src&&(_e.file=await oy(_e.src))}))}catch{u({type:"error",message:(0,rt.__)("Error installing the fonts, could not be downloaded.")});return}try{await C([$]),u({type:"success",message:(0,rt.__)("Fonts were installed successfully.")})}catch(_e){u({type:"error",message:_e.message})}re()},be=$=>$?!$.fontFace||!$.fontFace.length?[{fontFamily:$.fontFamily,fontStyle:"normal",fontWeight:"400"}]:oa($.fontFace):[];if(b)return(0,de.jsx)(py,{});let ye=e==="google-fonts"&&!b&&!o;return(0,de.jsxs)("div",{className:"font-library__tabpanel-layout",children:[_&&(0,de.jsx)("div",{className:"font-library__loading",children:(0,de.jsx)(Ce.ProgressBar,{})}),!_&&v&&(0,de.jsxs)(de.Fragment,{children:[(0,de.jsxs)(Ce.Navigator,{initialPath:"/",className:"font-library__tabpanel-layout",children:[(0,de.jsxs)(Ce.Navigator.Screen,{path:"/",children:[(0,de.jsxs)(Ce.__experimentalHStack,{justify:"space-between",children:[(0,de.jsxs)(Ce.__experimentalVStack,{children:[(0,de.jsx)(Ce.__experimentalHeading,{level:2,size:13,children:v.name}),(0,de.jsx)(Ce.__experimentalText,{children:v.description})]}),ye&&(0,de.jsx)(Ce.DropdownMenu,{icon:jl,label:(0,rt.__)("Actions"),popoverProps:{position:"bottom left"},controls:[{title:(0,rt.__)("Revoke access to Google Fonts"),onClick:k}]})]}),(0,de.jsx)(Ce.__experimentalSpacer,{margin:4}),(0,de.jsxs)(Ce.__experimentalHStack,{spacing:4,justify:"space-between",children:[(0,de.jsx)(Ce.SearchControl,{className:"font-library__search",value:h.search,placeholder:(0,rt.__)("Font name\u2026"),label:(0,rt.__)("Search"),onChange:U,hideLabelFromVision:!1}),(0,de.jsx)(Ce.SelectControl,{label:(0,rt.__)("Category"),value:h.category,onChange:N,children:O&&O.map($=>(0,de.jsx)("option",{value:$.slug,children:$.name},$.slug))})]}),(0,de.jsx)(Ce.__experimentalSpacer,{margin:4}),!!v?.font_families?.length&&!I.length&&(0,de.jsx)(Ce.__experimentalText,{children:(0,rt.__)("No fonts found. Try with a different search term.")}),(0,de.jsx)("div",{className:"font-library__fonts-grid__main",children:(0,de.jsx)("ul",{role:"list",className:"font-library__fonts-list",children:A.map($=>(0,de.jsx)("li",{className:"font-library__fonts-list-item",children:(0,de.jsx)(wi,{font:$.font_family_settings,navigatorPath:"/fontFamily",shouldFocus:$.font_family_settings.slug===i,onClick:()=>{n($.font_family_settings)}})},$.font_family_settings.slug))})})]}),(0,de.jsxs)(Ce.Navigator.Screen,{path:"/fontFamily",children:[(0,de.jsxs)(Ce.Flex,{justify:"flex-start",children:[(0,de.jsx)(Ce.Navigator.BackButton,{icon:(0,rt.isRTL)()?Wo:Uo,size:"small",onClick:()=>{s(o?.slug),n(null),u(null)},label:(0,rt.__)("Back")}),(0,de.jsx)(Ce.__experimentalHeading,{level:2,size:13,className:"global-styles-ui-header",children:o?.name})]}),a&&(0,de.jsxs)(de.Fragment,{children:[(0,de.jsx)(Ce.__experimentalSpacer,{margin:1}),(0,de.jsx)(Ce.Notice,{status:a.type,onRemove:()=>u(null),children:a.message}),(0,de.jsx)(Ce.__experimentalSpacer,{margin:1})]}),(0,de.jsx)(Ce.__experimentalSpacer,{margin:4}),(0,de.jsx)(Ce.__experimentalText,{children:(0,rt.__)("Select font variants to install.")}),(0,de.jsx)(Ce.__experimentalSpacer,{margin:4}),(0,de.jsx)(Ce.CheckboxControl,{className:"font-library__select-all",label:(0,rt.__)("Select all"),checked:ne,onChange:xe,indeterminate:W}),(0,de.jsx)(Ce.__experimentalVStack,{spacing:0,children:(0,de.jsx)("ul",{role:"list",className:"font-library__fonts-list",children:o&&be(o).map(($,_e)=>(0,de.jsx)("li",{className:"font-library__fonts-list-item",children:(0,de.jsx)(hy,{font:o,face:$,handleToggleVariant:R,selected:dy(o.slug,o.fontFace?$:null,B)})},`face${_e}`))})}),(0,de.jsx)(Ce.__experimentalSpacer,{margin:16})]})]}),o&&(0,de.jsx)(Ce.Flex,{justify:"flex-end",className:"font-library__footer",children:(0,de.jsx)(Ce.Button,{__next40pxDefaultSize:!0,variant:"primary",onClick:se,isBusy:x,disabled:l.length===0||x,accessibleWhenDisabled:!0,children:(0,rt.__)("Install")})}),!o&&(0,de.jsxs)(Ce.__experimentalHStack,{expanded:!1,className:"font-library__footer",justify:"end",spacing:6,children:[(0,de.jsx)(Ce.__experimentalHStack,{justify:"flex-start",expanded:!1,spacing:1,className:"font-library__page-selection",children:(0,yt.createInterpolateElement)((0,rt.sprintf)((0,rt._x)("
Page
%1$s
of %2$d
","paging"),"",S),{div:(0,de.jsx)("div",{"aria-hidden":!0}),CurrentPage:(0,de.jsx)(Ce.SelectControl,{"aria-label":(0,rt.__)("Current page"),value:m.toString(),options:[...Array(S)].map(($,_e)=>({label:(_e+1).toString(),value:(_e+1).toString()})),onChange:$=>d(parseInt($)),size:"small",variant:"minimal"})})}),(0,de.jsxs)(Ce.__experimentalHStack,{expanded:!1,spacing:1,children:[(0,de.jsx)(Ce.Button,{onClick:()=>d(m-1),disabled:m===1,accessibleWhenDisabled:!0,label:(0,rt.__)("Previous page"),icon:(0,rt.isRTL)()?Os:Fs,showTooltip:!0,size:"compact",tooltipPosition:"top"}),(0,de.jsx)(Ce.Button,{onClick:()=>d(m+1),disabled:m===S,accessibleWhenDisabled:!0,label:(0,rt.__)("Next page"),icon:(0,rt.isRTL)()?Fs:Os,showTooltip:!0,size:"compact",tooltipPosition:"top"})]})]})]})]})}var sa=kS;var Vn=f(ge(),1),Ot=f(ue(),1),_i=f(Te(),1);var aa=(e=>typeof Wt<"u"?Wt:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof Wt<"u"?Wt:t)[r]}):e)(function(e){if(typeof Wt<"u")return Wt.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')}),by=(function(){var e,t,r;return(function(){function o(n,i,s){function a(c,m){if(!i[c]){if(!n[c]){var d=typeof aa=="function"&&aa;if(!m&&d)return d(c,!0);if(u)return u(c,!0);var h=new Error("Cannot find module '"+c+"'");throw h.code="MODULE_NOT_FOUND",h}var g=i[c]={exports:{}};n[c][0].call(g.exports,function(b){var w=n[c][1][b];return a(w||b)},g,g.exports,o,n,i,s)}return i[c].exports}for(var u=typeof aa=="function"&&aa,l=0;l0},c.prototype.readMoreInput=function(){if(!(this.bit_end_pos_>256))if(this.eos_){if(this.bit_pos_>this.bit_end_pos_)throw new Error("Unexpected end of input "+this.bit_pos_+" "+this.bit_end_pos_)}else{var m=this.buf_ptr_,d=this.input_.read(this.buf_,m,s);if(d<0)throw new Error("Unexpected end of input");if(d=8;)this.val_>>>=8,this.val_|=this.buf_[this.pos_&u]<<24,++this.pos_,this.bit_pos_=this.bit_pos_-8>>>0,this.bit_end_pos_=this.bit_end_pos_-8>>>0},c.prototype.readBits=function(m){32-this.bit_pos_>>this.bit_pos_&l[m];return this.bit_pos_+=m,d},n.exports=c},{}],2:[function(o,n,i){var s=0,a=1,u=2,l=3;i.lookup=new Uint8Array([0,0,0,0,0,0,0,0,0,4,4,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,12,16,12,12,20,12,16,24,28,12,12,32,12,36,12,44,44,44,44,44,44,44,44,44,44,32,32,24,40,28,12,12,48,52,52,52,48,52,52,52,48,52,52,52,52,52,48,52,52,52,52,52,48,52,52,52,52,52,24,12,28,12,12,12,56,60,60,60,56,60,60,60,56,60,60,60,60,60,56,60,60,60,60,60,56,60,60,60,60,60,24,12,28,12,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,56,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10,11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,14,15,15,15,15,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,22,22,22,22,23,23,23,23,24,24,24,24,25,25,25,25,26,26,26,26,27,27,27,27,28,28,28,28,29,29,29,29,30,30,30,30,31,31,31,31,32,32,32,32,33,33,33,33,34,34,34,34,35,35,35,35,36,36,36,36,37,37,37,37,38,38,38,38,39,39,39,39,40,40,40,40,41,41,41,41,42,42,42,42,43,43,43,43,44,44,44,44,45,45,45,45,46,46,46,46,47,47,47,47,48,48,48,48,49,49,49,49,50,50,50,50,51,51,51,51,52,52,52,52,53,53,53,53,54,54,54,54,55,55,55,55,56,56,56,56,57,57,57,57,58,58,58,58,59,59,59,59,60,60,60,60,61,61,61,61,62,62,62,62,63,63,63,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]),i.lookupOffsets=new Uint16Array([1024,1536,1280,1536,0,256,768,512])},{}],3:[function(o,n,i){var s=o("./streams").BrotliInput,a=o("./streams").BrotliOutput,u=o("./bit_reader"),l=o("./dictionary"),c=o("./huffman").HuffmanCode,m=o("./huffman").BrotliBuildHuffmanTable,d=o("./context"),h=o("./prefix"),g=o("./transform"),b=8,w=16,C=256,x=704,v=26,_=6,k=2,E=8,T=255,O=1080,I=18,J=new Uint8Array([1,2,3,4,0,5,17,6,16,7,8,9,10,11,12,13,14,15]),D=16,S=new Uint8Array([3,2,1,0,3,3,3,3,3,3,2,2,2,2,2,2]),L=new Int8Array([0,0,0,0,-1,1,-2,2,-3,3,-1,1,-2,2,-3,3]),Y=new Uint16Array([256,402,436,468,500,534,566,598,630,662,694,726,758,790,822,854,886,920,952,984,1016,1048,1080]);function A(X){var M;return X.readBits(1)===0?16:(M=X.readBits(3),M>0?17+M:(M=X.readBits(3),M>0?8+M:17))}function N(X){if(X.readBits(1)){var M=X.readBits(3);return M===0?1:X.readBits(M)+(1<1&&pe===0)throw new Error("Invalid size byte");M.meta_block_length|=pe<4&&le===0)throw new Error("Invalid size nibble");M.meta_block_length|=le<>>K.bit_pos_&T,Q=X[M].bits-E,Q>0&&(K.bit_pos_+=E,M+=X[M].value,M+=K.val_>>>K.bit_pos_&(1<0;){var te=0,Ne;if(H.readMoreInput(),H.fillBitWindow(),te+=H.val_>>>H.bit_pos_&31,H.bit_pos_+=he[te].bits,Ne=he[te].value&255,Ne>Ne);else{var He=Ne-14,ot,Ze,Be=0;if(Ne===w&&(Be=pe),fe!==Be&&(le=0,fe=Be),ot=le,le>0&&(le-=2,le<<=He),le+=H.readBits(He)+3,Ze=le-ot,Q+Ze>M)throw new Error("[ReadHuffmanCodeLengths] symbol + repeat_delta > num_symbols");for(var Ue=0;Ue0;++fe){var Be=J[fe],Ue=0,ct;H.fillBitWindow(),Ue+=H.val_>>>H.bit_pos_&15,H.bit_pos_+=Ze[Ue].bits,ct=Ze[Ue].value,Ne[Be]=ct,ct!==0&&(He-=32>>ct,++ot)}if(!(ot===1||He===0))throw new Error("[ReadHuffmanCode] invalid num_codes or space");B(Ne,X,le,H)}if(Q=m(M,K,E,le,X),Q===0)throw new Error("[ReadHuffmanCode] BuildHuffmanTable failed: ");return Q}function P(X,M,K){var H,Q;return H=R(X,M,K),Q=h.kBlockLengthPrefixCode[H].nbits,h.kBlockLengthPrefixCode[H].offset+K.readBits(Q)}function W(X,M,K){var H;return X>>5]),this.htrees=new Uint32Array(M)}se.prototype.decode=function(X){var M,K,H=0;for(M=0;M=X)throw new Error("[DecodeContextMap] i >= context_map_size");me[le]=0,++le}else me[le]=he-Q,++le}return M.readBits(1)&&xe(me,X),K}function ye(X,M,K,H,Q,pe,le){var fe=K*2,me=K,he=R(M,K*O,le),V;he===0?V=Q[fe+(pe[me]&1)]:he===1?V=Q[fe+(pe[me]-1&1)]+1:V=he-2,V>=X&&(V-=X),H[K]=V,Q[fe+(pe[me]&1)]=V,++pe[me]}function $(X,M,K,H,Q,pe){var le=Q+1,fe=K&Q,me=pe.pos_&u.IBUF_MASK,he;if(M<8||pe.bit_pos_+(M<<3)0;)pe.readMoreInput(),H[fe++]=pe.readBits(8),fe===le&&(X.write(H,le),fe=0);return}if(pe.bit_end_pos_<32)throw new Error("[CopyUncompressedBlockToOutput] br.bit_end_pos_ < 32");for(;pe.bit_pos_<32;)H[fe]=pe.val_>>>pe.bit_pos_,pe.bit_pos_+=8,++fe,--M;if(he=pe.bit_end_pos_-pe.bit_pos_>>3,me+he>u.IBUF_MASK){for(var V=u.IBUF_MASK+1-me,te=0;te=le){X.write(H,le),fe-=le;for(var te=0;te=le;){if(he=le-fe,pe.input_.read(H,fe,he)M.buffer.length){var Fo=new Uint8Array(H+Ye);Fo.set(M.buffer),M.buffer=Fo}if(Q=wr.input_end,Yr=wr.is_uncompressed,wr.is_metadata){for(_e(Se);Ye>0;--Ye)Se.readMoreInput(),Se.readBits(8);continue}if(Ye!==0){if(Yr){Se.bit_pos_=Se.bit_pos_+7&-8,$(M,Ye,H,V,he,Se),H+=Ye;continue}for(K=0;K<3;++K)vt[K]=N(Se)+1,vt[K]>=2&&(re(vt[K]+2,Ue,K*O,Se),re(v,ct,K*O,Se),St[K]=P(ct,K*O,Se),G[K]=1);for(Se.readMoreInput(),y=Se.readBits(2),oe=D+(Se.readBits(4)<0;){var ft,At,Ht,en,Ta,Ut,er,qr,Hn,tn,Un;for(Se.readMoreInput(),St[1]===0&&(ye(vt[1],Ue,1,kt,F,G,Se),St[1]=P(ct,O,Se),pt=Be[1].htrees[kt[1]]),--St[1],ft=R(Be[1].codes,pt,Se),At=ft>>6,At>=2?(At-=2,er=-1):er=0,Ht=h.kInsertRangeLut[At]+(ft>>3&7),en=h.kCopyRangeLut[At]+(ft&7),Ta=h.kInsertLengthPrefixCode[Ht].offset+Se.readBits(h.kInsertLengthPrefixCode[Ht].nbits),Ut=h.kCopyLengthPrefixCode[en].offset+Se.readBits(h.kCopyLengthPrefixCode[en].nbits),ot=V[H-1&he],Ze=V[H-2&he],tn=0;tn4?3:Ut-2)&255,et=j[Or+Hn],er=R(Be[2].codes,Be[2].htrees[et],Se),er>=oe){var Pa,Vu,Wn;er-=oe,Vu=er&Ae,er>>=y,Pa=(er>>1)+1,Wn=(2+(er&1)<fe)if(Ut>=l.minDictionaryWordLength&&Ut<=l.maxDictionaryWordLength){var Wn=l.offsetsByLength[Ut],Du=qr-fe-1,Bu=l.sizeBitsByLength[Ut],zv=(1<>Bu;if(Wn+=Hv*Ut,ju=te){M.write(V,me);for(var Fi=0;Fi0&&(Ne[He&3]=qr,++He),Ut>Ye)throw new Error("Invalid backward reference. pos: "+H+" distance: "+qr+" len: "+Ut+" bytes left: "+Ye);for(tn=0;tn>=1;return(m&h-1)+h}function l(m,d,h,g,b){do g-=h,m[d+g]=new s(b.bits,b.value);while(g>0)}function c(m,d,h){for(var g=1<0;--S[x])C=new s(x&255,D[v++]&65535),l(m,d+_,k,I,C),_=u(_,x);for(T=J-1,E=-1,x=h+1,k=2;x<=a;++x,k<<=1)for(;S[x]>0;--S[x])(_&T)!==E&&(d+=I,O=c(S,x,h),I=1<>h),k,I,C),_=u(_,x);return J}},{}],8:[function(o,n,i){"use strict";i.byteLength=h,i.toByteArray=b,i.fromByteArray=x;for(var s=[],a=[],u=typeof Uint8Array<"u"?Uint8Array:Array,l="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",c=0,m=l.length;c0)throw new Error("Invalid string. Length must be a multiple of 4");var k=v.indexOf("=");k===-1&&(k=_);var E=k===_?0:4-k%4;return[k,E]}function h(v){var _=d(v),k=_[0],E=_[1];return(k+E)*3/4-E}function g(v,_,k){return(_+k)*3/4-k}function b(v){for(var _,k=d(v),E=k[0],T=k[1],O=new u(g(v,E,T)),I=0,J=T>0?E-4:E,D=0;D>16&255,O[I++]=_>>8&255,O[I++]=_&255;return T===2&&(_=a[v.charCodeAt(D)]<<2|a[v.charCodeAt(D+1)]>>4,O[I++]=_&255),T===1&&(_=a[v.charCodeAt(D)]<<10|a[v.charCodeAt(D+1)]<<4|a[v.charCodeAt(D+2)]>>2,O[I++]=_>>8&255,O[I++]=_&255),O}function w(v){return s[v>>18&63]+s[v>>12&63]+s[v>>6&63]+s[v&63]}function C(v,_,k){for(var E,T=[],O=_;OJ?J:I+O));return E===1?(_=v[k-1],T.push(s[_>>2]+s[_<<4&63]+"==")):E===2&&(_=(v[k-2]<<8)+v[k-1],T.push(s[_>>10]+s[_>>4&63]+s[_<<2&63]+"=")),T.join("")}},{}],9:[function(o,n,i){function s(a,u){this.offset=a,this.nbits=u}i.kBlockLengthPrefixCode=[new s(1,2),new s(5,2),new s(9,2),new s(13,2),new s(17,3),new s(25,3),new s(33,3),new s(41,3),new s(49,4),new s(65,4),new s(81,4),new s(97,4),new s(113,5),new s(145,5),new s(177,5),new s(209,5),new s(241,6),new s(305,6),new s(369,7),new s(497,8),new s(753,9),new s(1265,10),new s(2289,11),new s(4337,12),new s(8433,13),new s(16625,24)],i.kInsertLengthPrefixCode=[new s(0,0),new s(1,0),new s(2,0),new s(3,0),new s(4,0),new s(5,0),new s(6,1),new s(8,1),new s(10,2),new s(14,2),new s(18,3),new s(26,3),new s(34,4),new s(50,4),new s(66,5),new s(98,5),new s(130,6),new s(194,7),new s(322,8),new s(578,9),new s(1090,10),new s(2114,12),new s(6210,14),new s(22594,24)],i.kCopyLengthPrefixCode=[new s(2,0),new s(3,0),new s(4,0),new s(5,0),new s(6,0),new s(7,0),new s(8,0),new s(9,0),new s(10,1),new s(12,1),new s(14,2),new s(18,2),new s(22,3),new s(30,3),new s(38,4),new s(54,4),new s(70,5),new s(102,5),new s(134,6),new s(198,7),new s(326,8),new s(582,9),new s(1094,10),new s(2118,24)],i.kInsertRangeLut=[0,0,8,8,0,16,8,16,16],i.kCopyRangeLut=[0,8,0,8,16,0,16,8,16]},{}],10:[function(o,n,i){function s(u){this.buffer=u,this.pos=0}s.prototype.read=function(u,l,c){this.pos+c>this.buffer.length&&(c=this.buffer.length-this.pos);for(var m=0;mthis.buffer.length)throw new Error("Output buffer is not large enough");return this.buffer.set(u.subarray(0,l),this.pos),this.pos+=l,l},i.BrotliOutput=a},{}],11:[function(o,n,i){var s=o("./dictionary"),a=0,u=1,l=2,c=3,m=4,d=5,h=6,g=7,b=8,w=9,C=10,x=11,v=12,_=13,k=14,E=15,T=16,O=17,I=18,J=19,D=20;function S(A,N,q){this.prefix=new Uint8Array(A.length),this.transform=N,this.suffix=new Uint8Array(q.length);for(var U=0;U'),new S("",a,` +`),new S("",c,""),new S("",a,"]"),new S("",a," for "),new S("",k,""),new S("",l,""),new S("",a," a "),new S("",a," that "),new S(" ",C,""),new S("",a,". "),new S(".",a,""),new S(" ",a,", "),new S("",E,""),new S("",a," with "),new S("",a,"'"),new S("",a," from "),new S("",a," by "),new S("",T,""),new S("",O,""),new S(" the ",a,""),new S("",m,""),new S("",a,". The "),new S("",x,""),new S("",a," on "),new S("",a," as "),new S("",a," is "),new S("",g,""),new S("",u,"ing "),new S("",a,` + `),new S("",a,":"),new S(" ",a,". "),new S("",a,"ed "),new S("",D,""),new S("",I,""),new S("",h,""),new S("",a,"("),new S("",C,", "),new S("",b,""),new S("",a," at "),new S("",a,"ly "),new S(" the ",a," of "),new S("",d,""),new S("",w,""),new S(" ",C,", "),new S("",C,'"'),new S(".",a,"("),new S("",x," "),new S("",C,'">'),new S("",a,'="'),new S(" ",a,"."),new S(".com/",a,""),new S(" the ",a," of the "),new S("",C,"'"),new S("",a,". This "),new S("",a,","),new S(".",a," "),new S("",C,"("),new S("",C,"."),new S("",a," not "),new S(" ",a,'="'),new S("",a,"er "),new S(" ",x," "),new S("",a,"al "),new S(" ",x,""),new S("",a,"='"),new S("",x,'"'),new S("",C,". "),new S(" ",a,"("),new S("",a,"ful "),new S(" ",C,". "),new S("",a,"ive "),new S("",a,"less "),new S("",x,"'"),new S("",a,"est "),new S(" ",C,"."),new S("",x,'">'),new S(" ",a,"='"),new S("",C,","),new S("",a,"ize "),new S("",x,"."),new S("\xC2\xA0",a,""),new S(" ",a,","),new S("",C,'="'),new S("",x,'="'),new S("",a,"ous "),new S("",x,", "),new S("",C,"='"),new S(" ",C,","),new S(" ",x,'="'),new S(" ",x,", "),new S("",x,","),new S("",x,"("),new S("",x,". "),new S(" ",x,"."),new S("",x,"='"),new S(" ",x,". "),new S(" ",C,'="'),new S(" ",x,"='"),new S(" ",C,"='")];i.kTransforms=L,i.kNumTransforms=L.length;function Y(A,N){return A[N]<192?(A[N]>=97&&A[N]<=122&&(A[N]^=32),1):A[N]<224?(A[N+1]^=32,2):(A[N+2]^=5,3)}i.transformDictionaryWord=function(A,N,q,U,R){var B=L[R].prefix,re=L[R].suffix,P=L[R].transform,W=PU&&(W=U);for(var be=0;be0;){var ye=Y(A,se);se+=ye,U-=ye}for(var $=0;$typeof Wt<"u"?Wt:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof Wt<"u"?Wt:t)[r]}):e)(function(e){if(typeof Wt<"u")return Wt.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')}),wy=(function(){var e,t,r;return(function(){function o(n,i,s){function a(c,m){if(!i[c]){if(!n[c]){var d=typeof la=="function"&&la;if(!m&&d)return d(c,!0);if(u)return u(c,!0);var h=new Error("Cannot find module '"+c+"'");throw h.code="MODULE_NOT_FOUND",h}var g=i[c]={exports:{}};n[c][0].call(g.exports,function(b){var w=n[c][1][b];return a(w||b)},g,g.exports,o,n,i,s)}return i[c].exports}for(var u=typeof la=="function"&&la,l=0;l=252?6:c>=248?5:c>=240?4:c>=224?3:c>=192?2:1;l[254]=l[254]=1,i.string2buf=function(d){var h,g,b,w,C,x=d.length,v=0;for(w=0;w>>6,h[C++]=128|g&63):g<65536?(h[C++]=224|g>>>12,h[C++]=128|g>>>6&63,h[C++]=128|g&63):(h[C++]=240|g>>>18,h[C++]=128|g>>>12&63,h[C++]=128|g>>>6&63,h[C++]=128|g&63);return h};function m(d,h){if(h<65534&&(d.subarray&&u||!d.subarray&&a))return String.fromCharCode.apply(null,s.shrinkBuf(d,h));for(var g="",b=0;b4){v[b++]=65533,g+=C-1;continue}for(w&=C===2?31:C===3?15:7;C>1&&g1){v[b++]=65533;continue}w<65536?v[b++]=w:(w-=65536,v[b++]=55296|w>>10&1023,v[b++]=56320|w&1023)}return m(v,b)},i.utf8border=function(d,h){var g;for(h=h||d.length,h>d.length&&(h=d.length),g=h-1;g>=0&&(d[g]&192)===128;)g--;return g<0||g===0?h:g+l[d[g]]>h?g:h}},{"./common":1}],3:[function(o,n,i){"use strict";function s(a,u,l,c){for(var m=a&65535|0,d=a>>>16&65535|0,h=0;l!==0;){h=l>2e3?2e3:l,l-=h;do m=m+u[c++]|0,d=d+m|0;while(--h);m%=65521,d%=65521}return m|d<<16|0}n.exports=s},{}],4:[function(o,n,i){"use strict";n.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],5:[function(o,n,i){"use strict";function s(){for(var l,c=[],m=0;m<256;m++){l=m;for(var d=0;d<8;d++)l=l&1?3988292384^l>>>1:l>>>1;c[m]=l}return c}var a=s();function u(l,c,m,d){var h=a,g=d+m;l^=-1;for(var b=d;b>>8^h[(l^c[b])&255];return l^-1}n.exports=u},{}],6:[function(o,n,i){"use strict";function s(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}n.exports=s},{}],7:[function(o,n,i){"use strict";var s=30,a=12;n.exports=function(l,c){var m,d,h,g,b,w,C,x,v,_,k,E,T,O,I,J,D,S,L,Y,A,N,q,U,R;m=l.state,d=l.next_in,U=l.input,h=d+(l.avail_in-5),g=l.next_out,R=l.output,b=g-(c-l.avail_out),w=g+(l.avail_out-257),C=m.dmax,x=m.wsize,v=m.whave,_=m.wnext,k=m.window,E=m.hold,T=m.bits,O=m.lencode,I=m.distcode,J=(1<>>24,E>>>=L,T-=L,L=S>>>16&255,L===0)R[g++]=S&65535;else if(L&16){Y=S&65535,L&=15,L&&(T>>=L,T-=L),T<15&&(E+=U[d++]<>>24,E>>>=L,T-=L,L=S>>>16&255,L&16){if(A=S&65535,L&=15,TC){l.msg="invalid distance too far back",m.mode=s;break e}if(E>>>=L,T-=L,L=g-b,A>L){if(L=A-L,L>v&&m.sane){l.msg="invalid distance too far back",m.mode=s;break e}if(N=0,q=k,_===0){if(N+=x-L,L2;)R[g++]=q[N++],R[g++]=q[N++],R[g++]=q[N++],Y-=3;Y&&(R[g++]=q[N++],Y>1&&(R[g++]=q[N++]))}else{N=g-A;do R[g++]=R[N++],R[g++]=R[N++],R[g++]=R[N++],Y-=3;while(Y>2);Y&&(R[g++]=R[N++],Y>1&&(R[g++]=R[N++]))}}else if((L&64)===0){S=I[(S&65535)+(E&(1<>3,d-=Y,T-=Y<<3,E&=(1<>>24&255)+(F>>>8&65280)+((F&65280)<<8)+((F&255)<<24)}function Ne(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new s.Buf16(320),this.work=new s.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function He(F){var G;return!F||!F.state?_:(G=F.state,F.total_in=F.total_out=G.total=0,F.msg="",G.wrap&&(F.adler=G.wrap&1),G.mode=I,G.last=0,G.havedict=0,G.dmax=32768,G.head=null,G.hold=0,G.bits=0,G.lencode=G.lendyn=new s.Buf32(fe),G.distcode=G.distdyn=new s.Buf32(me),G.sane=1,G.back=-1,C)}function ot(F){var G;return!F||!F.state?_:(G=F.state,G.wsize=0,G.whave=0,G.wnext=0,He(F))}function Ze(F,G){var y,oe;return!F||!F.state||(oe=F.state,G<0?(y=0,G=-G):(y=(G>>4)+1,G<48&&(G&=15)),G&&(G<8||G>15))?_:(oe.window!==null&&oe.wbits!==G&&(oe.window=null),oe.wrap=y,oe.wbits=G,ot(F))}function Be(F,G){var y,oe;return F?(oe=new Ne,F.state=oe,oe.window=null,y=Ze(F,G),y!==C&&(F.state=null),y):_}function Ue(F){return Be(F,V)}var ct=!0,Se,Pr;function $t(F){if(ct){var G;for(Se=new s.Buf32(512),Pr=new s.Buf32(32),G=0;G<144;)F.lens[G++]=8;for(;G<256;)F.lens[G++]=9;for(;G<280;)F.lens[G++]=7;for(;G<288;)F.lens[G++]=8;for(c(d,F.lens,0,288,Se,0,F.work,{bits:9}),G=0;G<32;)F.lens[G++]=5;c(h,F.lens,0,32,Pr,0,F.work,{bits:5}),ct=!1}F.lencode=Se,F.lenbits=9,F.distcode=Pr,F.distbits=5}function Ye(F,G,y,oe){var Ae,ee=F.state;return ee.window===null&&(ee.wsize=1<=ee.wsize?(s.arraySet(ee.window,G,y-ee.wsize,ee.wsize,0),ee.wnext=0,ee.whave=ee.wsize):(Ae=ee.wsize-ee.wnext,Ae>oe&&(Ae=oe),s.arraySet(ee.window,G,y-oe,Ae,ee.wnext),oe-=Ae,oe?(s.arraySet(ee.window,G,y-oe,oe,0),ee.wnext=oe,ee.whave=ee.wsize):(ee.wnext+=Ae,ee.wnext===ee.wsize&&(ee.wnext=0),ee.whave>>8&255,y.check=u(y.check,ft,2,0),j=0,z=0,y.mode=J;break}if(y.flags=0,y.head&&(y.head.done=!1),!(y.wrap&1)||(((j&255)<<8)+(j>>8))%31){F.msg="incorrect header check",y.mode=Q;break}if((j&15)!==O){F.msg="unknown compression method",y.mode=Q;break}if(j>>>=4,z-=4,at=(j&15)+8,y.wbits===0)y.wbits=at;else if(at>y.wbits){F.msg="invalid window size",y.mode=Q;break}y.dmax=1<>8&1),y.flags&512&&(ft[0]=j&255,ft[1]=j>>>8&255,y.check=u(y.check,ft,2,0)),j=0,z=0,y.mode=D;case D:for(;z<32;){if(ie===0)break e;ie--,j+=oe[ee++]<>>8&255,ft[2]=j>>>16&255,ft[3]=j>>>24&255,y.check=u(y.check,ft,4,0)),j=0,z=0,y.mode=S;case S:for(;z<16;){if(ie===0)break e;ie--,j+=oe[ee++]<>8),y.flags&512&&(ft[0]=j&255,ft[1]=j>>>8&255,y.check=u(y.check,ft,2,0)),j=0,z=0,y.mode=L;case L:if(y.flags&1024){for(;z<16;){if(ie===0)break e;ie--,j+=oe[ee++]<>>8&255,y.check=u(y.check,ft,2,0)),j=0,z=0}else y.head&&(y.head.extra=null);y.mode=Y;case Y:if(y.flags&1024&&(ce=y.length,ce>ie&&(ce=ie),ce&&(y.head&&(at=y.head.extra_len-y.length,y.head.extra||(y.head.extra=new Array(y.head.extra_len)),s.arraySet(y.head.extra,oe,ee,ce,at)),y.flags&512&&(y.check=u(y.check,oe,ce,ee)),ie-=ce,ee+=ce,y.length-=ce),y.length))break e;y.length=0,y.mode=A;case A:if(y.flags&2048){if(ie===0)break e;ce=0;do at=oe[ee+ce++],y.head&&at&&y.length<65536&&(y.head.name+=String.fromCharCode(at));while(at&&ce>9&1,y.head.done=!0),F.adler=y.check=0,y.mode=B;break;case U:for(;z<32;){if(ie===0)break e;ie--,j+=oe[ee++]<>>=z&7,z-=z&7,y.mode=M;break}for(;z<3;){if(ie===0)break e;ie--,j+=oe[ee++]<>>=1,z-=1,j&3){case 0:y.mode=P;break;case 1:if($t(y),y.mode=ye,G===w){j>>>=2,z-=2;break e}break;case 2:y.mode=xe;break;case 3:F.msg="invalid block type",y.mode=Q}j>>>=2,z-=2;break;case P:for(j>>>=z&7,z-=z&7;z<32;){if(ie===0)break e;ie--,j+=oe[ee++]<>>16^65535)){F.msg="invalid stored block lengths",y.mode=Q;break}if(y.length=j&65535,j=0,z=0,y.mode=W,G===w)break e;case W:y.mode=ne;case ne:if(ce=y.length,ce){if(ce>ie&&(ce=ie),ce>Je&&(ce=Je),ce===0)break e;s.arraySet(Ae,oe,ee,ce,Qe),ie-=ce,ee+=ce,Je-=ce,Qe+=ce,y.length-=ce;break}y.mode=B;break;case xe:for(;z<14;){if(ie===0)break e;ie--,j+=oe[ee++]<>>=5,z-=5,y.ndist=(j&31)+1,j>>>=5,z-=5,y.ncode=(j&15)+4,j>>>=4,z-=4,y.nlen>286||y.ndist>30){F.msg="too many length or distance symbols",y.mode=Q;break}y.have=0,y.mode=se;case se:for(;y.have>>=3,z-=3}for(;y.have<19;)y.lens[en[y.have++]]=0;if(y.lencode=y.lendyn,y.lenbits=7,At={bits:y.lenbits},Ft=c(m,y.lens,0,19,y.lencode,0,y.work,At),y.lenbits=At.bits,Ft){F.msg="invalid code lengths set",y.mode=Q;break}y.have=0,y.mode=be;case be:for(;y.have>>24,$e=et>>>16&255,ut=et&65535,!(Me<=z);){if(ie===0)break e;ie--,j+=oe[ee++]<>>=Me,z-=Me,y.lens[y.have++]=ut;else{if(ut===16){for(Ht=Me+2;z>>=Me,z-=Me,y.have===0){F.msg="invalid bit length repeat",y.mode=Q;break}at=y.lens[y.have-1],ce=3+(j&3),j>>>=2,z-=2}else if(ut===17){for(Ht=Me+3;z>>=Me,z-=Me,at=0,ce=3+(j&7),j>>>=3,z-=3}else{for(Ht=Me+7;z>>=Me,z-=Me,at=0,ce=11+(j&127),j>>>=7,z-=7}if(y.have+ce>y.nlen+y.ndist){F.msg="invalid bit length repeat",y.mode=Q;break}for(;ce--;)y.lens[y.have++]=at}}if(y.mode===Q)break;if(y.lens[256]===0){F.msg="invalid code -- missing end-of-block",y.mode=Q;break}if(y.lenbits=9,At={bits:y.lenbits},Ft=c(d,y.lens,0,y.nlen,y.lencode,0,y.work,At),y.lenbits=At.bits,Ft){F.msg="invalid literal/lengths set",y.mode=Q;break}if(y.distbits=6,y.distcode=y.distdyn,At={bits:y.distbits},Ft=c(h,y.lens,y.nlen,y.ndist,y.distcode,0,y.work,At),y.distbits=At.bits,Ft){F.msg="invalid distances set",y.mode=Q;break}if(y.mode=ye,G===w)break e;case ye:y.mode=$;case $:if(ie>=6&&Je>=258){F.next_out=Qe,F.avail_out=Je,F.next_in=ee,F.avail_in=ie,y.hold=j,y.bits=z,l(F,je),Qe=F.next_out,Ae=F.output,Je=F.avail_out,ee=F.next_in,oe=F.input,ie=F.avail_in,j=y.hold,z=y.bits,y.mode===B&&(y.back=-1);break}for(y.back=0;et=y.lencode[j&(1<>>24,$e=et>>>16&255,ut=et&65535,!(Me<=z);){if(ie===0)break e;ie--,j+=oe[ee++]<>pt)],Me=et>>>24,$e=et>>>16&255,ut=et&65535,!(pt+Me<=z);){if(ie===0)break e;ie--,j+=oe[ee++]<>>=pt,z-=pt,y.back+=pt}if(j>>>=Me,z-=Me,y.back+=Me,y.length=ut,$e===0){y.mode=X;break}if($e&32){y.back=-1,y.mode=B;break}if($e&64){F.msg="invalid literal/length code",y.mode=Q;break}y.extra=$e&15,y.mode=_e;case _e:if(y.extra){for(Ht=y.extra;z>>=y.extra,z-=y.extra,y.back+=y.extra}y.was=y.length,y.mode=Fe;case Fe:for(;et=y.distcode[j&(1<>>24,$e=et>>>16&255,ut=et&65535,!(Me<=z);){if(ie===0)break e;ie--,j+=oe[ee++]<>pt)],Me=et>>>24,$e=et>>>16&255,ut=et&65535,!(pt+Me<=z);){if(ie===0)break e;ie--,j+=oe[ee++]<>>=pt,z-=pt,y.back+=pt}if(j>>>=Me,z-=Me,y.back+=Me,$e&64){F.msg="invalid distance code",y.mode=Q;break}y.offset=ut,y.extra=$e&15,y.mode=xt;case xt:if(y.extra){for(Ht=y.extra;z>>=y.extra,z-=y.extra,y.back+=y.extra}if(y.offset>y.dmax){F.msg="invalid distance too far back",y.mode=Q;break}y.mode=Le;case Le:if(Je===0)break e;if(ce=je-Je,y.offset>ce){if(ce=y.offset-ce,ce>y.whave&&y.sane){F.msg="invalid distance too far back",y.mode=Q;break}ce>y.wnext?(ce-=y.wnext,br=y.wsize-ce):br=y.wnext-ce,ce>y.length&&(ce=y.length),Or=y.window}else Or=Ae,br=Qe-y.offset,ce=y.length;ce>Je&&(ce=Je),Je-=ce,y.length-=ce;do Ae[Qe++]=Or[br++];while(--ce);y.length===0&&(y.mode=$);break;case X:if(Je===0)break e;Ae[Qe++]=y.length,Je--,y.mode=$;break;case M:if(y.wrap){for(;z<32;){if(ie===0)break e;ie--,j|=oe[ee++]<=1&&$[Y]===0;Y--);if(A>Y&&(A=Y),Y===0)return E[T++]=1<<24|64<<16|0,E[T++]=1<<24|64<<16|0,I.bits=1,0;for(L=1;L0&&(x===c||Y!==1))return-1;for(_e[1]=0,D=1;Du||x===d&&R>l)return 1;for(;;){Le=D-q,O[S]ye?(X=Fe[xt+O[S]],M=se[be+O[S]]):(X=96,M=0),re=1<>q)+P]=Le<<24|X<<16|M|0;while(P!==0);for(re=1<>=1;if(re!==0?(B&=re-1,B+=re):B=0,S++,--$[D]===0){if(D===Y)break;D=v[_+O[S]]}if(D>A&&(B&ne)!==W){for(q===0&&(q=A),xe+=L,N=D-q,U=1<u||x===d&&R>l)return 1;W=B&ne,E[W]=A<<24|N<<16|xe-T|0}}return B!==0&&(E[xe+B]=D-q<<24|64<<16|0),I.bits=A,0}},{"../utils/common":1}],10:[function(o,n,i){"use strict";n.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],11:[function(o,n,i){"use strict";function s(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}n.exports=s},{}],"/lib/inflate.js":[function(o,n,i){"use strict";var s=o("./zlib/inflate"),a=o("./utils/common"),u=o("./utils/strings"),l=o("./zlib/constants"),c=o("./zlib/messages"),m=o("./zlib/zstream"),d=o("./zlib/gzheader"),h=Object.prototype.toString;function g(C){if(!(this instanceof g))return new g(C);this.options=a.assign({chunkSize:16384,windowBits:0,to:""},C||{});var x=this.options;x.raw&&x.windowBits>=0&&x.windowBits<16&&(x.windowBits=-x.windowBits,x.windowBits===0&&(x.windowBits=-15)),x.windowBits>=0&&x.windowBits<16&&!(C&&C.windowBits)&&(x.windowBits+=32),x.windowBits>15&&x.windowBits<48&&(x.windowBits&15)===0&&(x.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new m,this.strm.avail_out=0;var v=s.inflateInit2(this.strm,x.windowBits);if(v!==l.Z_OK)throw new Error(c[v]);if(this.header=new d,s.inflateGetHeader(this.strm,this.header),x.dictionary&&(typeof x.dictionary=="string"?x.dictionary=u.string2buf(x.dictionary):h.call(x.dictionary)==="[object ArrayBuffer]"&&(x.dictionary=new Uint8Array(x.dictionary)),x.raw&&(v=s.inflateSetDictionary(this.strm,x.dictionary),v!==l.Z_OK)))throw new Error(c[v])}g.prototype.push=function(C,x){var v=this.strm,_=this.options.chunkSize,k=this.options.dictionary,E,T,O,I,J,D=!1;if(this.ended)return!1;T=x===~~x?x:x===!0?l.Z_FINISH:l.Z_NO_FLUSH,typeof C=="string"?v.input=u.binstring2buf(C):h.call(C)==="[object ArrayBuffer]"?v.input=new Uint8Array(C):v.input=C,v.next_in=0,v.avail_in=v.input.length;do{if(v.avail_out===0&&(v.output=new a.Buf8(_),v.next_out=0,v.avail_out=_),E=s.inflate(v,l.Z_NO_FLUSH),E===l.Z_NEED_DICT&&k&&(E=s.inflateSetDictionary(this.strm,k)),E===l.Z_BUF_ERROR&&D===!0&&(E=l.Z_OK,D=!1),E!==l.Z_STREAM_END&&E!==l.Z_OK)return this.onEnd(E),this.ended=!0,!1;v.next_out&&(v.avail_out===0||E===l.Z_STREAM_END||v.avail_in===0&&(T===l.Z_FINISH||T===l.Z_SYNC_FLUSH))&&(this.options.to==="string"?(O=u.utf8border(v.output,v.next_out),I=v.next_out-O,J=u.buf2string(v.output,O),v.next_out=I,v.avail_out=_-I,I&&a.arraySet(v.output,v.output,O,I,0),this.onData(J)):this.onData(a.shrinkBuf(v.output,v.next_out))),v.avail_in===0&&v.avail_out===0&&(D=!0)}while((v.avail_in>0||v.avail_out===0)&&E!==l.Z_STREAM_END);return E===l.Z_STREAM_END&&(T=l.Z_FINISH),T===l.Z_FINISH?(E=s.inflateEnd(this.strm),this.onEnd(E),this.ended=!0,E===l.Z_OK):(T===l.Z_SYNC_FLUSH&&(this.onEnd(l.Z_OK),v.avail_out=0),!0)},g.prototype.onData=function(C){this.chunks.push(C)},g.prototype.onEnd=function(C){C===l.Z_OK&&(this.options.to==="string"?this.result=this.chunks.join(""):this.result=a.flattenChunks(this.chunks)),this.chunks=[],this.err=C,this.msg=this.strm.msg};function b(C,x){var v=new g(x);if(v.push(C,!0),v.err)throw v.msg||c[v.err];return v.result}function w(C,x){return x=x||{},x.raw=!0,b(C,x)}i.Inflate=g,i.inflate=b,i.inflateRaw=w,i.ungzip=b},{"./utils/common":1,"./utils/strings":2,"./zlib/constants":4,"./zlib/gzheader":6,"./zlib/inflate":8,"./zlib/messages":10,"./zlib/zstream":11}]},{},[])("/lib/inflate.js")})();var TM=globalThis.fetch,ca=class{constructor(e,t={},r){this.type=e,this.detail=t,this.msg=r,Object.defineProperty(this,"__mayPropagate",{enumerable:!1,writable:!0}),this.__mayPropagate=!0}preventDefault(){}stopPropagation(){this.__mayPropagate=!1}valueOf(){return this}toString(){return this.msg?`[${this.type} event]: ${this.msg}`:`[${this.type} event]`}},FS=class{constructor(){this.listeners={}}addEventListener(e,t,r){let o=this.listeners[e]||[];r?o.unshift(t):o.push(t),this.listeners[e]=o}removeEventListener(e,t){let r=this.listeners[e]||[],o=r.findIndex(n=>n===t);o>-1&&(r.splice(o,1),this.listeners[e]=r)}dispatch(e){let t=this.listeners[e.type];if(t)for(let r=0,o=t.length;rString.fromCharCode(t)).join("")}var LS=class{constructor(e,t,r){this.name=(r||e.tag||"").trim(),this.length=e.length,this.start=e.offset,this.offset=0,this.data=t,["getInt8","getUint8","getInt16","getUint16","getInt32","getUint32","getBigInt64","getBigUint64"].forEach(o=>{let n=o.replace(/get(Big)?/,"").toLowerCase(),i=parseInt(o.replace(/[^\d]/g,""))/8;Object.defineProperty(this,n,{get:()=>this.getValue(o,i)})})}get currentPosition(){return this.start+this.offset}set currentPosition(e){this.start=e,this.offset=0}skip(e=0,t=8){this.offset+=e*t/8}getValue(e,t){let r=this.start+this.offset;this.offset+=t;try{return this.data[e](r)}catch(o){throw console.error("parser",e,t,this),console.error("parser",this.start,this.offset),o}}flags(e){if(e===8||e===16||e===32||e===64)return this[`uint${e}`].toString(2).padStart(e,0).split("").map(t=>t==="1");console.error("Error parsing flags: flag types can only be 1, 2, 4, or 8 bytes long"),console.trace()}get tag(){let e=this.uint32;return IS([e>>24&255,e>>16&255,e>>8&255,e&255])}get fixed(){let e=this.int16,t=Math.round(1e3*this.uint16/65356);return e+t/1e3}get legacyFixed(){let e=this.uint16,t=this.uint16.toString(16).padStart(4,0);return parseFloat(`${e}.${t}`)}get uint24(){return(this.uint8<<16)+(this.uint8<<8)+this.uint8}get uint128(){let e=0;for(let t=0;t<5;t++){let r=this.uint8;if(e=e*128+(r&127),r<128)break}return e}get longdatetime(){return new Date(AS+1e3*parseInt(this.int64.toString()))}get fword(){return this.int16}get ufword(){return this.uint16}get Offset16(){return this.uint16}get Offset32(){return this.uint32}get F2DOT14(){let e=p.uint16,t=[0,1,-2,-1][e>>14],r=e&16383;return t+r/16384}verifyLength(){this.offset!=this.length&&console.error(`unexpected parsed table size (${this.offset}) for "${this.name}" (expected ${this.length})`)}readBytes(e=0,t=0,r=8,o=!1){if(e=e||this.length,e===0)return[];t&&(this.currentPosition=t);let n=`${o?"":"u"}int${r}`,i=[];for(;e--;)i.push(this[n]);return i}},lt=class{constructor(e){Object.defineProperty(this,"parser",{enumerable:!1,get:()=>e});let r=e.currentPosition;Object.defineProperty(this,"start",{enumerable:!1,get:()=>r})}load(e){Object.keys(e).forEach(t=>{let r=Object.getOwnPropertyDescriptor(e,t);r.get?this[t]=r.get.bind(this):r.value!==void 0&&(this[t]=r.value)}),this.parser.length&&this.parser.verifyLength()}},ke=class extends lt{constructor(e,t,r){let{parser:o,start:n}=super(new LS(e,t,r));Object.defineProperty(this,"p",{enumerable:!1,get:()=>o}),Object.defineProperty(this,"tableStart",{enumerable:!1,get:()=>n})}};function ae(e,t,r){let o;Object.defineProperty(e,t,{get:()=>o||(o=r(),o),enumerable:!0})}var NS=class extends ke{constructor(e,t,r){let{p:o}=super({offset:0,length:12},t,"sfnt");this.version=o.uint32,this.numTables=o.uint16,this.searchRange=o.uint16,this.entrySelector=o.uint16,this.rangeShift=o.uint16,o.verifyLength(),this.directory=[...new Array(this.numTables)].map(n=>new MS(o)),this.tables={},this.directory.forEach(n=>{let i=()=>r(this.tables,{tag:n.tag,offset:n.offset,length:n.length},t);ae(this.tables,n.tag.trim(),i)})}},MS=class{constructor(e){this.tag=e.tag,this.checksum=e.uint32,this.offset=e.uint32,this.length=e.uint32}},xy=wy.inflate||void 0,Sy=void 0,VS=class extends ke{constructor(e,t,r){let{p:o}=super({offset:0,length:44},t,"woff");this.signature=o.tag,this.flavor=o.uint32,this.length=o.uint32,this.numTables=o.uint16,o.uint16,this.totalSfntSize=o.uint32,this.majorVersion=o.uint16,this.minorVersion=o.uint16,this.metaOffset=o.uint32,this.metaLength=o.uint32,this.metaOrigLength=o.uint32,this.privOffset=o.uint32,this.privLength=o.uint32,o.verifyLength(),this.directory=[...new Array(this.numTables)].map(n=>new DS(o)),BS(this,t,r)}},DS=class{constructor(e){this.tag=e.tag,this.offset=e.uint32,this.compLength=e.uint32,this.origLength=e.uint32,this.origChecksum=e.uint32}};function BS(e,t,r){e.tables={},e.directory.forEach(o=>{ae(e.tables,o.tag.trim(),()=>{let n=0,i=t;if(o.compLength!==o.origLength){let s=t.buffer.slice(o.offset,o.offset+o.compLength),a;if(xy)a=xy(new Uint8Array(s));else if(Sy)a=Sy(new Uint8Array(s));else{let u="no brotli decoder available to decode WOFF2 font";throw font.onerror&&font.onerror(u),new Error(u)}i=new DataView(a.buffer)}else n=o.offset;return r(e.tables,{tag:o.tag,offset:n,length:o.origLength},i)})})}var Cy=by,_y=void 0,jS=class extends ke{constructor(e,t,r){let{p:o}=super({offset:0,length:48},t,"woff2");this.signature=o.tag,this.flavor=o.uint32,this.length=o.uint32,this.numTables=o.uint16,o.uint16,this.totalSfntSize=o.uint32,this.totalCompressedSize=o.uint32,this.majorVersion=o.uint16,this.minorVersion=o.uint16,this.metaOffset=o.uint32,this.metaLength=o.uint32,this.metaOrigLength=o.uint32,this.privOffset=o.uint32,this.privLength=o.uint32,o.verifyLength(),this.directory=[...new Array(this.numTables)].map(a=>new zS(o));let n=o.currentPosition;this.directory[0].offset=0,this.directory.forEach((a,u)=>{let l=this.directory[u+1];l&&(l.offset=a.offset+(a.transformLength!==void 0?a.transformLength:a.origLength))});let i,s=t.buffer.slice(n);if(Cy)i=Cy(new Uint8Array(s));else if(_y)i=new Uint8Array(_y(s));else{let a="no brotli decoder available to decode WOFF2 font";throw e.onerror&&e.onerror(a),new Error(a)}HS(this,i,r)}},zS=class{constructor(e){this.flags=e.uint8;let t=this.tagNumber=this.flags&63;t===63?this.tag=e.tag:this.tag=US(t);let o=(this.transformVersion=(this.flags&192)>>6)!==0;(this.tag==="glyf"||this.tag==="loca")&&(o=this.transformVersion!==3),this.origLength=e.uint128,o&&(this.transformLength=e.uint128)}};function HS(e,t,r){e.tables={},e.directory.forEach(o=>{ae(e.tables,o.tag.trim(),()=>{let n=o.offset,i=n+(o.transformLength?o.transformLength:o.origLength),s=new DataView(t.slice(n,i).buffer);try{return r(e.tables,{tag:o.tag,offset:0,length:o.origLength},s)}catch(a){console.error(a)}})})}function US(e){return["cmap","head","hhea","hmtx","maxp","name","OS/2","post","cvt ","fpgm","glyf","loca","prep","CFF ","VORG","EBDT","EBLC","gasp","hdmx","kern","LTSH","PCLT","VDMX","vhea","vmtx","BASE","GDEF","GPOS","GSUB","EBSC","JSTF","MATH","CBDT","CBLC","COLR","CPAL","SVG ","sbix","acnt","avar","bdat","bloc","bsln","cvar","fdsc","feat","fmtx","fvar","gvar","hsty","just","lcar","mort","morx","opbd","prop","trak","Zapf","Silf","Glat","Gloc","Feat","Sill"][e&63]}var Fy={},Ay=!1;Promise.all([Promise.resolve().then(function(){return yC}),Promise.resolve().then(function(){return bC}),Promise.resolve().then(function(){return xC}),Promise.resolve().then(function(){return _C}),Promise.resolve().then(function(){return EC}),Promise.resolve().then(function(){return FC}),Promise.resolve().then(function(){return IC}),Promise.resolve().then(function(){return NC}),Promise.resolve().then(function(){return GC}),Promise.resolve().then(function(){return r_}),Promise.resolve().then(function(){return U_}),Promise.resolve().then(function(){return G_}),Promise.resolve().then(function(){return X_}),Promise.resolve().then(function(){return $_}),Promise.resolve().then(function(){return tR}),Promise.resolve().then(function(){return oR}),Promise.resolve().then(function(){return sR}),Promise.resolve().then(function(){return lR}),Promise.resolve().then(function(){return uR}),Promise.resolve().then(function(){return dR}),Promise.resolve().then(function(){return mR}),Promise.resolve().then(function(){return gR}),Promise.resolve().then(function(){return bR}),Promise.resolve().then(function(){return SR}),Promise.resolve().then(function(){return CR}),Promise.resolve().then(function(){return RR}),Promise.resolve().then(function(){return TR}),Promise.resolve().then(function(){return OR}),Promise.resolve().then(function(){return FR}),Promise.resolve().then(function(){return LR}),Promise.resolve().then(function(){return jR}),Promise.resolve().then(function(){return WR}),Promise.resolve().then(function(){return qR}),Promise.resolve().then(function(){return JR}),Promise.resolve().then(function(){return $R}),Promise.resolve().then(function(){return t2}),Promise.resolve().then(function(){return n2}),Promise.resolve().then(function(){return s2}),Promise.resolve().then(function(){return f2}),Promise.resolve().then(function(){return p2}),Promise.resolve().then(function(){return g2})]).then(e=>{e.forEach(t=>{let r=Object.keys(t)[0];Fy[r]=t[r]}),Ay=!0});function WS(e,t,r){let o=t.tag.replace(/[^\w\d]/g,""),n=Fy[o];return n?new n(t,r,e):(console.warn(`lib-font has no definition for ${o}. The table was skipped.`),{})}function GS(){let e=0;function t(r,o){if(!Ay)return e>10?o(new Error("loading took too long")):(e++,setTimeout(()=>t(r),250));r(WS)}return new Promise((r,o)=>t(r))}function YS(e,t){let r=e.lastIndexOf("."),o=(e.substring(r+1)||"").toLowerCase(),n={ttf:"truetype",otf:"opentype",woff:"woff",woff2:"woff2"}[o];if(n)return n;let i={eot:"The .eot format is not supported: it died in January 12, 2016, when Microsoft retired all versions of IE that didn't already support WOFF.",svg:"The .svg format is not supported: SVG fonts (not to be confused with OpenType with embedded SVG) were so bad we took the entire fonts chapter out of the SVG specification again.",fon:"The .fon format is not supported: this is an ancient Windows bitmap font format.",ttc:"Based on the current CSS specification, font collections are not (yet?) supported."}[o];if(i||(i=`${e} is not a known webfont format.`),t)throw new Error(i);console.warn(`Could not load font: ${i}`)}async function qS(e,t,r={}){if(!globalThis.document)return;let o=YS(t,r.errorOnStyle);if(!o)return;let n=document.createElement("style");n.className="injected-by-Font-js";let i=[];return r.styleRules&&(i=Object.entries(r.styleRules).map(([s,a])=>`${s}: ${a};`)),n.textContent=` @font-face { font-family: "${e}"; - ${s.join(` + ${i.join(` `)} src: url("${t}") format("${o}"); -}`,globalThis.document.head.appendChild(n),n}var lS=[0,1,0,0],cS=[79,84,84,79],uS=[119,79,70,70],fS=[119,79,70,50];function na(e,t){if(e.length===t.length){for(let r=0;r(globalThis.document&&!this.options.skipStyleSheet&&await aS(this.name,e,this.options),this.loadFont(e)))()}async loadFont(e,t){fetch(e).then(r=>pS(r)&&r.arrayBuffer()).then(r=>this.fromDataBuffer(r,t||e)).catch(r=>{let o=new oa("error",r,`Failed to load font at ${t||e}`);this.dispatch(o),this.onerror&&this.onerror(o)})}async fromDataBuffer(e,t){this.fontData=new DataView(e);let r=dS(this.fontData);if(!r)throw new Error(`${t} is either an unsupported font format, or not a font at all.`);await this.parseBasicData(r);let o=new oa("load",{font:this});this.dispatch(o),this.onload&&this.onload(o)}async parseBasicData(e){return sS().then(t=>(e==="SFNT"&&(this.opentype=new Xx(this,this.fontData,t)),e==="WOFF"&&(this.opentype=new Jx(this,this.fontData,t)),e==="WOFF2"&&(this.opentype=new eS(this,this.fontData,t)),this.opentype))}getGlyphId(e){return this.opentype.tables.cmap.getGlyphId(e)}reverse(e){return this.opentype.tables.cmap.reverse(e)}supports(e){return this.getGlyphId(e)!==0}supportsVariation(e){return this.opentype.tables.cmap.supportsVariation(e)!==!1}measureText(e,t=16){if(this.__unloaded)throw new Error("Cannot measure text: font was unloaded. Please reload before calling measureText()");let r=document.createElement("div");r.textContent=e,r.style.fontFamily=this.name,r.style.fontSize=`${t}px`,r.style.color="transparent",r.style.background="transparent",r.style.top="0",r.style.left="0",r.style.position="absolute",document.body.appendChild(r);let o=r.getBoundingClientRect();document.body.removeChild(r);let n=this.opentype.tables["OS/2"];return o.fontSize=t,o.ascender=n.sTypoAscender,o.descender=n.sTypoDescender,o}unload(){if(this.styleElement.parentNode){this.styleElement.parentNode.removeElement(this.styleElement);let e=new oa("unload",{font:this});this.dispatch(e),this.onunload&&this.onunload(e)}this._unloaded=!0}load(){if(this.__unloaded){delete this.__unloaded,document.head.appendChild(this.styleElement);let e=new oa("load",{font:this});this.dispatch(e),this.onload&&this.onload(e)}}};globalThis.Font=ia;var $r=class extends ct{constructor(e,t,r){super(e),this.plaformID=t,this.encodingID=r}},mS=class extends $r{constructor(e,t,r){super(e,t,r),this.format=0,this.length=e.uint16,this.language=e.uint16,this.glyphIdArray=[...new Array(256)].map(o=>e.uint8)}supports(e){return e.charCodeAt&&(e=-1,console.warn("supports(character) not implemented for cmap subtable format 0. only supports(id) is implemented.")),0<=e&&e<=255}reverse(e){return console.warn("reverse not implemented for cmap subtable format 0"),{}}getSupportedCharCodes(){return[{start:1,end:256}]}},hS=class extends $r{constructor(e,t,r){super(e,t,r),this.format=2,this.length=e.uint16,this.language=e.uint16,this.subHeaderKeys=[...new Array(256)].map(i=>e.uint16);let o=Math.max(...this.subHeaderKeys),n=e.currentPosition;ae(this,"subHeaders",()=>(e.currentPosition=n,[...new Array(o)].map(i=>new gS(e))));let s=n+o*8;ae(this,"glyphIndexArray",()=>(e.currentPosition=s,[...new Array(o)].map(i=>e.uint16)))}supports(e){e.charCodeAt&&(e=-1,console.warn("supports(character) not implemented for cmap subtable format 2. only supports(id) is implemented."));let t=e&&255,r=e&&65280,o=this.subHeaders[r],n=this.subHeaders[o],s=n.firstCode,i=s+n.entryCount;return s<=t&&t<=i}reverse(e){return console.warn("reverse not implemented for cmap subtable format 2"),{}}getSupportedCharCodes(e=!1){return e?this.subHeaders.map(t=>({firstCode:t.firstCode,lastCode:t.lastCode})):this.subHeaders.map(t=>({start:t.firstCode,end:t.lastCode}))}},gS=class{constructor(e){this.firstCode=e.uint16,this.entryCount=e.uint16,this.lastCode=this.first+this.entryCount,this.idDelta=e.int16,this.idRangeOffset=e.uint16}},yS=class extends $r{constructor(e,t,r){super(e,t,r),this.format=4,this.length=e.uint16,this.language=e.uint16,this.segCountX2=e.uint16,this.segCount=this.segCountX2/2,this.searchRange=e.uint16,this.entrySelector=e.uint16,this.rangeShift=e.uint16;let o=e.currentPosition;ae(this,"endCode",()=>e.readBytes(this.segCount,o,16));let n=o+2+this.segCountX2;ae(this,"startCode",()=>e.readBytes(this.segCount,n,16));let s=n+this.segCountX2;ae(this,"idDelta",()=>e.readBytes(this.segCount,s,16,!0));let i=s+this.segCountX2;ae(this,"idRangeOffset",()=>e.readBytes(this.segCount,i,16));let a=i+this.segCountX2,u=this.length-(a-this.tableStart);ae(this,"glyphIdArray",()=>e.readBytes(u,a,16)),ae(this,"segments",()=>this.buildSegments(i,a,e))}buildSegments(e,t,r){let o=(n,s)=>{let i=this.startCode[s],a=this.endCode[s],u=this.idDelta[s],l=this.idRangeOffset[s],c=e+2*s,f=[];if(l===0)for(let m=i+u,g=a+u;m<=g;m++)f.push(m);else for(let m=0,g=a-i;m<=g;m++)r.currentPosition=c+l+m*2,f.push(r.uint16);return{startCode:i,endCode:a,idDelta:u,idRangeOffset:l,glyphIDs:f}};return[...new Array(this.segCount)].map(o)}reverse(e){let t=this.segments.find(o=>o.glyphIDs.includes(e));if(!t)return{};let r=t.startCode+t.glyphIDs.indexOf(e);return{code:r,unicode:String.fromCodePoint(r)}}getGlyphId(e){if(e.charCodeAt&&(e=e.charCodeAt(0)),55296<=e&&e<=57343||(e&65534)===65534||(e&65535)===65535)return 0;let t=this.segments.find(r=>r.startCode<=e&&e<=r.endCode);return t?t.glyphIDs[e-t.startCode]:0}supports(e){return this.getGlyphId(e)!==0}getSupportedCharCodes(e=!1){return e?this.segments:this.segments.map(t=>({start:t.startCode,end:t.endCode}))}},vS=class extends $r{constructor(e,t,r){super(e,t,r),this.format=6,this.length=e.uint16,this.language=e.uint16,this.firstCode=e.uint16,this.entryCount=e.uint16,this.lastCode=this.firstCode+this.entryCount-1,ae(this,"glyphIdArray",()=>[...new Array(this.entryCount)].map(n=>e.uint16))}supports(e){if(e.charCodeAt&&(e=-1,console.warn("supports(character) not implemented for cmap subtable format 6. only supports(id) is implemented.")),ethis.firstCode+this.entryCount)return{};let t=e-this.firstCode;return{code:t,unicode:String.fromCodePoint(t)}}reverse(e){let t=this.glyphIdArray.indexOf(e);if(t>-1)return this.firstCode+t}getSupportedCharCodes(e=!1){return e?[{firstCode:this.firstCode,lastCode:this.lastCode}]:[{start:this.firstCode,end:this.lastCode}]}},bS=class extends $r{constructor(e,t,r){super(e,t,r),this.format=8,e.uint16,this.length=e.uint32,this.language=e.uint32,this.is32=[...new Array(8192)].map(n=>e.uint8),this.numGroups=e.uint32,ae(this,"groups",()=>[...new Array(this.numGroups)].map(n=>new wS(e)))}supports(e){return e.charCodeAt&&(e=-1,console.warn("supports(character) not implemented for cmap subtable format 8. only supports(id) is implemented.")),this.groups.findIndex(t=>t.startcharCode<=e&&e<=t.endcharCode)!==-1}reverse(e){return console.warn("reverse not implemented for cmap subtable format 8"),{}}getSupportedCharCodes(e=!1){return e?this.groups:this.groups.map(t=>({start:t.startcharCode,end:t.endcharCode}))}},wS=class{constructor(e){this.startcharCode=e.uint32,this.endcharCode=e.uint32,this.startGlyphID=e.uint32}},xS=class extends $r{constructor(e,t,r){super(e,t,r),this.format=10,e.uint16,this.length=e.uint32,this.language=e.uint32,this.startCharCode=e.uint32,this.numChars=e.uint32,this.endCharCode=this.startCharCode+this.numChars,ae(this,"glyphs",()=>[...new Array(this.numChars)].map(n=>e.uint16))}supports(e){return e.charCodeAt&&(e=-1,console.warn("supports(character) not implemented for cmap subtable format 10. only supports(id) is implemented.")),ethis.startCharCode+this.numChars?!1:e-this.startCharCode}reverse(e){return console.warn("reverse not implemented for cmap subtable format 10"),{}}getSupportedCharCodes(e=!1){return e?[{startCharCode:this.startCharCode,endCharCode:this.endCharCode}]:[{start:this.startCharCode,end:this.endCharCode}]}},SS=class extends $r{constructor(e,t,r){super(e,t,r),this.format=12,e.uint16,this.length=e.uint32,this.language=e.uint32,this.numGroups=e.uint32,ae(this,"groups",()=>[...new Array(this.numGroups)].map(n=>new CS(e)))}supports(e){return e.charCodeAt&&(e=e.charCodeAt(0)),55296<=e&&e<=57343||(e&65534)===65534||(e&65535)===65535?0:this.groups.findIndex(t=>t.startCharCode<=e&&e<=t.endCharCode)!==-1}reverse(e){for(let t of this.groups){let r=t.startGlyphID;if(r>e)continue;if(r===e)return t.startCharCode;if(r+(t.endCharCode-t.startCharCode)({start:t.startCharCode,end:t.endCharCode}))}},CS=class{constructor(e){this.startCharCode=e.uint32,this.endCharCode=e.uint32,this.startGlyphID=e.uint32}},RS=class extends $r{constructor(e,t,r){super(e,t,r),this.format=13,e.uint16,this.length=e.uint32,this.language=e.uint32,this.numGroups=e.uint32;let o=[...new Array(this.numGroups)].map(n=>new ES(e));ae(this,"groups",o)}supports(e){return e.charCodeAt&&(e=e.charCodeAt(0)),this.groups.findIndex(t=>t.startCharCode<=e&&e<=t.endCharCode)!==-1}reverse(e){return console.warn("reverse not implemented for cmap subtable format 13"),{}}getSupportedCharCodes(e=!1){return e?this.groups:this.groups.map(t=>({start:t.startCharCode,end:t.endCharCode}))}},ES=class{constructor(e){this.startCharCode=e.uint32,this.endCharCode=e.uint32,this.glyphID=e.uint32}},TS=class extends $r{constructor(e,t,r){super(e,t,r),this.subTableStart=e.currentPosition,this.format=14,this.length=e.uint32,this.numVarSelectorRecords=e.uint32,ae(this,"varSelectors",()=>[...new Array(this.numVarSelectorRecords)].map(o=>new _S(e)))}supports(){return console.warn("supports not implemented for cmap subtable format 14"),0}getSupportedCharCodes(){return console.warn("getSupportedCharCodes not implemented for cmap subtable format 14"),[]}reverse(e){return console.warn("reverse not implemented for cmap subtable format 14"),{}}supportsVariation(e){let t=this.varSelector.find(r=>r.varSelector===e);return t||!1}getSupportedVariations(){return this.varSelectors.map(e=>e.varSelector)}},_S=class{constructor(e){this.varSelector=e.uint24,this.defaultUVSOffset=e.Offset32,this.nonDefaultUVSOffset=e.Offset32}};function PS(e,t,r){let o=e.uint16;return o===0?new mS(e,t,r):o===2?new hS(e,t,r):o===4?new yS(e,t,r):o===6?new vS(e,t,r):o===8?new bS(e,t,r):o===10?new xS(e,t,r):o===12?new SS(e,t,r):o===13?new RS(e,t,r):o===14?new TS(e,t,r):{}}var OS=class extends Pe{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.numTables=r.uint16,this.encodingRecords=[...new Array(this.numTables)].map(o=>new kS(r,this.tableStart))}getSubTable(e){return this.encodingRecords[e].table}getSupportedEncodings(){return this.encodingRecords.map(e=>({platformID:e.platformID,encodingId:e.encodingID}))}getSupportedCharCodes(e,t){let r=this.encodingRecords.findIndex(n=>n.platformID===e&&n.encodingID===t);return r===-1?!1:this.getSubTable(r).getSupportedCharCodes()}reverse(e){for(let t=0;t{let n=this.getSubTable(o);return n.getGlyphId?(t=n.getGlyphId(e),t!==0):!1}),t}supports(e){return this.encodingRecords.some((t,r)=>{let o=this.getSubTable(r);return o.supports&&o.supports(e)!==!1})}supportsVariation(e){return this.encodingRecords.some((t,r)=>{let o=this.getSubTable(r);return o.supportsVariation&&o.supportsVariation(e)!==!1})}},kS=class{constructor(e,t){let r=this.platformID=e.uint16,o=this.encodingID=e.uint16,n=this.offset=e.Offset32;ae(this,"table",()=>(e.currentPosition=t+n,PS(e,r,o)))}},FS=Object.freeze({__proto__:null,cmap:OS}),AS=class extends Pe{constructor(e,t){let{p:r}=super(e,t);this.load({majorVersion:r.uint16,minorVersion:r.uint16,fontRevision:r.fixed,checkSumAdjustment:r.uint32,magicNumber:r.uint32,flags:r.flags(16),unitsPerEm:r.uint16,created:r.longdatetime,modified:r.longdatetime,xMin:r.int16,yMin:r.int16,xMax:r.int16,yMax:r.int16,macStyle:r.flags(16),lowestRecPPEM:r.uint16,fontDirectionHint:r.uint16,indexToLocFormat:r.uint16,glyphDataFormat:r.uint16})}},IS=Object.freeze({__proto__:null,head:AS}),LS=class extends Pe{constructor(e,t){let{p:r}=super(e,t);this.majorVersion=r.uint16,this.minorVersion=r.uint16,this.ascender=r.fword,this.descender=r.fword,this.lineGap=r.fword,this.advanceWidthMax=r.ufword,this.minLeftSideBearing=r.fword,this.minRightSideBearing=r.fword,this.xMaxExtent=r.fword,this.caretSlopeRise=r.int16,this.caretSlopeRun=r.int16,this.caretOffset=r.int16,r.int16,r.int16,r.int16,r.int16,this.metricDataFormat=r.int16,this.numberOfHMetrics=r.uint16,r.verifyLength()}},NS=Object.freeze({__proto__:null,hhea:LS}),DS=class extends Pe{constructor(e,t,r){let{p:o}=super(e,t),n=r.hhea.numberOfHMetrics,s=r.maxp.numGlyphs,i=o.currentPosition;if(ae(this,"hMetrics",()=>(o.currentPosition=i,[...new Array(n)].map(a=>new MS(o.uint16,o.int16)))),n(o.currentPosition=a,[...new Array(s-n)].map(u=>o.int16)))}}},MS=class{constructor(e,t){this.advanceWidth=e,this.lsb=t}},VS=Object.freeze({__proto__:null,hmtx:DS}),BS=class extends Pe{constructor(e,t){let{p:r}=super(e,t);this.version=r.legacyFixed,this.numGlyphs=r.uint16,this.version===1&&(this.maxPoints=r.uint16,this.maxContours=r.uint16,this.maxCompositePoints=r.uint16,this.maxCompositeContours=r.uint16,this.maxZones=r.uint16,this.maxTwilightPoints=r.uint16,this.maxStorage=r.uint16,this.maxFunctionDefs=r.uint16,this.maxInstructionDefs=r.uint16,this.maxStackElements=r.uint16,this.maxSizeOfInstructions=r.uint16,this.maxComponentElements=r.uint16,this.maxComponentDepth=r.uint16),r.verifyLength()}},jS=Object.freeze({__proto__:null,maxp:BS}),zS=class extends Pe{constructor(e,t){let{p:r}=super(e,t);this.format=r.uint16,this.count=r.uint16,this.stringOffset=r.Offset16,this.nameRecords=[...new Array(this.count)].map(o=>new HS(r,this)),this.format===1&&(this.langTagCount=r.uint16,this.langTagRecords=[...new Array(this.langTagCount)].map(o=>new US(r.uint16,r.Offset16))),this.stringStart=this.tableStart+this.stringOffset}get(e){let t=this.nameRecords.find(r=>r.nameID===e);if(t)return t.string}},US=class{constructor(e,t){this.length=e,this.offset=t}},HS=class{constructor(e,t){this.platformID=e.uint16,this.encodingID=e.uint16,this.languageID=e.uint16,this.nameID=e.uint16,this.length=e.uint16,this.offset=e.Offset16,ae(this,"string",()=>(e.currentPosition=t.stringStart+this.offset,WS(e,this)))}};function WS(e,t){let{platformID:r,length:o}=t;if(o===0)return"";if(r===0||r===3){let i=[];for(let a=0,u=o/2;ar.uint8),this.ulUnicodeRange1=r.flags(32),this.ulUnicodeRange2=r.flags(32),this.ulUnicodeRange3=r.flags(32),this.ulUnicodeRange4=r.flags(32),this.achVendID=r.tag,this.fsSelection=r.uint16,this.usFirstCharIndex=r.uint16,this.usLastCharIndex=r.uint16,this.sTypoAscender=r.int16,this.sTypoDescender=r.int16,this.sTypoLineGap=r.int16,this.usWinAscent=r.uint16,this.usWinDescent=r.uint16,this.version===0||(this.ulCodePageRange1=r.flags(32),this.ulCodePageRange2=r.flags(32),this.version===1)||(this.sxHeight=r.int16,this.sCapHeight=r.int16,this.usDefaultChar=r.uint16,this.usBreakChar=r.uint16,this.usMaxContext=r.uint16,this.version<=4)||(this.usLowerOpticalPointSize=r.uint16,this.usUpperOpticalPointSize=r.uint16,this.version===5))return r.verifyLength()}},qS=Object.freeze({__proto__:null,OS2:YS}),ZS=class extends Pe{constructor(e,t){let{p:r}=super(e,t);if(this.version=r.legacyFixed,this.italicAngle=r.fixed,this.underlinePosition=r.fword,this.underlineThickness=r.fword,this.isFixedPitch=r.uint32,this.minMemType42=r.uint32,this.maxMemType42=r.uint32,this.minMemType1=r.uint32,this.maxMemType1=r.uint32,this.version===1||this.version===3)return r.verifyLength();if(this.numGlyphs=r.uint16,this.version===2){this.glyphNameIndex=[...new Array(this.numGlyphs)].map(o=>r.uint16),this.namesOffset=r.currentPosition,this.glyphNameOffsets=[1];for(let o=0;or.int8))}getGlyphName(e){if(this.version!==2)return console.warn(`post table version ${this.version} does not support glyph name lookups`),"";let t=this.glyphNameIndex[e];if(t<258)return ey[t];let r=this.glyphNameOffsets[e],n=this.glyphNameOffsets[e+1]-r-1;return n===0?".notdef.":(this.parser.currentPosition=this.namesOffset+r,this.parser.readBytes(n,this.namesOffset+r,8,!0).map(i=>String.fromCharCode(i)).join(""))}},ey=[".notdef",".null","nonmarkingreturn","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quotesingle","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","grave","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","Adieresis","Aring","Ccedilla","Eacute","Ntilde","Odieresis","Udieresis","aacute","agrave","acircumflex","adieresis","atilde","aring","ccedilla","eacute","egrave","ecircumflex","edieresis","iacute","igrave","icircumflex","idieresis","ntilde","oacute","ograve","ocircumflex","odieresis","otilde","uacute","ugrave","ucircumflex","udieresis","dagger","degree","cent","sterling","section","bullet","paragraph","germandbls","registered","copyright","trademark","acute","dieresis","notequal","AE","Oslash","infinity","plusminus","lessequal","greaterequal","yen","mu","partialdiff","summation","product","pi","integral","ordfeminine","ordmasculine","Omega","ae","oslash","questiondown","exclamdown","logicalnot","radical","florin","approxequal","Delta","guillemotleft","guillemotright","ellipsis","nonbreakingspace","Agrave","Atilde","Otilde","OE","oe","endash","emdash","quotedblleft","quotedblright","quoteleft","quoteright","divide","lozenge","ydieresis","Ydieresis","fraction","currency","guilsinglleft","guilsinglright","fi","fl","daggerdbl","periodcentered","quotesinglbase","quotedblbase","perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave","Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex","apple","Ograve","Uacute","Ucircumflex","Ugrave","dotlessi","circumflex","tilde","macron","breve","dotaccent","ring","cedilla","hungarumlaut","ogonek","caron","Lslash","lslash","Scaron","scaron","Zcaron","zcaron","brokenbar","Eth","eth","Yacute","yacute","Thorn","thorn","minus","multiply","onesuperior","twosuperior","threesuperior","onehalf","onequarter","threequarters","franc","Gbreve","gbreve","Idotaccent","Scedilla","scedilla","Cacute","cacute","Ccaron","ccaron","dcroat"],XS=Object.freeze({__proto__:null,post:ZS}),KS=class extends Pe{constructor(e,t){let{p:r}=super(e,t);this.majorVersion=r.uint16,this.minorVersion=r.uint16,this.horizAxisOffset=r.Offset16,this.vertAxisOffset=r.Offset16,ae(this,"horizAxis",()=>new Yc({offset:e.offset+this.horizAxisOffset},t)),ae(this,"vertAxis",()=>new Yc({offset:e.offset+this.vertAxisOffset},t)),this.majorVersion===1&&this.minorVersion===1&&(this.itemVarStoreOffset=r.Offset32,ae(this,"itemVarStore",()=>new Yc({offset:e.offset+this.itemVarStoreOffset},t)))}},Yc=class extends Pe{constructor(e,t){let{p:r}=super(e,t,"AxisTable");this.baseTagListOffset=r.Offset16,this.baseScriptListOffset=r.Offset16,ae(this,"baseTagList",()=>new JS({offset:e.offset+this.baseTagListOffset},t)),ae(this,"baseScriptList",()=>new QS({offset:e.offset+this.baseScriptListOffset},t))}},JS=class extends Pe{constructor(e,t){let{p:r}=super(e,t,"BaseTagListTable");this.baseTagCount=r.uint16,this.baselineTags=[...new Array(this.baseTagCount)].map(o=>r.tag)}},QS=class extends Pe{constructor(e,t){let{p:r}=super(e,t,"BaseScriptListTable");this.baseScriptCount=r.uint16;let o=r.currentPosition;ae(this,"baseScriptRecords",()=>(r.currentPosition=o,[...new Array(this.baseScriptCount)].map(n=>new $S(this.start,r))))}},$S=class{constructor(e,t){this.baseScriptTag=t.tag,this.baseScriptOffset=t.Offset16,ae(this,"baseScriptTable",()=>(t.currentPosition=e+this.baseScriptOffset,new eC(t)))}},eC=class{constructor(e){this.start=e.currentPosition,this.baseValuesOffset=e.Offset16,this.defaultMinMaxOffset=e.Offset16,this.baseLangSysCount=e.uint16,this.baseLangSysRecords=[...new Array(this.baseLangSysCount)].map(t=>new tC(this.start,e)),ae(this,"baseValues",()=>(e.currentPosition=this.start+this.baseValuesOffset,new rC(e))),ae(this,"defaultMinMax",()=>(e.currentPosition=this.start+this.defaultMinMaxOffset,new ly(e)))}},tC=class{constructor(e,t){this.baseLangSysTag=t.tag,this.minMaxOffset=t.Offset16,ae(this,"minMax",()=>(t.currentPosition=e+this.minMaxOffset,new ly(t)))}},rC=class{constructor(e){this.parser=e,this.start=e.currentPosition,this.defaultBaselineIndex=e.uint16,this.baseCoordCount=e.uint16,this.baseCoords=[...new Array(this.baseCoordCount)].map(t=>e.Offset16)}getTable(e){return this.parser.currentPosition=this.start+this.baseCoords[e],new nC(this.parser)}},ly=class{constructor(e){this.minCoord=e.Offset16,this.maxCoord=e.Offset16,this.featMinMaxCount=e.uint16;let t=e.currentPosition;ae(this,"featMinMaxRecords",()=>(e.currentPosition=t,[...new Array(this.featMinMaxCount)].map(r=>new oC(e))))}},oC=class{constructor(e){this.featureTableTag=e.tag,this.minCoord=e.Offset16,this.maxCoord=e.Offset16}},nC=class{constructor(e){this.baseCoordFormat=e.uint16,this.coordinate=e.int16,this.baseCoordFormat===2&&(this.referenceGlyph=e.uint16,this.baseCoordPoint=e.uint16),this.baseCoordFormat===3&&(this.deviceTable=e.Offset16)}},sC=Object.freeze({__proto__:null,BASE:KS}),ty=class{constructor(e){this.classFormat=e.uint16,this.classFormat===1&&(this.startGlyphID=e.uint16,this.glyphCount=e.uint16,this.classValueArray=[...new Array(this.glyphCount)].map(t=>e.uint16)),this.classFormat===2&&(this.classRangeCount=e.uint16,this.classRangeRecords=[...new Array(this.classRangeCount)].map(t=>new iC(e)))}},iC=class{constructor(e){this.startGlyphID=e.uint16,this.endGlyphID=e.uint16,this.class=e.uint16}},xs=class extends ct{constructor(e){super(e),this.coverageFormat=e.uint16,this.coverageFormat===1&&(this.glyphCount=e.uint16,this.glyphArray=[...new Array(this.glyphCount)].map(t=>e.uint16)),this.coverageFormat===2&&(this.rangeCount=e.uint16,this.rangeRecords=[...new Array(this.rangeCount)].map(t=>new aC(e)))}},aC=class{constructor(e){this.startGlyphID=e.uint16,this.endGlyphID=e.uint16,this.startCoverageIndex=e.uint16}},lC=class{constructor(e,t){this.table=e,this.parser=t,this.start=t.currentPosition,this.format=t.uint16,this.variationRegionListOffset=t.Offset32,this.itemVariationDataCount=t.uint16,this.itemVariationDataOffsets=[...new Array(this.itemVariationDataCount)].map(r=>t.Offset32)}},cC=class extends Pe{constructor(e,t){let{p:r}=super(e,t);this.majorVersion=r.uint16,this.minorVersion=r.uint16,this.glyphClassDefOffset=r.Offset16,ae(this,"glyphClassDefs",()=>{if(this.glyphClassDefOffset!==0)return r.currentPosition=this.tableStart+this.glyphClassDefOffset,new ty(r)}),this.attachListOffset=r.Offset16,ae(this,"attachList",()=>{if(this.attachListOffset!==0)return r.currentPosition=this.tableStart+this.attachListOffset,new uC(r)}),this.ligCaretListOffset=r.Offset16,ae(this,"ligCaretList",()=>{if(this.ligCaretListOffset!==0)return r.currentPosition=this.tableStart+this.ligCaretListOffset,new dC(r)}),this.markAttachClassDefOffset=r.Offset16,ae(this,"markAttachClassDef",()=>{if(this.markAttachClassDefOffset!==0)return r.currentPosition=this.tableStart+this.markAttachClassDefOffset,new ty(r)}),this.minorVersion>=2&&(this.markGlyphSetsDefOffset=r.Offset16,ae(this,"markGlyphSetsDef",()=>{if(this.markGlyphSetsDefOffset!==0)return r.currentPosition=this.tableStart+this.markGlyphSetsDefOffset,new hC(r)})),this.minorVersion===3&&(this.itemVarStoreOffset=r.Offset32,ae(this,"itemVarStore",()=>{if(this.itemVarStoreOffset!==0)return r.currentPosition=this.tableStart+this.itemVarStoreOffset,new lC(r)}))}},uC=class extends ct{constructor(e){super(e),this.coverageOffset=e.Offset16,this.glyphCount=e.uint16,this.attachPointOffsets=[...new Array(this.glyphCount)].map(t=>e.Offset16)}getPoint(e){return this.parser.currentPosition=this.start+this.attachPointOffsets[e],new fC(this.parser)}},fC=class{constructor(e){this.pointCount=e.uint16,this.pointIndices=[...new Array(this.pointCount)].map(t=>e.uint16)}},dC=class extends ct{constructor(e){super(e),this.coverageOffset=e.Offset16,ae(this,"coverage",()=>(e.currentPosition=this.start+this.coverageOffset,new xs(e))),this.ligGlyphCount=e.uint16,this.ligGlyphOffsets=[...new Array(this.ligGlyphCount)].map(t=>e.Offset16)}getLigGlyph(e){return this.parser.currentPosition=this.start+this.ligGlyphOffsets[e],new pC(this.parser)}},pC=class extends ct{constructor(e){super(e),this.caretCount=e.uint16,this.caretValueOffsets=[...new Array(this.caretCount)].map(t=>e.Offset16)}getCaretValue(e){return this.parser.currentPosition=this.start+this.caretValueOffsets[e],new mC(this.parser)}},mC=class{constructor(e){this.caretValueFormat=e.uint16,this.caretValueFormat===1&&(this.coordinate=e.int16),this.caretValueFormat===2&&(this.caretValuePointIndex=e.uint16),this.caretValueFormat===3&&(this.coordinate=e.int16,this.deviceOffset=e.Offset16)}},hC=class extends ct{constructor(e){super(e),this.markGlyphSetTableFormat=e.uint16,this.markGlyphSetCount=e.uint16,this.coverageOffsets=[...new Array(this.markGlyphSetCount)].map(t=>e.Offset32)}getMarkGlyphSet(e){return this.parser.currentPosition=this.start+this.coverageOffsets[e],new xs(this.parser)}},gC=Object.freeze({__proto__:null,GDEF:cC}),ry=class extends ct{static EMPTY={scriptCount:0,scriptRecords:[]};constructor(e){super(e),this.scriptCount=e.uint16,this.scriptRecords=[...new Array(this.scriptCount)].map(t=>new yC(e))}},yC=class{constructor(e){this.scriptTag=e.tag,this.scriptOffset=e.Offset16}},vC=class extends ct{constructor(e){super(e),this.defaultLangSys=e.Offset16,this.langSysCount=e.uint16,this.langSysRecords=[...new Array(this.langSysCount)].map(t=>new bC(e))}},bC=class{constructor(e){this.langSysTag=e.tag,this.langSysOffset=e.Offset16}},oy=class{constructor(e){this.lookupOrder=e.Offset16,this.requiredFeatureIndex=e.uint16,this.featureIndexCount=e.uint16,this.featureIndices=[...new Array(this.featureIndexCount)].map(t=>e.uint16)}},ny=class extends ct{static EMPTY={featureCount:0,featureRecords:[]};constructor(e){super(e),this.featureCount=e.uint16,this.featureRecords=[...new Array(this.featureCount)].map(t=>new wC(e))}},wC=class{constructor(e){this.featureTag=e.tag,this.featureOffset=e.Offset16}},xC=class extends ct{constructor(e){super(e),this.featureParams=e.Offset16,this.lookupIndexCount=e.uint16,this.lookupListIndices=[...new Array(this.lookupIndexCount)].map(t=>e.uint16)}getFeatureParams(){if(this.featureParams>0){let e=this.parser;e.currentPosition=this.start+this.featureParams;let t=this.featureTag;if(t==="size")return new CC(e);if(t.startsWith("cc"))return new SC(e);if(t.startsWith("ss"))return new RC(e)}}},SC=class{constructor(e){this.format=e.uint16,this.featUiLabelNameId=e.uint16,this.featUiTooltipTextNameId=e.uint16,this.sampleTextNameId=e.uint16,this.numNamedParameters=e.uint16,this.firstParamUiLabelNameId=e.uint16,this.charCount=e.uint16,this.character=[...new Array(this.charCount)].map(t=>e.uint24)}},CC=class{constructor(e){this.designSize=e.uint16,this.subfamilyIdentifier=e.uint16,this.subfamilyNameID=e.uint16,this.smallEnd=e.uint16,this.largeEnd=e.uint16}},RC=class{constructor(e){this.version=e.uint16,this.UINameID=e.uint16}};function cy(e){e.parser.currentPosition-=2,delete e.coverageOffset,delete e.getCoverageTable}var Zo=class extends ct{constructor(e){super(e),this.substFormat=e.uint16,this.coverageOffset=e.Offset16}getCoverageTable(){let e=this.parser;return e.currentPosition=this.start+this.coverageOffset,new xs(e)}},Zc=class{constructor(e){this.glyphSequenceIndex=e.uint16,this.lookupListIndex=e.uint16}},EC=class extends Zo{constructor(e){super(e),this.deltaGlyphID=e.int16}},TC=class extends Zo{constructor(e){super(e),this.sequenceCount=e.uint16,this.sequenceOffsets=[...new Array(this.sequenceCount)].map(t=>e.Offset16)}getSequence(e){let t=this.parser;return t.currentPosition=this.start+this.sequenceOffsets[e],new _C(t)}},_C=class{constructor(e){this.glyphCount=e.uint16,this.substituteGlyphIDs=[...new Array(this.glyphCount)].map(t=>e.uint16)}},PC=class extends Zo{constructor(e){super(e),this.alternateSetCount=e.uint16,this.alternateSetOffsets=[...new Array(this.alternateSetCount)].map(t=>e.Offset16)}getAlternateSet(e){let t=this.parser;return t.currentPosition=this.start+this.alternateSetOffsets[e],new OC(t)}},OC=class{constructor(e){this.glyphCount=e.uint16,this.alternateGlyphIDs=[...new Array(this.glyphCount)].map(t=>e.uint16)}},kC=class extends Zo{constructor(e){super(e),this.ligatureSetCount=e.uint16,this.ligatureSetOffsets=[...new Array(this.ligatureSetCount)].map(t=>e.Offset16)}getLigatureSet(e){let t=this.parser;return t.currentPosition=this.start+this.ligatureSetOffsets[e],new FC(t)}},FC=class extends ct{constructor(e){super(e),this.ligatureCount=e.uint16,this.ligatureOffsets=[...new Array(this.ligatureCount)].map(t=>e.Offset16)}getLigature(e){let t=this.parser;return t.currentPosition=this.start+this.ligatureOffsets[e],new AC(t)}},AC=class{constructor(e){this.ligatureGlyph=e.uint16,this.componentCount=e.uint16,this.componentGlyphIDs=[...new Array(this.componentCount-1)].map(t=>e.uint16)}},IC=class extends Zo{constructor(e){super(e),this.substFormat===1&&(this.subRuleSetCount=e.uint16,this.subRuleSetOffsets=[...new Array(this.subRuleSetCount)].map(t=>e.Offset16)),this.substFormat===2&&(this.classDefOffset=e.Offset16,this.subClassSetCount=e.uint16,this.subClassSetOffsets=[...new Array(this.subClassSetCount)].map(t=>e.Offset16)),this.substFormat===3&&(cy(this),this.glyphCount=e.uint16,this.substitutionCount=e.uint16,this.coverageOffsets=[...new Array(this.glyphCount)].map(t=>e.Offset16),this.substLookupRecords=[...new Array(this.substitutionCount)].map(t=>new Zc(e)))}getSubRuleSet(e){if(this.substFormat!==1)throw new Error(`lookup type 5.${this.substFormat} has no subrule sets.`);let t=this.parser;return t.currentPosition=this.start+this.subRuleSetOffsets[e],new LC(t)}getSubClassSet(e){if(this.substFormat!==2)throw new Error(`lookup type 5.${this.substFormat} has no subclass sets.`);let t=this.parser;return t.currentPosition=this.start+this.subClassSetOffsets[e],new NC(t)}getCoverageTable(e){if(this.substFormat!==3&&!e)return super.getCoverageTable();if(!e)throw new Error(`lookup type 5.${this.substFormat} requires an coverage table index.`);let t=this.parser;return t.currentPosition=this.start+this.coverageOffsets[e],new xs(t)}},LC=class extends ct{constructor(e){super(e),this.subRuleCount=e.uint16,this.subRuleOffsets=[...new Array(this.subRuleCount)].map(t=>e.Offset16)}getSubRule(e){let t=this.parser;return t.currentPosition=this.start+this.subRuleOffsets[e],new uy(t)}},uy=class{constructor(e){this.glyphCount=e.uint16,this.substitutionCount=e.uint16,this.inputSequence=[...new Array(this.glyphCount-1)].map(t=>e.uint16),this.substLookupRecords=[...new Array(this.substitutionCount)].map(t=>new Zc(e))}},NC=class extends ct{constructor(e){super(e),this.subClassRuleCount=e.uint16,this.subClassRuleOffsets=[...new Array(this.subClassRuleCount)].map(t=>e.Offset16)}getSubClass(e){let t=this.parser;return t.currentPosition=this.start+this.subClassRuleOffsets[e],new DC(t)}},DC=class extends uy{constructor(e){super(e)}},MC=class extends Zo{constructor(e){super(e),this.substFormat===1&&(this.chainSubRuleSetCount=e.uint16,this.chainSubRuleSetOffsets=[...new Array(this.chainSubRuleSetCount)].map(t=>e.Offset16)),this.substFormat===2&&(this.backtrackClassDefOffset=e.Offset16,this.inputClassDefOffset=e.Offset16,this.lookaheadClassDefOffset=e.Offset16,this.chainSubClassSetCount=e.uint16,this.chainSubClassSetOffsets=[...new Array(this.chainSubClassSetCount)].map(t=>e.Offset16)),this.substFormat===3&&(cy(this),this.backtrackGlyphCount=e.uint16,this.backtrackCoverageOffsets=[...new Array(this.backtrackGlyphCount)].map(t=>e.Offset16),this.inputGlyphCount=e.uint16,this.inputCoverageOffsets=[...new Array(this.inputGlyphCount)].map(t=>e.Offset16),this.lookaheadGlyphCount=e.uint16,this.lookaheadCoverageOffsets=[...new Array(this.lookaheadGlyphCount)].map(t=>e.Offset16),this.seqLookupCount=e.uint16,this.seqLookupRecords=[...new Array(this.substitutionCount)].map(t=>new fy(e)))}getChainSubRuleSet(e){if(this.substFormat!==1)throw new Error(`lookup type 6.${this.substFormat} has no chainsubrule sets.`);let t=this.parser;return t.currentPosition=this.start+this.chainSubRuleSetOffsets[e],new VC(t)}getChainSubClassSet(e){if(this.substFormat!==2)throw new Error(`lookup type 6.${this.substFormat} has no chainsubclass sets.`);let t=this.parser;return t.currentPosition=this.start+this.chainSubClassSetOffsets[e],new jC(t)}getCoverageFromOffset(e){if(this.substFormat!==3)throw new Error(`lookup type 6.${this.substFormat} does not use contextual coverage offsets.`);let t=this.parser;return t.currentPosition=this.start+e,new xs(t)}},VC=class extends ct{constructor(e){super(e),this.chainSubRuleCount=e.uint16,this.chainSubRuleOffsets=[...new Array(this.chainSubRuleCount)].map(t=>e.Offset16)}getSubRule(e){let t=this.parser;return t.currentPosition=this.start+this.chainSubRuleOffsets[e],new BC(t)}},BC=class{constructor(e){this.backtrackGlyphCount=e.uint16,this.backtrackSequence=[...new Array(this.backtrackGlyphCount)].map(t=>e.uint16),this.inputGlyphCount=e.uint16,this.inputSequence=[...new Array(this.inputGlyphCount-1)].map(t=>e.uint16),this.lookaheadGlyphCount=e.uint16,this.lookAheadSequence=[...new Array(this.lookAheadGlyphCount)].map(t=>e.uint16),this.substitutionCount=e.uint16,this.substLookupRecords=[...new Array(this.SubstCount)].map(t=>new Zc(e))}},jC=class extends ct{constructor(e){super(e),this.chainSubClassRuleCount=e.uint16,this.chainSubClassRuleOffsets=[...new Array(this.chainSubClassRuleCount)].map(t=>e.Offset16)}getSubClass(e){let t=this.parser;return t.currentPosition=this.start+this.chainSubRuleOffsets[e],new zC(t)}},zC=class{constructor(e){this.backtrackGlyphCount=e.uint16,this.backtrackSequence=[...new Array(this.backtrackGlyphCount)].map(t=>e.uint16),this.inputGlyphCount=e.uint16,this.inputSequence=[...new Array(this.inputGlyphCount-1)].map(t=>e.uint16),this.lookaheadGlyphCount=e.uint16,this.lookAheadSequence=[...new Array(this.lookAheadGlyphCount)].map(t=>e.uint16),this.substitutionCount=e.uint16,this.substLookupRecords=[...new Array(this.substitutionCount)].map(t=>new fy(e))}},fy=class extends ct{constructor(e){super(e),this.sequenceIndex=e.uint16,this.lookupListIndex=e.uint16}},UC=class extends ct{constructor(e){super(e),this.substFormat=e.uint16,this.extensionLookupType=e.uint16,this.extensionOffset=e.Offset32}},HC=class extends Zo{constructor(e){super(e),this.backtrackGlyphCount=e.uint16,this.backtrackCoverageOffsets=[...new Array(this.backtrackGlyphCount)].map(t=>e.Offset16),this.lookaheadGlyphCount=e.uint16,this.lookaheadCoverageOffsets=[new Array(this.lookaheadGlyphCount)].map(t=>e.Offset16),this.glyphCount=e.uint16,this.substituteGlyphIDs=[...new Array(this.glyphCount)].map(t=>e.uint16)}},WC={buildSubtable:function(e,t){let r=new[void 0,EC,TC,PC,kC,IC,MC,UC,HC][e](t);return r.type=e,r}},eo=class extends ct{constructor(e){super(e)}},GC=class extends eo{constructor(e){super(e),console.log("lookup type 1")}},YC=class extends eo{constructor(e){super(e),console.log("lookup type 2")}},qC=class extends eo{constructor(e){super(e),console.log("lookup type 3")}},ZC=class extends eo{constructor(e){super(e),console.log("lookup type 4")}},XC=class extends eo{constructor(e){super(e),console.log("lookup type 5")}},KC=class extends eo{constructor(e){super(e),console.log("lookup type 6")}},JC=class extends eo{constructor(e){super(e),console.log("lookup type 7")}},QC=class extends eo{constructor(e){super(e),console.log("lookup type 8")}},$C=class extends eo{constructor(e){super(e),console.log("lookup type 9")}},eR={buildSubtable:function(e,t){let r=new[void 0,GC,YC,qC,ZC,XC,KC,JC,QC,$C][e](t);return r.type=e,r}},sy=class extends ct{static EMPTY={lookupCount:0,lookups:[]};constructor(e){super(e),this.lookupCount=e.uint16,this.lookups=[...new Array(this.lookupCount)].map(t=>e.Offset16)}},tR=class extends ct{constructor(e,t){super(e),this.ctType=t,this.lookupType=e.uint16,this.lookupFlag=e.uint16,this.subTableCount=e.uint16,this.subtableOffsets=[...new Array(this.subTableCount)].map(r=>e.Offset16),this.markFilteringSet=e.uint16}get rightToLeft(){return this.lookupFlag&!0}get ignoreBaseGlyphs(){return this.lookupFlag&!0}get ignoreLigatures(){return this.lookupFlag&!0}get ignoreMarks(){return this.lookupFlag&!0}get useMarkFilteringSet(){return this.lookupFlag&!0}get markAttachmentType(){return this.lookupFlag&!0}getSubTable(e){let t=this.ctType==="GSUB"?WC:eR;return this.parser.currentPosition=this.start+this.subtableOffsets[e],t.buildSubtable(this.lookupType,this.parser)}},dy=class extends Pe{constructor(e,t,r){let{p:o,tableStart:n}=super(e,t,r);this.majorVersion=o.uint16,this.minorVersion=o.uint16,this.scriptListOffset=o.Offset16,this.featureListOffset=o.Offset16,this.lookupListOffset=o.Offset16,this.majorVersion===1&&this.minorVersion===1&&(this.featureVariationsOffset=o.Offset32);let s=!(this.scriptListOffset||this.featureListOffset||this.lookupListOffset);ae(this,"scriptList",()=>s?ry.EMPTY:(o.currentPosition=n+this.scriptListOffset,new ry(o))),ae(this,"featureList",()=>s?ny.EMPTY:(o.currentPosition=n+this.featureListOffset,new ny(o))),ae(this,"lookupList",()=>s?sy.EMPTY:(o.currentPosition=n+this.lookupListOffset,new sy(o))),this.featureVariationsOffset&&ae(this,"featureVariations",()=>s?FeatureVariations.EMPTY:(o.currentPosition=n+this.featureVariationsOffset,new FeatureVariations(o)))}getSupportedScripts(){return this.scriptList.scriptRecords.map(e=>e.scriptTag)}getScriptTable(e){let t=this.scriptList.scriptRecords.find(o=>o.scriptTag===e);this.parser.currentPosition=this.scriptList.start+t.scriptOffset;let r=new vC(this.parser);return r.scriptTag=e,r}ensureScriptTable(e){return typeof e=="string"?this.getScriptTable(e):e}getSupportedLangSys(e){e=this.ensureScriptTable(e);let t=e.defaultLangSys!==0,r=e.langSysRecords.map(o=>o.langSysTag);return t&&r.unshift("dflt"),r}getDefaultLangSysTable(e){e=this.ensureScriptTable(e);let t=e.defaultLangSys;if(t!==0){this.parser.currentPosition=e.start+t;let r=new oy(this.parser);return r.langSysTag="",r.defaultForScript=e.scriptTag,r}}getLangSysTable(e,t="dflt"){if(t==="dflt")return this.getDefaultLangSysTable(e);e=this.ensureScriptTable(e);let r=e.langSysRecords.find(n=>n.langSysTag===t);this.parser.currentPosition=e.start+r.langSysOffset;let o=new oy(this.parser);return o.langSysTag=t,o}getFeatures(e){return e.featureIndices.map(t=>this.getFeature(t))}getFeature(e){let t;if(parseInt(e)==e?t=this.featureList.featureRecords[e]:t=this.featureList.featureRecords.find(o=>o.featureTag===e),!t)return;this.parser.currentPosition=this.featureList.start+t.featureOffset;let r=new xC(this.parser);return r.featureTag=t.featureTag,r}getLookups(e){return e.lookupListIndices.map(t=>this.getLookup(t))}getLookup(e,t){let r=this.lookupList.lookups[e];return this.parser.currentPosition=this.lookupList.start+r,new tR(this.parser,t)}},rR=class extends dy{constructor(e,t){super(e,t,"GSUB")}getLookup(e){return super.getLookup(e,"GSUB")}},oR=Object.freeze({__proto__:null,GSUB:rR}),nR=class extends dy{constructor(e,t){super(e,t,"GPOS")}getLookup(e){return super.getLookup(e,"GPOS")}},sR=Object.freeze({__proto__:null,GPOS:nR}),iR=class extends Pe{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.offsetToSVGDocumentList=r.Offset32,r.currentPosition=this.tableStart+this.offsetToSVGDocumentList,this.documentList=new aR(r)}},aR=class extends ct{constructor(e){super(e),this.numEntries=e.uint16,this.documentRecords=[...new Array(this.numEntries)].map(t=>new lR(e))}getDocument(e){let t=this.documentRecords[e];if(!t)return"";let r=this.start+t.svgDocOffset;return this.parser.currentPosition=r,this.parser.readBytes(t.svgDocLength)}getDocumentForGlyph(e){let t=this.documentRecords.findIndex(r=>r.startGlyphID<=e&&e<=r.endGlyphID);return t===-1?"":this.getDocument(t)}},lR=class{constructor(e){this.startGlyphID=e.uint16,this.endGlyphID=e.uint16,this.svgDocOffset=e.Offset32,this.svgDocLength=e.uint32}},cR=Object.freeze({__proto__:null,SVG:iR}),uR=class extends Pe{constructor(e,t){let{p:r}=super(e,t);this.majorVersion=r.uint16,this.minorVersion=r.uint16,this.axesArrayOffset=r.Offset16,r.uint16,this.axisCount=r.uint16,this.axisSize=r.uint16,this.instanceCount=r.uint16,this.instanceSize=r.uint16;let o=this.tableStart+this.axesArrayOffset;ae(this,"axes",()=>(r.currentPosition=o,[...new Array(this.axisCount)].map(s=>new fR(r))));let n=o+this.axisCount*this.axisSize;ae(this,"instances",()=>{let s=[];for(let i=0;ie.tag)}getAxis(e){return this.axes.find(t=>t.tag===e)}},fR=class{constructor(e){this.tag=e.tag,this.minValue=e.fixed,this.defaultValue=e.fixed,this.maxValue=e.fixed,this.flags=e.flags(16),this.axisNameID=e.uint16}},dR=class{constructor(e,t,r){let o=e.currentPosition;this.subfamilyNameID=e.uint16,e.uint16,this.coordinates=[...new Array(t)].map(n=>e.fixed),e.currentPosition-o[...new Array(o)].map(n=>r.fword))}},hR=Object.freeze({__proto__:null,cvt:mR}),gR=class extends Pe{constructor(e,t){let{p:r}=super(e,t);ae(this,"instructions",()=>[...new Array(e.length)].map(o=>r.uint8))}},yR=Object.freeze({__proto__:null,fpgm:gR}),vR=class extends Pe{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.numRanges=r.uint16,ae(this,"gaspRanges",()=>[...new Array(this.numRanges)].map(n=>new bR(r)))}},bR=class{constructor(e){this.rangeMaxPPEM=e.uint16,this.rangeGaspBehavior=e.uint16}},wR=Object.freeze({__proto__:null,gasp:vR}),xR=class extends Pe{constructor(e,t){super(e,t)}getGlyphData(e,t){return this.parser.currentPosition=this.tableStart+e,this.parser.readBytes(t)}},SR=Object.freeze({__proto__:null,glyf:xR}),CR=class extends Pe{constructor(e,t,r){let{p:o}=super(e,t),n=r.maxp.numGlyphs+1;r.head.indexToLocFormat===0?(this.x2=!0,ae(this,"offsets",()=>[...new Array(n)].map(s=>o.Offset16))):ae(this,"offsets",()=>[...new Array(n)].map(s=>o.Offset32))}getGlyphDataOffsetAndLength(e){let t=this.offsets[e]*this.x2?2:1,r=this.offsets[e+1]*this.x2?2:1;return{offset:t,length:r-t}}},RR=Object.freeze({__proto__:null,loca:CR}),ER=class extends Pe{constructor(e,t){let{p:r}=super(e,t);ae(this,"instructions",()=>[...new Array(e.length)].map(o=>r.uint8))}},TR=Object.freeze({__proto__:null,prep:ER}),_R=class extends Pe{constructor(e,t){let{p:r}=super(e,t);ae(this,"data",()=>r.readBytes())}},PR=Object.freeze({__proto__:null,CFF:_R}),OR=class extends Pe{constructor(e,t){let{p:r}=super(e,t);ae(this,"data",()=>r.readBytes())}},kR=Object.freeze({__proto__:null,CFF2:OR}),FR=class extends Pe{constructor(e,t){let{p:r}=super(e,t);this.majorVersion=r.uint16,this.minorVersion=r.uint16,this.defaultVertOriginY=r.int16,this.numVertOriginYMetrics=r.uint16,ae(this,"vertORiginYMetrics",()=>[...new Array(this.numVertOriginYMetrics)].map(o=>new AR(r)))}},AR=class{constructor(e){this.glyphIndex=e.uint16,this.vertOriginY=e.int16}},IR=Object.freeze({__proto__:null,VORG:FR}),LR=class{constructor(e){this.indexSubTableArrayOffset=e.Offset32,this.indexTablesSize=e.uint32,this.numberofIndexSubTables=e.uint32,this.colorRef=e.uint32,this.hori=new sa(e),this.vert=new sa(e),this.startGlyphIndex=e.uint16,this.endGlyphIndex=e.uint16,this.ppemX=e.uint8,this.ppemY=e.uint8,this.bitDepth=e.uint8,this.flags=e.int8}},NR=class{constructor(e){this.hori=new sa(e),this.vert=new sa(e),this.ppemX=e.uint8,this.ppemY=e.uint8,this.substitutePpemX=e.uint8,this.substitutePpemY=e.uint8}},sa=class{constructor(e){this.ascender=e.int8,this.descender=e.int8,this.widthMax=e.uint8,this.caretSlopeNumerator=e.int8,this.caretSlopeDenominator=e.int8,this.caretOffset=e.int8,this.minOriginSB=e.int8,this.minAdvanceSB=e.int8,this.maxBeforeBL=e.int8,this.minAfterBL=e.int8,this.pad1=e.int8,this.pad2=e.int8}},py=class extends Pe{constructor(e,t,r){let{p:o}=super(e,t,r);this.majorVersion=o.uint16,this.minorVersion=o.uint16,this.numSizes=o.uint32,ae(this,"bitMapSizes",()=>[...new Array(this.numSizes)].map(n=>new LR(o)))}},DR=Object.freeze({__proto__:null,EBLC:py}),my=class extends Pe{constructor(e,t,r){let{p:o}=super(e,t,r);this.majorVersion=o.uint16,this.minorVersion=o.uint16}},MR=Object.freeze({__proto__:null,EBDT:my}),VR=class extends Pe{constructor(e,t){let{p:r}=super(e,t);this.majorVersion=r.uint16,this.minorVersion=r.uint16,this.numSizes=r.uint32,ae(this,"bitmapScales",()=>[...new Array(this.numSizes)].map(o=>new NR(r)))}},BR=Object.freeze({__proto__:null,EBSC:VR}),jR=class extends py{constructor(e,t){super(e,t,"CBLC")}},zR=Object.freeze({__proto__:null,CBLC:jR}),UR=class extends my{constructor(e,t){super(e,t,"CBDT")}},HR=Object.freeze({__proto__:null,CBDT:UR}),WR=class extends Pe{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.flags=r.flags(16),this.numStrikes=r.uint32,ae(this,"strikeOffsets",()=>[...new Array(this.numStrikes)].map(o=>r.Offset32))}},GR=Object.freeze({__proto__:null,sbix:WR}),YR=class extends Pe{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.numBaseGlyphRecords=r.uint16,this.baseGlyphRecordsOffset=r.Offset32,this.layerRecordsOffset=r.Offset32,this.numLayerRecords=r.uint16}getBaseGlyphRecord(e){let t=this.tableStart+this.baseGlyphRecordsOffset;this.parser.currentPosition=t;let r=new qc(this.parser),o=r.gID,n=this.tableStart+this.layerRecordsOffset-6;this.parser.currentPosition=n;let s=new qc(this.parser),i=s.gID;if(o===e)return r;if(i===e)return s;for(;t!==n;){let a=t+(n-t)/12;this.parser.currentPosition=a;let u=new qc(this.parser),l=u.gID;if(l===e)return u;l>e?n=a:lnew qR(p))}},qc=class{constructor(e){this.gID=e.uint16,this.firstLayerIndex=e.uint16,this.numLayers=e.uint16}},qR=class{constructor(e){this.gID=e.uint16,this.paletteIndex=e.uint16}},ZR=Object.freeze({__proto__:null,COLR:YR}),XR=class extends Pe{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.numPaletteEntries=r.uint16;let o=this.numPalettes=r.uint16;this.numColorRecords=r.uint16,this.offsetFirstColorRecord=r.Offset32,this.colorRecordIndices=[...new Array(this.numPalettes)].map(n=>r.uint16),ae(this,"colorRecords",()=>(r.currentPosition=this.tableStart+this.offsetFirstColorRecord,[...new Array(this.numColorRecords)].map(n=>new KR(r)))),this.version===1&&(this.offsetPaletteTypeArray=r.Offset32,this.offsetPaletteLabelArray=r.Offset32,this.offsetPaletteEntryLabelArray=r.Offset32,ae(this,"paletteTypeArray",()=>(r.currentPosition=this.tableStart+this.offsetPaletteTypeArray,new JR(r,o))),ae(this,"paletteLabelArray",()=>(r.currentPosition=this.tableStart+this.offsetPaletteLabelArray,new QR(r,o))),ae(this,"paletteEntryLabelArray",()=>(r.currentPosition=this.tableStart+this.offsetPaletteEntryLabelArray,new $R(r,o))))}},KR=class{constructor(e){this.blue=e.uint8,this.green=e.uint8,this.red=e.uint8,this.alpha=e.uint8}},JR=class{constructor(e,t){this.paletteTypes=[...new Array(t)].map(r=>e.uint32)}},QR=class{constructor(e,t){this.paletteLabels=[...new Array(t)].map(r=>e.uint16)}},$R=class{constructor(e,t){this.paletteEntryLabels=[...new Array(t)].map(r=>e.uint16)}},eE=Object.freeze({__proto__:null,CPAL:XR}),tE=class extends Pe{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint32,this.numSignatures=r.uint16,this.flags=r.uint16,this.signatureRecords=[...new Array(this.numSignatures)].map(o=>new rE(r))}getData(e){let t=this.signatureRecords[e];return this.parser.currentPosition=this.tableStart+t.offset,new oE(this.parser)}},rE=class{constructor(e){this.format=e.uint32,this.length=e.uint32,this.offset=e.Offset32}},oE=class{constructor(e){e.uint16,e.uint16,this.signatureLength=e.uint32,this.signature=e.readBytes(this.signatureLength)}},nE=Object.freeze({__proto__:null,DSIG:tE}),sE=class extends Pe{constructor(e,t,r){let{p:o}=super(e,t),n=r.hmtx.numGlyphs;this.version=o.uint16,this.numRecords=o.int16,this.sizeDeviceRecord=o.int32,this.records=[...new Array(numRecords)].map(s=>new iE(o,n))}},iE=class{constructor(e,t){this.pixelSize=e.uint8,this.maxWidth=e.uint8,this.widths=e.readBytes(t)}},aE=Object.freeze({__proto__:null,hdmx:sE}),lE=class extends Pe{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.nTables=r.uint16,ae(this,"tables",()=>{let o=this.tableStart+4,n=[];for(let s=0;s[...new Array(this.nPairs)].map(t=>new uE(e)))),this.format===2&&console.warn("Kern subtable format 2 is not supported: this parser currently only parses universal table data.")}get horizontal(){return this.coverage[0]}get minimum(){return this.coverage[1]}get crossstream(){return this.coverage[2]}get override(){return this.coverage[3]}},uE=class{constructor(e){this.left=e.uint16,this.right=e.uint16,this.value=e.fword}},fE=Object.freeze({__proto__:null,kern:lE}),dE=class extends Pe{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.numGlyphs=r.uint16,this.yPels=r.readBytes(this.numGlyphs)}},pE=Object.freeze({__proto__:null,LTSH:dE}),mE=class extends Pe{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.mergeClassCount=r.uint16,this.mergeDataOffset=r.Offset16,this.classDefCount=r.uint16,this.offsetToClassDefOffsets=r.Offset16,ae(this,"mergeEntryMatrix",()=>[...new Array(this.mergeClassCount)].map(o=>r.readBytes(this.mergeClassCount))),console.warn("Full MERG parsing is currently not supported."),console.warn("If you need this table parsed, please file an issue, or better yet, a PR.")}},hE=Object.freeze({__proto__:null,MERG:mE}),gE=class extends Pe{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint32,this.flags=r.uint32,r.uint32,this.dataMapsCount=r.uint32,this.dataMaps=[...new Array(this.dataMapsCount)].map(o=>new yE(this.tableStart,r))}},yE=class{constructor(e,t){this.tableStart=e,this.parser=t,this.tag=t.tag,this.dataOffset=t.Offset32,this.dataLength=t.uint32}getData(){return this.parser.currentField=this.tableStart+this.dataOffset,this.parser.readBytes(this.dataLength)}},vE=Object.freeze({__proto__:null,meta:gE}),bE=class extends Pe{constructor(e,t){super(e,t),console.warn("This font uses a PCLT table, which is currently not supported by this parser."),console.warn("If you need this table parsed, please file an issue, or better yet, a PR.")}},wE=Object.freeze({__proto__:null,PCLT:bE}),xE=class extends Pe{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.numRecs=r.uint16,this.numRatios=r.uint16,this.ratRanges=[...new Array(this.numRatios)].map(o=>new SE(r)),this.offsets=[...new Array(this.numRatios)].map(o=>r.Offset16),this.VDMXGroups=[...new Array(this.numRecs)].map(o=>new CE(r))}},SE=class{constructor(e){this.bCharSet=e.uint8,this.xRatio=e.uint8,this.yStartRatio=e.uint8,this.yEndRatio=e.uint8}},CE=class{constructor(e){this.recs=e.uint16,this.startsz=e.uint8,this.endsz=e.uint8,this.records=[...new Array(this.recs)].map(t=>new RE(e))}},RE=class{constructor(e){this.yPelHeight=e.uint16,this.yMax=e.int16,this.yMin=e.int16}},EE=Object.freeze({__proto__:null,VDMX:xE}),TE=class extends Pe{constructor(e,t){let{p:r}=super(e,t);this.version=r.fixed,this.ascent=this.vertTypoAscender=r.int16,this.descent=this.vertTypoDescender=r.int16,this.lineGap=this.vertTypoLineGap=r.int16,this.advanceHeightMax=r.int16,this.minTopSideBearing=r.int16,this.minBottomSideBearing=r.int16,this.yMaxExtent=r.int16,this.caretSlopeRise=r.int16,this.caretSlopeRun=r.int16,this.caretOffset=r.int16,this.reserved=r.int16,this.reserved=r.int16,this.reserved=r.int16,this.reserved=r.int16,this.metricDataFormat=r.int16,this.numOfLongVerMetrics=r.uint16,r.verifyLength()}},_E=Object.freeze({__proto__:null,vhea:TE}),PE=class extends Pe{constructor(e,t,r){super(e,t);let o=r.vhea.numOfLongVerMetrics,n=r.maxp.numGlyphs,s=p.currentPosition;if(lazy(this,"vMetrics",()=>(p.currentPosition=s,[...new Array(o)].map(i=>new OE(p.uint16,p.int16)))),o(p.currentPosition=i,[...new Array(n-o)].map(a=>p.int16)))}}},OE=class{constructor(e,t){this.advanceHeight=e,this.topSideBearing=t}},kE=Object.freeze({__proto__:null,vmtx:PE});function hy(e){let t=e.reduce((r,o)=>(r[o.fontFamily]||(r[o.fontFamily]={name:o.fontFamily,fontFamily:o.fontFamily,slug:Hi(o.fontFamily.toLowerCase()),fontFace:[]}),r[o.fontFamily].fontFace.push(o),r),{});return Object.values(t)}var Jt=h(Y(),1);function FE(){let{installFonts:e}=(0,Ss.useContext)(Mt),[t,r]=(0,Ss.useState)(!1),[o,n]=(0,Ss.useState)(null),s=g=>{a(g)},i=g=>{a(g.target.files)},a=async g=>{if(!g)return;n(null),r(!0);let d=new Set,v=[...g],x=!1,C=v.map(async b=>{if(!await l(b))return x=!0,null;if(d.has(b.name))return null;let A=(((b.name??"").split(".")??[]).pop()??"").toLowerCase();return Uc.includes(A)?(d.add(b.name),b):null}),w=(await Promise.all(C)).filter(b=>b!==null);if(w.length>0)u(w);else{let b=x?(0,Dn.__)("Sorry, you are not allowed to upload this file type."):(0,Dn.__)("No fonts found to install.");n({type:"error",message:b}),r(!1)}},u=async g=>{let d=await Promise.all(g.map(async v=>{let x=await f(v);return await xo(x,x.file,"all"),x}));m(d)};async function l(g){let d=new ia("Uploaded Font");try{let v=await c(g);return await d.fromDataBuffer(v,"font"),!0}catch{return!1}}async function c(g){return new Promise((d,v)=>{let x=new window.FileReader;x.readAsArrayBuffer(g),x.onload=()=>d(x.result),x.onerror=v})}let f=async g=>{let d=await c(g),v=new ia("Uploaded Font");v.fromDataBuffer(d,g.name);let C=(await new Promise(N=>v.onload=N)).detail.font,{name:w}=C.opentype.tables,b=w.get(16)||w.get(1),R=w.get(2).toLowerCase().includes("italic"),A=C.opentype.tables["OS/2"].usWeightClass||"normal",_=!!C.opentype.tables.fvar&&C.opentype.tables.fvar.axes.find(({tag:N})=>N==="wght"),P=_?`${_.minValue} ${_.maxValue}`:null;return{file:g,fontFamily:b,fontStyle:R?"italic":"normal",fontWeight:P||A}},m=async g=>{let d=hy(g);try{await e(d),n({type:"success",message:(0,Dn.__)("Fonts were installed successfully.")})}catch(v){let x=v;n({type:"error",message:x.message,errors:x?.installationErrors})}r(!1)};return(0,Jt.jsxs)("div",{className:"font-library__tabpanel-layout",children:[(0,Jt.jsx)(Ft.DropZone,{onFilesDrop:s}),(0,Jt.jsxs)(Ft.__experimentalVStack,{className:"font-library__local-fonts",justify:"start",children:[o&&(0,Jt.jsxs)(Ft.Notice,{status:o.type,__unstableHTML:!0,onRemove:()=>n(null),children:[o.message,o.errors&&(0,Jt.jsx)("ul",{children:o.errors.map((g,d)=>(0,Jt.jsx)("li",{children:g},d))})]}),t&&(0,Jt.jsx)(Ft.FlexItem,{children:(0,Jt.jsx)("div",{className:"font-library__upload-area",children:(0,Jt.jsx)(Ft.ProgressBar,{})})}),!t&&(0,Jt.jsx)(Ft.FormFileUpload,{accept:Uc.map(g=>`.${g}`).join(","),multiple:!0,onChange:i,render:({openFileDialog:g})=>(0,Jt.jsx)(Ft.Button,{__next40pxDefaultSize:!0,className:"font-library__upload-area",onClick:g,children:(0,Dn.__)("Upload font")})}),(0,Jt.jsx)(Ft.__experimentalText,{className:"font-library__upload-area__text",children:(0,Dn.__)("Uploaded fonts appear in your library and can be used in your theme. Supported formats: .ttf, .otf, .woff, and .woff2.")})]})]})}var aa=FE;var yy=h(Y(),1),{Tabs:HV}=Be(Xc.privateApis),WV={id:"installed-fonts",title:(0,la._x)("Library","Font library")},GV={id:"upload-fonts",title:(0,la._x)("Upload","noun")};var vy=h(xe(),1),Kc=h(ce(),1),IE=h(ke(),1);var by=h(Y(),1);var Jc=h(Y(),1);var wy=h(xe(),1),ca=h(ce(),1);var xy=h(Y(),1);var $c=h(Y(),1);var mr=h(xe(),1),eu=h(ce(),1),zE=h(ke(),1);var Sy=h(Dt(),1);var BE=h(Y(),1),{useSettingsForBlockElement:xB,TypographyPanel:SB}=Be(Sy.privateApis);var jE=h(Y(),1);var tu=h(Y(),1),FB={text:{description:(0,mr.__)("Manage the fonts used on the site."),title:(0,mr.__)("Text")},link:{description:(0,mr.__)("Manage the fonts and typography used on the links."),title:(0,mr.__)("Links")},heading:{description:(0,mr.__)("Manage the fonts and typography used on headings."),title:(0,mr.__)("Headings")},caption:{description:(0,mr.__)("Manage the fonts and typography used on captions."),title:(0,mr.__)("Captions")},button:{description:(0,mr.__)("Manage the fonts and typography used on buttons."),title:(0,mr.__)("Buttons")}};var GE=h(xe(),1),YE=h(ce(),1),Ry=h(Dt(),1);var Mn=h(ce(),1),Cy=h(xe(),1);var WE=h(ke(),1);var UE=h(ce(),1),HE=h(Y(),1);var ru=h(Y(),1);var ou=h(Y(),1),{useSettingsForBlockElement:qB,ColorPanel:ZB}=Be(Ry.privateApis);var $E=h(xe(),1);var XE=h(No(),1),nu=h(ce(),1),KE=h(xe(),1);var fa=h(ce(),1);var ua=h(ce(),1);var Ey=h(Y(),1);function Ty(){let{paletteColors:e}=Tn();return e.slice(0,4).map(({slug:t,color:r},o)=>(0,Ey.jsx)("div",{style:{flexGrow:1,height:"100%",background:r}},`${t}-${o}`))}var Rs=h(Y(),1),qE={start:{scale:1,opacity:1},hover:{scale:0,opacity:0}},ZE=({label:e,isFocused:t,withHoverView:r})=>(0,Rs.jsx)(On,{label:e,isFocused:t,withHoverView:r,children:({key:o})=>(0,Rs.jsx)(ua.__unstableMotion.div,{variants:qE,style:{height:"100%",overflow:"hidden"},children:(0,Rs.jsx)(ua.__experimentalHStack,{spacing:0,justify:"center",style:{height:"100%",overflow:"hidden"},children:(0,Rs.jsx)(Ty,{})})},o)}),_y=ZE;var Xo=h(Y(),1),Py=["color"];function da({title:e,gap:t=2}){let r=Ni(Py);return r?.length<=1?null:(0,Xo.jsxs)(fa.__experimentalVStack,{spacing:3,children:[e&&(0,Xo.jsx)(ur,{level:3,children:e}),(0,Xo.jsx)(fa.__experimentalGrid,{gap:t,children:r.map((o,n)=>(0,Xo.jsx)(Fn,{variation:o,isPill:!0,properties:Py,showTooltip:!0,children:()=>(0,Xo.jsx)(_y,{})},n))})]})}var Oy=h(Y(),1);var JE=h(No(),1),pa=h(ce(),1),QE=h(xe(),1);var ky=h(Y(),1);var su=h(Y(),1);var t2=h(xe(),1),Ay=h(Dt(),1),r2=h(ce(),1);var Fy=h(Dt(),1);var e2=h(Y(),1);var{BackgroundPanel:xj}=Be(Fy.privateApis);var iu=h(Y(),1),{useHasBackgroundPanel:Pj}=Be(Ay.privateApis);var Ly=h(xe(),1);var Es=h(ce(),1),i2=h(xe(),1);var a2=h(ke(),1);var o2=h(ce(),1),n2=h(xe(),1),s2=h(Y(),1);var Iy=h(Y(),1),{Menu:Dj}=Be(Es.privateApis);var lu=h(Y(),1);var hr=h(ce(),1),My=h(xe(),1);var ma=h(ke(),1);var Ts=h(ce(),1);var Ny=h(Y(),1),{Menu:Kj}=Be(Ts.privateApis);var u2=h(ce(),1),f2=h(xe(),1),d2=h(Y(),1);var cu=h(ce(),1),p2=h(xe(),1),m2=h(ke(),1);var Dy=h(Y(),1);var uu=h(Y(),1);var v2=h(Y(),1);var x2=h(xe(),1),By=h(Dt(),1);var Vy=h(Dt(),1),b2=h(ke(),1);var w2=h(Y(),1),{useSettingsForBlockElement:xz,DimensionsPanel:Sz}=Be(Vy.privateApis);var fu=h(Y(),1),{useHasDimensionsPanel:Oz,useSettingsForBlockElement:kz}=Be(By.privateApis);var Gy=h(ce(),1),E2=h(xe(),1);var C2=h(xe(),1),R2=h(ce(),1);var jy=h(nr(),1),zy=h(Xt(),1),ga=h(ke(),1),Uy=h(ce(),1),Hy=h(xe(),1);var ha=h(Y(),1);function S2({gap:e=2}){let{user:t}=(0,ga.useContext)(Tt),r=t?.styles,n=(0,zy.useSelect)(i=>{let a=i(jy.store).__experimentalGetCurrentThemeGlobalStylesVariations();return Array.isArray(a)?a:void 0},[])?.filter(i=>!hs(i,["color"])&&!hs(i,["typography","spacing"])),s=(0,ga.useMemo)(()=>[...[{title:(0,Hy.__)("Default"),settings:{},styles:{}},...n??[]].map(a=>{let u=a?.styles?.blocks?{...a.styles.blocks}:{};r?.blocks&&Object.keys(r.blocks).forEach(m=>{if(r.blocks?.[m]?.css){let g=u[m]||{},d={css:`${u[m]?.css||""} ${r.blocks?.[m]?.css?.trim()||""}`};u[m]={...g,...d}}});let l=r?.css||a.styles?.css?{css:`${a.styles?.css||""} ${r?.css||""}`}:{},c=Object.keys(u).length>0?{blocks:u}:{},f={...a.styles,...l,...c};return{...a,settings:a.settings??{},styles:f}})],[n,r?.blocks,r?.css]);return!n||n.length<1?null:(0,ha.jsx)(Uy.__experimentalGrid,{columns:2,className:"global-styles-ui-style-variations-container",gap:e,children:s.map((i,a)=>(0,ha.jsx)(Fn,{variation:i,children:u=>(0,ha.jsx)(Ic,{label:i?.title,withHoverView:!0,isFocused:u,variation:i})},a))})}var du=S2;var Wy=h(Y(),1);var pu=h(Y(),1);var T2=h(xe(),1),_2=h(ce(),1),Yy=h(Dt(),1);var mu=h(Y(),1),{AdvancedPanel:Zz}=Be(Yy.privateApis);var ev=h(xe(),1),gu=h(ce(),1),yu=h(ke(),1);var P2=h(Xt(),1),O2=h(nr(),1),qy=h(ke(),1);var Ky=h(xe(),1),ya=h(ce(),1),va=h(Xy(),1),k2=h(nr(),1),F2=h(Xt(),1);var Jy=h(jc(),1);var Qy=h(Y(),1),{Badge:e7}=Be(ya.privateApis),t7=3600*1e3*24;var hu=h(ce(),1),_s=h(xe(),1);var $y=h(Y(),1);var vu=h(Y(),1);var tv=h(xe(),1),rv=h(ce(),1);var ov=h(Y(),1);var sv=h(xe(),1),Ps=h(ce(),1),iv=h(ke(),1);var I2=h(Dt(),1),L2=h(xe(),1);var N2=h(Y(),1);var to=h(ce(),1),nv=h(Y(),1);var bu=h(Y(),1);var xu=h(Y(),1);var Su=h(Y(),1);function Vn(e){return function({value:r,baseValue:o,onChange:n,...s}){return(0,Su.jsx)(ms,{value:r,baseValue:o,onChange:n,children:(0,Su.jsx)(e,{...s})})}}var B2=Vn(du);var j2=Vn(da);var z2=Vn(Ui);var Bn=h(Y(),1);function Cu({value:e,baseValue:t,onChange:r,activeTab:o="installed-fonts"}){let n;switch(o){case"upload-fonts":n=(0,Bn.jsx)(aa,{});break;case"installed-fonts":n=(0,Bn.jsx)(Qi,{});break;default:n=(0,Bn.jsx)(ea,{slug:o})}return(0,Bn.jsx)(ms,{value:e,baseValue:t,onChange:r,children:(0,Bn.jsx)(Yi,{children:n})})}var cv=h(as()),{unlock:Ru}=(0,cv.__dangerousOptInToUnstableAPIsOnlyForCoreModules)("I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.","@wordpress/font-list-route");if(typeof document<"u"&&!document.head.querySelector("style[data-wp-hash='9553e553cd']")){let e=document.createElement("style");e.setAttribute("data-wp-hash","9553e553cd"),e.appendChild(document.createTextNode('@media (min-width:782px){.font-library-modal.font-library-modal{width:65vw}}.font-library-modal .components-modal__header{border-bottom:none}.font-library-modal .components-modal__content{margin-bottom:90px;padding:0}.font-library-modal .font-library__subtitle{font-size:11px;font-weight:var(--wpds-typography-font-weight-emphasis,600);text-transform:uppercase}.font-library-modal__tab-panel{height:calc(100% - 50px)}.font-library__tabpanel-layout{display:flex;flex-direction:column;height:100%}.font-library__tabpanel-layout>div{flex-grow:1}.font-library__tabpanel-layout .font-library__loading{align-items:center;box-sizing:border-box;display:flex;height:100%;justify-content:center;left:0;padding-top:124px;position:absolute;top:0;width:100%}.font-library__footer,.font-library__tabpanel-layout .components-navigator-screen{padding:24px;width:100%}.font-library__footer{background-color:#fff;border-top:1px solid #ddd;bottom:0;box-sizing:border-box;flex-grow:0!important;flex-shrink:0;height:90px;position:absolute}.font-library__page-selection{font-size:11px;font-weight:var(--wpds-typography-font-weight-emphasis,600);text-transform:uppercase}@media (min-width:600px){.font-library__page-selection .components-select-control__input{font-size:11px!important;font-weight:var(--wpds-typography-font-weight-emphasis,600)}}.font-library__search{width:240px}.font-library__fonts-title{font-size:11px;font-weight:var(--wpds-typography-font-weight-emphasis,600);margin-bottom:0;margin-top:0;text-transform:uppercase}.font-library__fonts-list{list-style:none;margin-bottom:0;margin-top:0;padding:0}.font-library__fonts-list-item{margin-bottom:0}.font-library__font-card{border:1px solid #ddd;box-sizing:border-box;height:auto!important;margin-top:-1px;padding:16px;width:100%}.font-library__font-card:hover{background-color:#f0f0f0}.font-library__font-card:focus{position:relative}.font-library__font-card .font-library__font-card__name{font-weight:700}.font-library__font-card .font-library__font-card__count{color:#757575}.font-library__font-card .font-library__font-variant_demo-image{display:block;height:24px;width:auto}.font-library__font-card .font-library__font-variant_demo-text{flex-shrink:0;white-space:nowrap}@media not (prefers-reduced-motion){.font-library__font-card .font-library__font-variant_demo-text{transition:opacity .3s ease-in-out}}.font-library-modal__tablist-container{background:#fff;border-bottom:1px solid #ddd;position:sticky;top:0;z-index:1}.font-library__upload-area{align-items:center;display:flex;height:256px!important;justify-content:center;width:100%}button.font-library__upload-area{background-color:#f0f0f0}.font-library__local-fonts{margin:24px auto;width:80%}.font-library__local-fonts .font-library__upload-area__text{color:#757575}.font-library__google-fonts-confirm{align-items:center;display:flex;justify-content:center;margin-top:64px}.font-library__google-fonts-confirm p{line-height:1.4}.font-library__google-fonts-confirm h2{font-size:1.2rem;font-weight:400}.font-library__google-fonts-confirm .components-card{padding:16px;width:400px}.font-library__google-fonts-confirm .components-button{justify-content:center;width:100%}.font-library__select-all{padding:16px 16px 16px 17px}.font-library__select-all .components-checkbox-control__label{padding-left:16px}.global-styles-ui-pagination .components-button.is-tertiary{height:32px;justify-content:center;width:32px}.global-styles-ui-screen-revisions__revisions-list{flex-grow:1;list-style:none;margin:0 16px 16px}.global-styles-ui-screen-revisions__revisions-list li{margin-bottom:0}.global-styles-ui-screen-revisions__revision-item{cursor:var(--wpds-cursor-control,pointer);display:flex;flex-direction:column;position:relative}.global-styles-ui-screen-revisions__revision-item[role=option]:active,.global-styles-ui-screen-revisions__revision-item[role=option]:focus{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid transparent}.global-styles-ui-screen-revisions__revision-item:hover{background:rgba(var(--wp-admin-theme-color--rgb),.04)}.global-styles-ui-screen-revisions__revision-item:hover .global-styles-ui-screen-revisions__date{color:var(--wp-admin-theme-color)}.global-styles-ui-screen-revisions__revision-item:after,.global-styles-ui-screen-revisions__revision-item:before{content:"\\a";display:block;position:absolute}.global-styles-ui-screen-revisions__revision-item:before{background:#ddd;border:4px solid transparent;border-radius:50%;height:8px;left:17px;top:18px;transform:translate(-50%,-50%);width:8px;z-index:1}.global-styles-ui-screen-revisions__revision-item[aria-selected=true]{background:rgba(var(--wp-admin-theme-color--rgb),.04);border-radius:2px;color:var(--wp-admin-theme-color);outline:3px solid transparent;outline-offset:-2px}.global-styles-ui-screen-revisions__revision-item[aria-selected=true] .global-styles-ui-screen-revisions__date{color:var(--wp-admin-theme-color)}.global-styles-ui-screen-revisions__revision-item[aria-selected=true]:before{background:var(--wp-admin-theme-color)}.global-styles-ui-screen-revisions__revision-item[aria-selected=true] .global-styles-ui-screen-revisions__changes>li,.global-styles-ui-screen-revisions__revision-item[aria-selected=true] .global-styles-ui-screen-revisions__meta{color:#1e1e1e}.global-styles-ui-screen-revisions__revision-item:after{border:.5px solid #ddd;height:100%;left:16px;top:0;width:0}.global-styles-ui-screen-revisions__revision-item:first-child:after{top:18px}.global-styles-ui-screen-revisions__revision-item:last-child:after{height:18px}.global-styles-ui-screen-revisions__revision-item-wrapper{display:block;padding:12px 12px 4px 40px}.global-styles-ui-screen-revisions__active-badge,.global-styles-ui-screen-revisions__apply-button.is-primary{align-self:flex-start;margin:0 12px 12px 40px}.global-styles-ui-screen-revisions__changes,.global-styles-ui-screen-revisions__meta{color:#757575;font-size:12px}.global-styles-ui-screen-revisions__description{align-items:flex-start;display:flex;flex-direction:column;gap:8px}.global-styles-ui-screen-revisions__description .global-styles-ui-screen-revisions__date{font-size:12px;font-weight:var(--wpds-typography-font-weight-emphasis,600);text-transform:uppercase}.global-styles-ui-screen-revisions__meta{align-items:flex-start;display:flex;justify-content:start;margin-bottom:4px;text-align:left;width:100%}.global-styles-ui-screen-revisions__meta img{border-radius:100%;height:16px;margin-right:8px;width:16px}.global-styles-ui-screen-revisions__loading{margin:24px auto!important}.global-styles-ui-screen-revisions__changes{line-height:1.4;list-style:disc;margin-left:12px;text-align:left}.global-styles-ui-screen-revisions__changes li{margin-bottom:4px}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination{gap:2px;justify-content:space-between}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .edit-site-pagination__total{height:1px;left:-1000px;margin:-1px;overflow:hidden;position:absolute}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-text{font-size:12px;will-change:opacity}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-button.is-tertiary{color:#1e1e1e}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-button.is-tertiary:disabled,.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-button.is-tertiary[aria-disabled=true]{color:#949494}.global-styles-ui-screen-revisions__footer{background:#fff;border-top:1px solid #ddd;bottom:0;box-sizing:border-box;height:56px;min-width:100%;padding:12px;position:sticky;z-index:1}.global-styles-ui-variations_item{box-sizing:border-box;cursor:var(--wpds-cursor-control,pointer)}.global-styles-ui-variations_item .global-styles-ui-variations_item-preview{border-radius:2px;outline:1px solid rgba(0,0,0,.1);outline-offset:-1px;overflow:hidden;position:relative}@media not (prefers-reduced-motion){.global-styles-ui-variations_item .global-styles-ui-variations_item-preview{transition:outline .1s linear}}.global-styles-ui-variations_item .global-styles-ui-variations_item-preview.is-pill{height:32px}.global-styles-ui-variations_item .global-styles-ui-variations_item-preview.is-pill .block-editor-iframe__scale-container{overflow:hidden}.global-styles-ui-variations_item:not(.is-active):hover .global-styles-ui-variations_item-preview{outline-color:rgba(0,0,0,.3)}.global-styles-ui-variations_item.is-active .global-styles-ui-variations_item-preview,.global-styles-ui-variations_item:focus-visible .global-styles-ui-variations_item-preview{outline-color:#1e1e1e;outline-offset:1px;outline-width:var(--wp-admin-border-width-focus)}.global-styles-ui-variations_item:focus-visible .global-styles-ui-variations_item-preview{outline-color:var(--wp-admin-theme-color)}.global-styles-ui-preview__wrapper{display:block;max-width:100%;width:100%}.global-styles-ui-preview__wrapper.is-hoverable{cursor:var(--wpds-cursor-control,pointer)}.global-styles-ui-typography-preview{align-items:center;background:#f0f0f0;border-radius:2px;display:flex;justify-content:center;margin-bottom:20px;min-height:100px;overflow:hidden}.global-styles-ui-font-size__item{line-break:anywhere;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.global-styles-ui-font-size__item-value{color:#757575}.global-styles-ui-screen-typography__indicator{align-items:center;border-radius:2px;display:flex!important;font-size:14px;height:24px;justify-content:center;width:24px}.global-styles-ui-block-types-search{margin-bottom:10px;padding:0 16px}.global-styles-ui-screen-typography__font-variants-count{color:#757575}.global-styles-ui-font-families__manage-fonts{justify-content:center}.global-styles-ui-screen .color-block-support-panel{border-top:none;padding-left:0;padding-right:0;padding-top:0;row-gap:12px}.global-styles-ui-header{line-height:1.9!important;margin-bottom:0!important}.global-styles-ui-subtitle{font-size:11px!important;font-weight:var(--wpds-typography-font-weight-emphasis,600)!important;margin-bottom:0!important;text-transform:uppercase}.global-styles-ui-section-title{color:#2f2f2f;font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:1.2;margin:0;padding:16px 16px 0}.global-styles-ui-icon-with-current-color{fill:currentColor}.global-styles-ui__color-indicator-wrapper{flex-shrink:0;height:24px}.global-styles-ui__shadows-panel__options-container,.global-styles-ui__typography-panel__options-container{height:24px}.global-styles-ui__block-preview-panel{border:1px solid #ddd;border-radius:2px;overflow:hidden;position:relative;width:100%}.global-styles-ui__shadow-preview-panel{background-image:repeating-linear-gradient(45deg,#e0e0e0 25%,transparent 0,transparent 75%,#e0e0e0 0,#e0e0e0),repeating-linear-gradient(45deg,#e0e0e0 25%,transparent 0,transparent 75%,#e0e0e0 0,#e0e0e0);background-position:0 0,8px 8px;background-size:16px 16px;border:1px solid #ddd;border-radius:2px;height:144px;overflow:auto}.global-styles-ui__shadow-preview-panel .global-styles-ui__shadow-preview-block{background-color:#fff;border:1px solid #ddd;border-radius:2px;height:60px;width:60%}.global-styles-ui__shadow-editor__dropdown-content{width:280px}.global-styles-ui__shadow-editor-panel{margin-bottom:4px}.global-styles-ui__shadow-editor__dropdown{position:relative;width:100%}.global-styles-ui__shadow-editor__dropdown-toggle{border-radius:inherit;height:auto;padding-bottom:8px;padding-top:8px;text-align:left;width:100%}.global-styles-ui__shadow-editor__dropdown-toggle.is-open{background:#f0f0f0;color:var(--wp-admin-theme-color)}.global-styles-ui__shadow-editor__remove-button{opacity:0;position:absolute;right:8px;top:8px}.global-styles-ui__shadow-editor__remove-button.global-styles-ui__shadow-editor__remove-button{border:none}.global-styles-ui__shadow-editor__dropdown-toggle:hover+.global-styles-ui__shadow-editor__remove-button,.global-styles-ui__shadow-editor__remove-button:focus,.global-styles-ui__shadow-editor__remove-button:hover{opacity:1}@media (hover:none){.global-styles-ui__shadow-editor__remove-button{opacity:1}}.global-styles-ui-screen-css{display:flex;flex:1 1 auto;flex-direction:column;margin:16px}.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel{flex:1 1 auto}.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel__custom-css-input,.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel__custom-css-input .components-base-control__field{display:flex;flex:1 1 auto;flex-direction:column}.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel__custom-css-input textarea{flex:1 1 auto}.global-styles-ui-screen-css-help-link{display:inline-block;margin-top:8px}.global-styles-ui-screen-variations{border-top:1px solid #ddd;margin-top:16px}.global-styles-ui-screen-variations>*{margin:24px 16px}.global-styles-ui-sidebar__navigator-provider{height:100%}.global-styles-ui-sidebar__navigator-screen{display:flex;flex-direction:column;height:100%}.global-styles-ui-color-palette__tablist-container{border-bottom:1px solid #ddd}.global-styles-ui-color-palette__tablist{margin-bottom:-1px}.global-styles-ui-sidebar__navigator-screen .single-column{grid-column:span 1}.global-styles-ui-screen-root.global-styles-ui-screen-root,.global-styles-ui-screen-style-variations.global-styles-ui-screen-style-variations{background:unset;color:inherit}.global-styles-ui-sidebar__panel .block-editor-block-icon svg{fill:currentColor}.global-styles-ui-screen-root__active-style-tile.global-styles-ui-screen-root__active-style-tile,.global-styles-ui-screen-root__active-style-tile.global-styles-ui-screen-root__active-style-tile .global-styles-ui-screen-root__active-style-tile-preview{border-radius:2px}.global-styles-ui-screen-root__active-style-tile-preview{clip-path:border-box}.global-styles-ui-color-palette-panel,.global-styles-ui-gradient-palette-panel{padding:16px}.font-library-page__tablist{border-bottom:1px solid #f0f0f0;padding:0 24px}.font-library-page__tab-panel{flex-grow:1;max-height:calc(100% - 110px);overflow:auto}.font-library-page:has(.font-library__footer) .font-library-page__tab-panel{max-height:calc(100% - 198px)}')),document.head.appendChild(e)}var{Tabs:ba}=Ru(uv.privateApis),{useGlobalStyles:U2}=Ru(fv.privateApis);function H2(){let{records:e=[]}=(0,wa.useEntityRecords)("root","fontCollection",{_fields:"slug,name,description"}),[t,r]=(0,pv.useState)("installed-fonts"),{base:o,user:n,setUser:s,isReady:i}=U2(),a=(0,dv.useSelect)(l=>l(wa.store).canUser("create",{kind:"postType",name:"wp_font_family"}),[]);if(!i)return null;let u=[{id:"installed-fonts",title:(0,jn._x)("Library","Font library")}];return a&&(u.push({id:"upload-fonts",title:(0,jn._x)("Upload","noun")}),u.push(...(e||[]).map(({slug:l,name:c})=>({id:l,title:e&&e.length===1&&l==="google-fonts"?(0,jn.__)("Install Fonts"):c})))),React.createElement(ic,{title:(0,jn.__)("Fonts"),className:"font-library-page"},React.createElement(ba,{selectedTabId:t,onSelect:l=>r(l)},React.createElement("div",{className:"font-library-page__tablist"},React.createElement(ba.TabList,null,u.map(({id:l,title:c})=>React.createElement(ba.Tab,{key:l,tabId:l},c)))),u.map(({id:l})=>React.createElement(ba.TabPanel,{key:l,tabId:l,focusable:!1,className:"font-library-page__tab-panel"},React.createElement(Cu,{value:n,baseValue:o,onChange:s,activeTab:l})))))}function W2(){return React.createElement(H2,null)}var G2=W2;export{G2 as stage}; +}`,globalThis.document.head.appendChild(n),n}var ZS=[0,1,0,0],XS=[79,84,84,79],KS=[119,79,70,70],JS=[119,79,70,50];function ua(e,t){if(e.length===t.length){for(let r=0;r(globalThis.document&&!this.options.skipStyleSheet&&await qS(this.name,e,this.options),this.loadFont(e)))()}async loadFont(e,t){fetch(e).then(r=>$S(r)&&r.arrayBuffer()).then(r=>this.fromDataBuffer(r,t||e)).catch(r=>{let o=new ca("error",r,`Failed to load font at ${t||e}`);this.dispatch(o),this.onerror&&this.onerror(o)})}async fromDataBuffer(e,t){this.fontData=new DataView(e);let r=QS(this.fontData);if(!r)throw new Error(`${t} is either an unsupported font format, or not a font at all.`);await this.parseBasicData(r);let o=new ca("load",{font:this});this.dispatch(o),this.onload&&this.onload(o)}async parseBasicData(e){return GS().then(t=>(e==="SFNT"&&(this.opentype=new NS(this,this.fontData,t)),e==="WOFF"&&(this.opentype=new VS(this,this.fontData,t)),e==="WOFF2"&&(this.opentype=new jS(this,this.fontData,t)),this.opentype))}getGlyphId(e){return this.opentype.tables.cmap.getGlyphId(e)}reverse(e){return this.opentype.tables.cmap.reverse(e)}supports(e){return this.getGlyphId(e)!==0}supportsVariation(e){return this.opentype.tables.cmap.supportsVariation(e)!==!1}measureText(e,t=16){if(this.__unloaded)throw new Error("Cannot measure text: font was unloaded. Please reload before calling measureText()");let r=document.createElement("div");r.textContent=e,r.style.fontFamily=this.name,r.style.fontSize=`${t}px`,r.style.color="transparent",r.style.background="transparent",r.style.top="0",r.style.left="0",r.style.position="absolute",document.body.appendChild(r);let o=r.getBoundingClientRect();document.body.removeChild(r);let n=this.opentype.tables["OS/2"];return o.fontSize=t,o.ascender=n.sTypoAscender,o.descender=n.sTypoDescender,o}unload(){if(this.styleElement.parentNode){this.styleElement.parentNode.removeElement(this.styleElement);let e=new ca("unload",{font:this});this.dispatch(e),this.onunload&&this.onunload(e)}this._unloaded=!0}load(){if(this.__unloaded){delete this.__unloaded,document.head.appendChild(this.styleElement);let e=new ca("load",{font:this});this.dispatch(e),this.onload&&this.onload(e)}}};globalThis.Font=da;var oo=class extends lt{constructor(e,t,r){super(e),this.plaformID=t,this.encodingID=r}},eC=class extends oo{constructor(e,t,r){super(e,t,r),this.format=0,this.length=e.uint16,this.language=e.uint16,this.glyphIdArray=[...new Array(256)].map(o=>e.uint8)}supports(e){return e.charCodeAt&&(e=-1,console.warn("supports(character) not implemented for cmap subtable format 0. only supports(id) is implemented.")),0<=e&&e<=255}reverse(e){return console.warn("reverse not implemented for cmap subtable format 0"),{}}getSupportedCharCodes(){return[{start:1,end:256}]}},tC=class extends oo{constructor(e,t,r){super(e,t,r),this.format=2,this.length=e.uint16,this.language=e.uint16,this.subHeaderKeys=[...new Array(256)].map(s=>e.uint16);let o=Math.max(...this.subHeaderKeys),n=e.currentPosition;ae(this,"subHeaders",()=>(e.currentPosition=n,[...new Array(o)].map(s=>new rC(e))));let i=n+o*8;ae(this,"glyphIndexArray",()=>(e.currentPosition=i,[...new Array(o)].map(s=>e.uint16)))}supports(e){e.charCodeAt&&(e=-1,console.warn("supports(character) not implemented for cmap subtable format 2. only supports(id) is implemented."));let t=e&&255,r=e&&65280,o=this.subHeaders[r],n=this.subHeaders[o],i=n.firstCode,s=i+n.entryCount;return i<=t&&t<=s}reverse(e){return console.warn("reverse not implemented for cmap subtable format 2"),{}}getSupportedCharCodes(e=!1){return e?this.subHeaders.map(t=>({firstCode:t.firstCode,lastCode:t.lastCode})):this.subHeaders.map(t=>({start:t.firstCode,end:t.lastCode}))}},rC=class{constructor(e){this.firstCode=e.uint16,this.entryCount=e.uint16,this.lastCode=this.first+this.entryCount,this.idDelta=e.int16,this.idRangeOffset=e.uint16}},oC=class extends oo{constructor(e,t,r){super(e,t,r),this.format=4,this.length=e.uint16,this.language=e.uint16,this.segCountX2=e.uint16,this.segCount=this.segCountX2/2,this.searchRange=e.uint16,this.entrySelector=e.uint16,this.rangeShift=e.uint16;let o=e.currentPosition;ae(this,"endCode",()=>e.readBytes(this.segCount,o,16));let n=o+2+this.segCountX2;ae(this,"startCode",()=>e.readBytes(this.segCount,n,16));let i=n+this.segCountX2;ae(this,"idDelta",()=>e.readBytes(this.segCount,i,16,!0));let s=i+this.segCountX2;ae(this,"idRangeOffset",()=>e.readBytes(this.segCount,s,16));let a=s+this.segCountX2,u=this.length-(a-this.tableStart);ae(this,"glyphIdArray",()=>e.readBytes(u,a,16)),ae(this,"segments",()=>this.buildSegments(s,a,e))}buildSegments(e,t,r){let o=(n,i)=>{let s=this.startCode[i],a=this.endCode[i],u=this.idDelta[i],l=this.idRangeOffset[i],c=e+2*i,m=[];if(l===0)for(let d=s+u,h=a+u;d<=h;d++)m.push(d);else for(let d=0,h=a-s;d<=h;d++)r.currentPosition=c+l+d*2,m.push(r.uint16);return{startCode:s,endCode:a,idDelta:u,idRangeOffset:l,glyphIDs:m}};return[...new Array(this.segCount)].map(o)}reverse(e){let t=this.segments.find(o=>o.glyphIDs.includes(e));if(!t)return{};let r=t.startCode+t.glyphIDs.indexOf(e);return{code:r,unicode:String.fromCodePoint(r)}}getGlyphId(e){if(e.charCodeAt&&(e=e.charCodeAt(0)),55296<=e&&e<=57343||(e&65534)===65534||(e&65535)===65535)return 0;let t=this.segments.find(r=>r.startCode<=e&&e<=r.endCode);return t?t.glyphIDs[e-t.startCode]:0}supports(e){return this.getGlyphId(e)!==0}getSupportedCharCodes(e=!1){return e?this.segments:this.segments.map(t=>({start:t.startCode,end:t.endCode}))}},nC=class extends oo{constructor(e,t,r){super(e,t,r),this.format=6,this.length=e.uint16,this.language=e.uint16,this.firstCode=e.uint16,this.entryCount=e.uint16,this.lastCode=this.firstCode+this.entryCount-1,ae(this,"glyphIdArray",()=>[...new Array(this.entryCount)].map(n=>e.uint16))}supports(e){if(e.charCodeAt&&(e=-1,console.warn("supports(character) not implemented for cmap subtable format 6. only supports(id) is implemented.")),ethis.firstCode+this.entryCount)return{};let t=e-this.firstCode;return{code:t,unicode:String.fromCodePoint(t)}}reverse(e){let t=this.glyphIdArray.indexOf(e);if(t>-1)return this.firstCode+t}getSupportedCharCodes(e=!1){return e?[{firstCode:this.firstCode,lastCode:this.lastCode}]:[{start:this.firstCode,end:this.lastCode}]}},iC=class extends oo{constructor(e,t,r){super(e,t,r),this.format=8,e.uint16,this.length=e.uint32,this.language=e.uint32,this.is32=[...new Array(8192)].map(n=>e.uint8),this.numGroups=e.uint32,ae(this,"groups",()=>[...new Array(this.numGroups)].map(n=>new sC(e)))}supports(e){return e.charCodeAt&&(e=-1,console.warn("supports(character) not implemented for cmap subtable format 8. only supports(id) is implemented.")),this.groups.findIndex(t=>t.startcharCode<=e&&e<=t.endcharCode)!==-1}reverse(e){return console.warn("reverse not implemented for cmap subtable format 8"),{}}getSupportedCharCodes(e=!1){return e?this.groups:this.groups.map(t=>({start:t.startcharCode,end:t.endcharCode}))}},sC=class{constructor(e){this.startcharCode=e.uint32,this.endcharCode=e.uint32,this.startGlyphID=e.uint32}},aC=class extends oo{constructor(e,t,r){super(e,t,r),this.format=10,e.uint16,this.length=e.uint32,this.language=e.uint32,this.startCharCode=e.uint32,this.numChars=e.uint32,this.endCharCode=this.startCharCode+this.numChars,ae(this,"glyphs",()=>[...new Array(this.numChars)].map(n=>e.uint16))}supports(e){return e.charCodeAt&&(e=-1,console.warn("supports(character) not implemented for cmap subtable format 10. only supports(id) is implemented.")),ethis.startCharCode+this.numChars?!1:e-this.startCharCode}reverse(e){return console.warn("reverse not implemented for cmap subtable format 10"),{}}getSupportedCharCodes(e=!1){return e?[{startCharCode:this.startCharCode,endCharCode:this.endCharCode}]:[{start:this.startCharCode,end:this.endCharCode}]}},lC=class extends oo{constructor(e,t,r){super(e,t,r),this.format=12,e.uint16,this.length=e.uint32,this.language=e.uint32,this.numGroups=e.uint32,ae(this,"groups",()=>[...new Array(this.numGroups)].map(n=>new cC(e)))}supports(e){return e.charCodeAt&&(e=e.charCodeAt(0)),55296<=e&&e<=57343||(e&65534)===65534||(e&65535)===65535?0:this.groups.findIndex(t=>t.startCharCode<=e&&e<=t.endCharCode)!==-1}reverse(e){for(let t of this.groups){let r=t.startGlyphID;if(r>e)continue;if(r===e)return t.startCharCode;if(r+(t.endCharCode-t.startCharCode)({start:t.startCharCode,end:t.endCharCode}))}},cC=class{constructor(e){this.startCharCode=e.uint32,this.endCharCode=e.uint32,this.startGlyphID=e.uint32}},uC=class extends oo{constructor(e,t,r){super(e,t,r),this.format=13,e.uint16,this.length=e.uint32,this.language=e.uint32,this.numGroups=e.uint32;let o=[...new Array(this.numGroups)].map(n=>new fC(e));ae(this,"groups",o)}supports(e){return e.charCodeAt&&(e=e.charCodeAt(0)),this.groups.findIndex(t=>t.startCharCode<=e&&e<=t.endCharCode)!==-1}reverse(e){return console.warn("reverse not implemented for cmap subtable format 13"),{}}getSupportedCharCodes(e=!1){return e?this.groups:this.groups.map(t=>({start:t.startCharCode,end:t.endCharCode}))}},fC=class{constructor(e){this.startCharCode=e.uint32,this.endCharCode=e.uint32,this.glyphID=e.uint32}},dC=class extends oo{constructor(e,t,r){super(e,t,r),this.subTableStart=e.currentPosition,this.format=14,this.length=e.uint32,this.numVarSelectorRecords=e.uint32,ae(this,"varSelectors",()=>[...new Array(this.numVarSelectorRecords)].map(o=>new pC(e)))}supports(){return console.warn("supports not implemented for cmap subtable format 14"),0}getSupportedCharCodes(){return console.warn("getSupportedCharCodes not implemented for cmap subtable format 14"),[]}reverse(e){return console.warn("reverse not implemented for cmap subtable format 14"),{}}supportsVariation(e){let t=this.varSelector.find(r=>r.varSelector===e);return t||!1}getSupportedVariations(){return this.varSelectors.map(e=>e.varSelector)}},pC=class{constructor(e){this.varSelector=e.uint24,this.defaultUVSOffset=e.Offset32,this.nonDefaultUVSOffset=e.Offset32}};function mC(e,t,r){let o=e.uint16;return o===0?new eC(e,t,r):o===2?new tC(e,t,r):o===4?new oC(e,t,r):o===6?new nC(e,t,r):o===8?new iC(e,t,r):o===10?new aC(e,t,r):o===12?new lC(e,t,r):o===13?new uC(e,t,r):o===14?new dC(e,t,r):{}}var hC=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.numTables=r.uint16,this.encodingRecords=[...new Array(this.numTables)].map(o=>new gC(r,this.tableStart))}getSubTable(e){return this.encodingRecords[e].table}getSupportedEncodings(){return this.encodingRecords.map(e=>({platformID:e.platformID,encodingId:e.encodingID}))}getSupportedCharCodes(e,t){let r=this.encodingRecords.findIndex(n=>n.platformID===e&&n.encodingID===t);return r===-1?!1:this.getSubTable(r).getSupportedCharCodes()}reverse(e){for(let t=0;t{let n=this.getSubTable(o);return n.getGlyphId?(t=n.getGlyphId(e),t!==0):!1}),t}supports(e){return this.encodingRecords.some((t,r)=>{let o=this.getSubTable(r);return o.supports&&o.supports(e)!==!1})}supportsVariation(e){return this.encodingRecords.some((t,r)=>{let o=this.getSubTable(r);return o.supportsVariation&&o.supportsVariation(e)!==!1})}},gC=class{constructor(e,t){let r=this.platformID=e.uint16,o=this.encodingID=e.uint16,n=this.offset=e.Offset32;ae(this,"table",()=>(e.currentPosition=t+n,mC(e,r,o)))}},yC=Object.freeze({__proto__:null,cmap:hC}),vC=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.load({majorVersion:r.uint16,minorVersion:r.uint16,fontRevision:r.fixed,checkSumAdjustment:r.uint32,magicNumber:r.uint32,flags:r.flags(16),unitsPerEm:r.uint16,created:r.longdatetime,modified:r.longdatetime,xMin:r.int16,yMin:r.int16,xMax:r.int16,yMax:r.int16,macStyle:r.flags(16),lowestRecPPEM:r.uint16,fontDirectionHint:r.uint16,indexToLocFormat:r.uint16,glyphDataFormat:r.uint16})}},bC=Object.freeze({__proto__:null,head:vC}),wC=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.majorVersion=r.uint16,this.minorVersion=r.uint16,this.ascender=r.fword,this.descender=r.fword,this.lineGap=r.fword,this.advanceWidthMax=r.ufword,this.minLeftSideBearing=r.fword,this.minRightSideBearing=r.fword,this.xMaxExtent=r.fword,this.caretSlopeRise=r.int16,this.caretSlopeRun=r.int16,this.caretOffset=r.int16,r.int16,r.int16,r.int16,r.int16,this.metricDataFormat=r.int16,this.numberOfHMetrics=r.uint16,r.verifyLength()}},xC=Object.freeze({__proto__:null,hhea:wC}),SC=class extends ke{constructor(e,t,r){let{p:o}=super(e,t),n=r.hhea.numberOfHMetrics,i=r.maxp.numGlyphs,s=o.currentPosition;if(ae(this,"hMetrics",()=>(o.currentPosition=s,[...new Array(n)].map(a=>new CC(o.uint16,o.int16)))),n(o.currentPosition=a,[...new Array(i-n)].map(u=>o.int16)))}}},CC=class{constructor(e,t){this.advanceWidth=e,this.lsb=t}},_C=Object.freeze({__proto__:null,hmtx:SC}),RC=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.legacyFixed,this.numGlyphs=r.uint16,this.version===1&&(this.maxPoints=r.uint16,this.maxContours=r.uint16,this.maxCompositePoints=r.uint16,this.maxCompositeContours=r.uint16,this.maxZones=r.uint16,this.maxTwilightPoints=r.uint16,this.maxStorage=r.uint16,this.maxFunctionDefs=r.uint16,this.maxInstructionDefs=r.uint16,this.maxStackElements=r.uint16,this.maxSizeOfInstructions=r.uint16,this.maxComponentElements=r.uint16,this.maxComponentDepth=r.uint16),r.verifyLength()}},EC=Object.freeze({__proto__:null,maxp:RC}),TC=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.format=r.uint16,this.count=r.uint16,this.stringOffset=r.Offset16,this.nameRecords=[...new Array(this.count)].map(o=>new OC(r,this)),this.format===1&&(this.langTagCount=r.uint16,this.langTagRecords=[...new Array(this.langTagCount)].map(o=>new PC(r.uint16,r.Offset16))),this.stringStart=this.tableStart+this.stringOffset}get(e){let t=this.nameRecords.find(r=>r.nameID===e);if(t)return t.string}},PC=class{constructor(e,t){this.length=e,this.offset=t}},OC=class{constructor(e,t){this.platformID=e.uint16,this.encodingID=e.uint16,this.languageID=e.uint16,this.nameID=e.uint16,this.length=e.uint16,this.offset=e.Offset16,ae(this,"string",()=>(e.currentPosition=t.stringStart+this.offset,kC(e,this)))}};function kC(e,t){let{platformID:r,length:o}=t;if(o===0)return"";if(r===0||r===3){let s=[];for(let a=0,u=o/2;ar.uint8),this.ulUnicodeRange1=r.flags(32),this.ulUnicodeRange2=r.flags(32),this.ulUnicodeRange3=r.flags(32),this.ulUnicodeRange4=r.flags(32),this.achVendID=r.tag,this.fsSelection=r.uint16,this.usFirstCharIndex=r.uint16,this.usLastCharIndex=r.uint16,this.sTypoAscender=r.int16,this.sTypoDescender=r.int16,this.sTypoLineGap=r.int16,this.usWinAscent=r.uint16,this.usWinDescent=r.uint16,this.version===0||(this.ulCodePageRange1=r.flags(32),this.ulCodePageRange2=r.flags(32),this.version===1)||(this.sxHeight=r.int16,this.sCapHeight=r.int16,this.usDefaultChar=r.uint16,this.usBreakChar=r.uint16,this.usMaxContext=r.uint16,this.version<=4)||(this.usLowerOpticalPointSize=r.uint16,this.usUpperOpticalPointSize=r.uint16,this.version===5))return r.verifyLength()}},IC=Object.freeze({__proto__:null,OS2:AC}),LC=class extends ke{constructor(e,t){let{p:r}=super(e,t);if(this.version=r.legacyFixed,this.italicAngle=r.fixed,this.underlinePosition=r.fword,this.underlineThickness=r.fword,this.isFixedPitch=r.uint32,this.minMemType42=r.uint32,this.maxMemType42=r.uint32,this.minMemType1=r.uint32,this.maxMemType1=r.uint32,this.version===1||this.version===3)return r.verifyLength();if(this.numGlyphs=r.uint16,this.version===2){this.glyphNameIndex=[...new Array(this.numGlyphs)].map(o=>r.uint16),this.namesOffset=r.currentPosition,this.glyphNameOffsets=[1];for(let o=0;or.int8))}getGlyphName(e){if(this.version!==2)return console.warn(`post table version ${this.version} does not support glyph name lookups`),"";let t=this.glyphNameIndex[e];if(t<258)return Ry[t];let r=this.glyphNameOffsets[e],n=this.glyphNameOffsets[e+1]-r-1;return n===0?".notdef.":(this.parser.currentPosition=this.namesOffset+r,this.parser.readBytes(n,this.namesOffset+r,8,!0).map(s=>String.fromCharCode(s)).join(""))}},Ry=[".notdef",".null","nonmarkingreturn","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quotesingle","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","grave","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","Adieresis","Aring","Ccedilla","Eacute","Ntilde","Odieresis","Udieresis","aacute","agrave","acircumflex","adieresis","atilde","aring","ccedilla","eacute","egrave","ecircumflex","edieresis","iacute","igrave","icircumflex","idieresis","ntilde","oacute","ograve","ocircumflex","odieresis","otilde","uacute","ugrave","ucircumflex","udieresis","dagger","degree","cent","sterling","section","bullet","paragraph","germandbls","registered","copyright","trademark","acute","dieresis","notequal","AE","Oslash","infinity","plusminus","lessequal","greaterequal","yen","mu","partialdiff","summation","product","pi","integral","ordfeminine","ordmasculine","Omega","ae","oslash","questiondown","exclamdown","logicalnot","radical","florin","approxequal","Delta","guillemotleft","guillemotright","ellipsis","nonbreakingspace","Agrave","Atilde","Otilde","OE","oe","endash","emdash","quotedblleft","quotedblright","quoteleft","quoteright","divide","lozenge","ydieresis","Ydieresis","fraction","currency","guilsinglleft","guilsinglright","fi","fl","daggerdbl","periodcentered","quotesinglbase","quotedblbase","perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave","Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex","apple","Ograve","Uacute","Ucircumflex","Ugrave","dotlessi","circumflex","tilde","macron","breve","dotaccent","ring","cedilla","hungarumlaut","ogonek","caron","Lslash","lslash","Scaron","scaron","Zcaron","zcaron","brokenbar","Eth","eth","Yacute","yacute","Thorn","thorn","minus","multiply","onesuperior","twosuperior","threesuperior","onehalf","onequarter","threequarters","franc","Gbreve","gbreve","Idotaccent","Scedilla","scedilla","Cacute","cacute","Ccaron","ccaron","dcroat"],NC=Object.freeze({__proto__:null,post:LC}),MC=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.majorVersion=r.uint16,this.minorVersion=r.uint16,this.horizAxisOffset=r.Offset16,this.vertAxisOffset=r.Offset16,ae(this,"horizAxis",()=>new nu({offset:e.offset+this.horizAxisOffset},t)),ae(this,"vertAxis",()=>new nu({offset:e.offset+this.vertAxisOffset},t)),this.majorVersion===1&&this.minorVersion===1&&(this.itemVarStoreOffset=r.Offset32,ae(this,"itemVarStore",()=>new nu({offset:e.offset+this.itemVarStoreOffset},t)))}},nu=class extends ke{constructor(e,t){let{p:r}=super(e,t,"AxisTable");this.baseTagListOffset=r.Offset16,this.baseScriptListOffset=r.Offset16,ae(this,"baseTagList",()=>new VC({offset:e.offset+this.baseTagListOffset},t)),ae(this,"baseScriptList",()=>new DC({offset:e.offset+this.baseScriptListOffset},t))}},VC=class extends ke{constructor(e,t){let{p:r}=super(e,t,"BaseTagListTable");this.baseTagCount=r.uint16,this.baselineTags=[...new Array(this.baseTagCount)].map(o=>r.tag)}},DC=class extends ke{constructor(e,t){let{p:r}=super(e,t,"BaseScriptListTable");this.baseScriptCount=r.uint16;let o=r.currentPosition;ae(this,"baseScriptRecords",()=>(r.currentPosition=o,[...new Array(this.baseScriptCount)].map(n=>new BC(this.start,r))))}},BC=class{constructor(e,t){this.baseScriptTag=t.tag,this.baseScriptOffset=t.Offset16,ae(this,"baseScriptTable",()=>(t.currentPosition=e+this.baseScriptOffset,new jC(t)))}},jC=class{constructor(e){this.start=e.currentPosition,this.baseValuesOffset=e.Offset16,this.defaultMinMaxOffset=e.Offset16,this.baseLangSysCount=e.uint16,this.baseLangSysRecords=[...new Array(this.baseLangSysCount)].map(t=>new zC(this.start,e)),ae(this,"baseValues",()=>(e.currentPosition=this.start+this.baseValuesOffset,new HC(e))),ae(this,"defaultMinMax",()=>(e.currentPosition=this.start+this.defaultMinMaxOffset,new Iy(e)))}},zC=class{constructor(e,t){this.baseLangSysTag=t.tag,this.minMaxOffset=t.Offset16,ae(this,"minMax",()=>(t.currentPosition=e+this.minMaxOffset,new Iy(t)))}},HC=class{constructor(e){this.parser=e,this.start=e.currentPosition,this.defaultBaselineIndex=e.uint16,this.baseCoordCount=e.uint16,this.baseCoords=[...new Array(this.baseCoordCount)].map(t=>e.Offset16)}getTable(e){return this.parser.currentPosition=this.start+this.baseCoords[e],new WC(this.parser)}},Iy=class{constructor(e){this.minCoord=e.Offset16,this.maxCoord=e.Offset16,this.featMinMaxCount=e.uint16;let t=e.currentPosition;ae(this,"featMinMaxRecords",()=>(e.currentPosition=t,[...new Array(this.featMinMaxCount)].map(r=>new UC(e))))}},UC=class{constructor(e){this.featureTableTag=e.tag,this.minCoord=e.Offset16,this.maxCoord=e.Offset16}},WC=class{constructor(e){this.baseCoordFormat=e.uint16,this.coordinate=e.int16,this.baseCoordFormat===2&&(this.referenceGlyph=e.uint16,this.baseCoordPoint=e.uint16),this.baseCoordFormat===3&&(this.deviceTable=e.Offset16)}},GC=Object.freeze({__proto__:null,BASE:MC}),Ey=class{constructor(e){this.classFormat=e.uint16,this.classFormat===1&&(this.startGlyphID=e.uint16,this.glyphCount=e.uint16,this.classValueArray=[...new Array(this.glyphCount)].map(t=>e.uint16)),this.classFormat===2&&(this.classRangeCount=e.uint16,this.classRangeRecords=[...new Array(this.classRangeCount)].map(t=>new YC(e)))}},YC=class{constructor(e){this.startGlyphID=e.uint16,this.endGlyphID=e.uint16,this.class=e.uint16}},Ci=class extends lt{constructor(e){super(e),this.coverageFormat=e.uint16,this.coverageFormat===1&&(this.glyphCount=e.uint16,this.glyphArray=[...new Array(this.glyphCount)].map(t=>e.uint16)),this.coverageFormat===2&&(this.rangeCount=e.uint16,this.rangeRecords=[...new Array(this.rangeCount)].map(t=>new qC(e)))}},qC=class{constructor(e){this.startGlyphID=e.uint16,this.endGlyphID=e.uint16,this.startCoverageIndex=e.uint16}},ZC=class{constructor(e,t){this.table=e,this.parser=t,this.start=t.currentPosition,this.format=t.uint16,this.variationRegionListOffset=t.Offset32,this.itemVariationDataCount=t.uint16,this.itemVariationDataOffsets=[...new Array(this.itemVariationDataCount)].map(r=>t.Offset32)}},XC=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.majorVersion=r.uint16,this.minorVersion=r.uint16,this.glyphClassDefOffset=r.Offset16,ae(this,"glyphClassDefs",()=>{if(this.glyphClassDefOffset!==0)return r.currentPosition=this.tableStart+this.glyphClassDefOffset,new Ey(r)}),this.attachListOffset=r.Offset16,ae(this,"attachList",()=>{if(this.attachListOffset!==0)return r.currentPosition=this.tableStart+this.attachListOffset,new KC(r)}),this.ligCaretListOffset=r.Offset16,ae(this,"ligCaretList",()=>{if(this.ligCaretListOffset!==0)return r.currentPosition=this.tableStart+this.ligCaretListOffset,new QC(r)}),this.markAttachClassDefOffset=r.Offset16,ae(this,"markAttachClassDef",()=>{if(this.markAttachClassDefOffset!==0)return r.currentPosition=this.tableStart+this.markAttachClassDefOffset,new Ey(r)}),this.minorVersion>=2&&(this.markGlyphSetsDefOffset=r.Offset16,ae(this,"markGlyphSetsDef",()=>{if(this.markGlyphSetsDefOffset!==0)return r.currentPosition=this.tableStart+this.markGlyphSetsDefOffset,new t_(r)})),this.minorVersion===3&&(this.itemVarStoreOffset=r.Offset32,ae(this,"itemVarStore",()=>{if(this.itemVarStoreOffset!==0)return r.currentPosition=this.tableStart+this.itemVarStoreOffset,new ZC(r)}))}},KC=class extends lt{constructor(e){super(e),this.coverageOffset=e.Offset16,this.glyphCount=e.uint16,this.attachPointOffsets=[...new Array(this.glyphCount)].map(t=>e.Offset16)}getPoint(e){return this.parser.currentPosition=this.start+this.attachPointOffsets[e],new JC(this.parser)}},JC=class{constructor(e){this.pointCount=e.uint16,this.pointIndices=[...new Array(this.pointCount)].map(t=>e.uint16)}},QC=class extends lt{constructor(e){super(e),this.coverageOffset=e.Offset16,ae(this,"coverage",()=>(e.currentPosition=this.start+this.coverageOffset,new Ci(e))),this.ligGlyphCount=e.uint16,this.ligGlyphOffsets=[...new Array(this.ligGlyphCount)].map(t=>e.Offset16)}getLigGlyph(e){return this.parser.currentPosition=this.start+this.ligGlyphOffsets[e],new $C(this.parser)}},$C=class extends lt{constructor(e){super(e),this.caretCount=e.uint16,this.caretValueOffsets=[...new Array(this.caretCount)].map(t=>e.Offset16)}getCaretValue(e){return this.parser.currentPosition=this.start+this.caretValueOffsets[e],new e_(this.parser)}},e_=class{constructor(e){this.caretValueFormat=e.uint16,this.caretValueFormat===1&&(this.coordinate=e.int16),this.caretValueFormat===2&&(this.caretValuePointIndex=e.uint16),this.caretValueFormat===3&&(this.coordinate=e.int16,this.deviceOffset=e.Offset16)}},t_=class extends lt{constructor(e){super(e),this.markGlyphSetTableFormat=e.uint16,this.markGlyphSetCount=e.uint16,this.coverageOffsets=[...new Array(this.markGlyphSetCount)].map(t=>e.Offset32)}getMarkGlyphSet(e){return this.parser.currentPosition=this.start+this.coverageOffsets[e],new Ci(this.parser)}},r_=Object.freeze({__proto__:null,GDEF:XC}),Ty=class extends lt{static EMPTY={scriptCount:0,scriptRecords:[]};constructor(e){super(e),this.scriptCount=e.uint16,this.scriptRecords=[...new Array(this.scriptCount)].map(t=>new o_(e))}},o_=class{constructor(e){this.scriptTag=e.tag,this.scriptOffset=e.Offset16}},n_=class extends lt{constructor(e){super(e),this.defaultLangSys=e.Offset16,this.langSysCount=e.uint16,this.langSysRecords=[...new Array(this.langSysCount)].map(t=>new i_(e))}},i_=class{constructor(e){this.langSysTag=e.tag,this.langSysOffset=e.Offset16}},Py=class{constructor(e){this.lookupOrder=e.Offset16,this.requiredFeatureIndex=e.uint16,this.featureIndexCount=e.uint16,this.featureIndices=[...new Array(this.featureIndexCount)].map(t=>e.uint16)}},Oy=class extends lt{static EMPTY={featureCount:0,featureRecords:[]};constructor(e){super(e),this.featureCount=e.uint16,this.featureRecords=[...new Array(this.featureCount)].map(t=>new s_(e))}},s_=class{constructor(e){this.featureTag=e.tag,this.featureOffset=e.Offset16}},a_=class extends lt{constructor(e){super(e),this.featureParams=e.Offset16,this.lookupIndexCount=e.uint16,this.lookupListIndices=[...new Array(this.lookupIndexCount)].map(t=>e.uint16)}getFeatureParams(){if(this.featureParams>0){let e=this.parser;e.currentPosition=this.start+this.featureParams;let t=this.featureTag;if(t==="size")return new c_(e);if(t.startsWith("cc"))return new l_(e);if(t.startsWith("ss"))return new u_(e)}}},l_=class{constructor(e){this.format=e.uint16,this.featUiLabelNameId=e.uint16,this.featUiTooltipTextNameId=e.uint16,this.sampleTextNameId=e.uint16,this.numNamedParameters=e.uint16,this.firstParamUiLabelNameId=e.uint16,this.charCount=e.uint16,this.character=[...new Array(this.charCount)].map(t=>e.uint24)}},c_=class{constructor(e){this.designSize=e.uint16,this.subfamilyIdentifier=e.uint16,this.subfamilyNameID=e.uint16,this.smallEnd=e.uint16,this.largeEnd=e.uint16}},u_=class{constructor(e){this.version=e.uint16,this.UINameID=e.uint16}};function Ly(e){e.parser.currentPosition-=2,delete e.coverageOffset,delete e.getCoverageTable}var Qo=class extends lt{constructor(e){super(e),this.substFormat=e.uint16,this.coverageOffset=e.Offset16}getCoverageTable(){let e=this.parser;return e.currentPosition=this.start+this.coverageOffset,new Ci(e)}},su=class{constructor(e){this.glyphSequenceIndex=e.uint16,this.lookupListIndex=e.uint16}},f_=class extends Qo{constructor(e){super(e),this.deltaGlyphID=e.int16}},d_=class extends Qo{constructor(e){super(e),this.sequenceCount=e.uint16,this.sequenceOffsets=[...new Array(this.sequenceCount)].map(t=>e.Offset16)}getSequence(e){let t=this.parser;return t.currentPosition=this.start+this.sequenceOffsets[e],new p_(t)}},p_=class{constructor(e){this.glyphCount=e.uint16,this.substituteGlyphIDs=[...new Array(this.glyphCount)].map(t=>e.uint16)}},m_=class extends Qo{constructor(e){super(e),this.alternateSetCount=e.uint16,this.alternateSetOffsets=[...new Array(this.alternateSetCount)].map(t=>e.Offset16)}getAlternateSet(e){let t=this.parser;return t.currentPosition=this.start+this.alternateSetOffsets[e],new h_(t)}},h_=class{constructor(e){this.glyphCount=e.uint16,this.alternateGlyphIDs=[...new Array(this.glyphCount)].map(t=>e.uint16)}},g_=class extends Qo{constructor(e){super(e),this.ligatureSetCount=e.uint16,this.ligatureSetOffsets=[...new Array(this.ligatureSetCount)].map(t=>e.Offset16)}getLigatureSet(e){let t=this.parser;return t.currentPosition=this.start+this.ligatureSetOffsets[e],new y_(t)}},y_=class extends lt{constructor(e){super(e),this.ligatureCount=e.uint16,this.ligatureOffsets=[...new Array(this.ligatureCount)].map(t=>e.Offset16)}getLigature(e){let t=this.parser;return t.currentPosition=this.start+this.ligatureOffsets[e],new v_(t)}},v_=class{constructor(e){this.ligatureGlyph=e.uint16,this.componentCount=e.uint16,this.componentGlyphIDs=[...new Array(this.componentCount-1)].map(t=>e.uint16)}},b_=class extends Qo{constructor(e){super(e),this.substFormat===1&&(this.subRuleSetCount=e.uint16,this.subRuleSetOffsets=[...new Array(this.subRuleSetCount)].map(t=>e.Offset16)),this.substFormat===2&&(this.classDefOffset=e.Offset16,this.subClassSetCount=e.uint16,this.subClassSetOffsets=[...new Array(this.subClassSetCount)].map(t=>e.Offset16)),this.substFormat===3&&(Ly(this),this.glyphCount=e.uint16,this.substitutionCount=e.uint16,this.coverageOffsets=[...new Array(this.glyphCount)].map(t=>e.Offset16),this.substLookupRecords=[...new Array(this.substitutionCount)].map(t=>new su(e)))}getSubRuleSet(e){if(this.substFormat!==1)throw new Error(`lookup type 5.${this.substFormat} has no subrule sets.`);let t=this.parser;return t.currentPosition=this.start+this.subRuleSetOffsets[e],new w_(t)}getSubClassSet(e){if(this.substFormat!==2)throw new Error(`lookup type 5.${this.substFormat} has no subclass sets.`);let t=this.parser;return t.currentPosition=this.start+this.subClassSetOffsets[e],new x_(t)}getCoverageTable(e){if(this.substFormat!==3&&!e)return super.getCoverageTable();if(!e)throw new Error(`lookup type 5.${this.substFormat} requires an coverage table index.`);let t=this.parser;return t.currentPosition=this.start+this.coverageOffsets[e],new Ci(t)}},w_=class extends lt{constructor(e){super(e),this.subRuleCount=e.uint16,this.subRuleOffsets=[...new Array(this.subRuleCount)].map(t=>e.Offset16)}getSubRule(e){let t=this.parser;return t.currentPosition=this.start+this.subRuleOffsets[e],new Ny(t)}},Ny=class{constructor(e){this.glyphCount=e.uint16,this.substitutionCount=e.uint16,this.inputSequence=[...new Array(this.glyphCount-1)].map(t=>e.uint16),this.substLookupRecords=[...new Array(this.substitutionCount)].map(t=>new su(e))}},x_=class extends lt{constructor(e){super(e),this.subClassRuleCount=e.uint16,this.subClassRuleOffsets=[...new Array(this.subClassRuleCount)].map(t=>e.Offset16)}getSubClass(e){let t=this.parser;return t.currentPosition=this.start+this.subClassRuleOffsets[e],new S_(t)}},S_=class extends Ny{constructor(e){super(e)}},C_=class extends Qo{constructor(e){super(e),this.substFormat===1&&(this.chainSubRuleSetCount=e.uint16,this.chainSubRuleSetOffsets=[...new Array(this.chainSubRuleSetCount)].map(t=>e.Offset16)),this.substFormat===2&&(this.backtrackClassDefOffset=e.Offset16,this.inputClassDefOffset=e.Offset16,this.lookaheadClassDefOffset=e.Offset16,this.chainSubClassSetCount=e.uint16,this.chainSubClassSetOffsets=[...new Array(this.chainSubClassSetCount)].map(t=>e.Offset16)),this.substFormat===3&&(Ly(this),this.backtrackGlyphCount=e.uint16,this.backtrackCoverageOffsets=[...new Array(this.backtrackGlyphCount)].map(t=>e.Offset16),this.inputGlyphCount=e.uint16,this.inputCoverageOffsets=[...new Array(this.inputGlyphCount)].map(t=>e.Offset16),this.lookaheadGlyphCount=e.uint16,this.lookaheadCoverageOffsets=[...new Array(this.lookaheadGlyphCount)].map(t=>e.Offset16),this.seqLookupCount=e.uint16,this.seqLookupRecords=[...new Array(this.substitutionCount)].map(t=>new My(e)))}getChainSubRuleSet(e){if(this.substFormat!==1)throw new Error(`lookup type 6.${this.substFormat} has no chainsubrule sets.`);let t=this.parser;return t.currentPosition=this.start+this.chainSubRuleSetOffsets[e],new __(t)}getChainSubClassSet(e){if(this.substFormat!==2)throw new Error(`lookup type 6.${this.substFormat} has no chainsubclass sets.`);let t=this.parser;return t.currentPosition=this.start+this.chainSubClassSetOffsets[e],new E_(t)}getCoverageFromOffset(e){if(this.substFormat!==3)throw new Error(`lookup type 6.${this.substFormat} does not use contextual coverage offsets.`);let t=this.parser;return t.currentPosition=this.start+e,new Ci(t)}},__=class extends lt{constructor(e){super(e),this.chainSubRuleCount=e.uint16,this.chainSubRuleOffsets=[...new Array(this.chainSubRuleCount)].map(t=>e.Offset16)}getSubRule(e){let t=this.parser;return t.currentPosition=this.start+this.chainSubRuleOffsets[e],new R_(t)}},R_=class{constructor(e){this.backtrackGlyphCount=e.uint16,this.backtrackSequence=[...new Array(this.backtrackGlyphCount)].map(t=>e.uint16),this.inputGlyphCount=e.uint16,this.inputSequence=[...new Array(this.inputGlyphCount-1)].map(t=>e.uint16),this.lookaheadGlyphCount=e.uint16,this.lookAheadSequence=[...new Array(this.lookAheadGlyphCount)].map(t=>e.uint16),this.substitutionCount=e.uint16,this.substLookupRecords=[...new Array(this.SubstCount)].map(t=>new su(e))}},E_=class extends lt{constructor(e){super(e),this.chainSubClassRuleCount=e.uint16,this.chainSubClassRuleOffsets=[...new Array(this.chainSubClassRuleCount)].map(t=>e.Offset16)}getSubClass(e){let t=this.parser;return t.currentPosition=this.start+this.chainSubRuleOffsets[e],new T_(t)}},T_=class{constructor(e){this.backtrackGlyphCount=e.uint16,this.backtrackSequence=[...new Array(this.backtrackGlyphCount)].map(t=>e.uint16),this.inputGlyphCount=e.uint16,this.inputSequence=[...new Array(this.inputGlyphCount-1)].map(t=>e.uint16),this.lookaheadGlyphCount=e.uint16,this.lookAheadSequence=[...new Array(this.lookAheadGlyphCount)].map(t=>e.uint16),this.substitutionCount=e.uint16,this.substLookupRecords=[...new Array(this.substitutionCount)].map(t=>new My(e))}},My=class extends lt{constructor(e){super(e),this.sequenceIndex=e.uint16,this.lookupListIndex=e.uint16}},P_=class extends lt{constructor(e){super(e),this.substFormat=e.uint16,this.extensionLookupType=e.uint16,this.extensionOffset=e.Offset32}},O_=class extends Qo{constructor(e){super(e),this.backtrackGlyphCount=e.uint16,this.backtrackCoverageOffsets=[...new Array(this.backtrackGlyphCount)].map(t=>e.Offset16),this.lookaheadGlyphCount=e.uint16,this.lookaheadCoverageOffsets=[new Array(this.lookaheadGlyphCount)].map(t=>e.Offset16),this.glyphCount=e.uint16,this.substituteGlyphIDs=[...new Array(this.glyphCount)].map(t=>e.uint16)}},k_={buildSubtable:function(e,t){let r=new[void 0,f_,d_,m_,g_,b_,C_,P_,O_][e](t);return r.type=e,r}},no=class extends lt{constructor(e){super(e)}},F_=class extends no{constructor(e){super(e),console.log("lookup type 1")}},A_=class extends no{constructor(e){super(e),console.log("lookup type 2")}},I_=class extends no{constructor(e){super(e),console.log("lookup type 3")}},L_=class extends no{constructor(e){super(e),console.log("lookup type 4")}},N_=class extends no{constructor(e){super(e),console.log("lookup type 5")}},M_=class extends no{constructor(e){super(e),console.log("lookup type 6")}},V_=class extends no{constructor(e){super(e),console.log("lookup type 7")}},D_=class extends no{constructor(e){super(e),console.log("lookup type 8")}},B_=class extends no{constructor(e){super(e),console.log("lookup type 9")}},j_={buildSubtable:function(e,t){let r=new[void 0,F_,A_,I_,L_,N_,M_,V_,D_,B_][e](t);return r.type=e,r}},ky=class extends lt{static EMPTY={lookupCount:0,lookups:[]};constructor(e){super(e),this.lookupCount=e.uint16,this.lookups=[...new Array(this.lookupCount)].map(t=>e.Offset16)}},z_=class extends lt{constructor(e,t){super(e),this.ctType=t,this.lookupType=e.uint16,this.lookupFlag=e.uint16,this.subTableCount=e.uint16,this.subtableOffsets=[...new Array(this.subTableCount)].map(r=>e.Offset16),this.markFilteringSet=e.uint16}get rightToLeft(){return this.lookupFlag&!0}get ignoreBaseGlyphs(){return this.lookupFlag&!0}get ignoreLigatures(){return this.lookupFlag&!0}get ignoreMarks(){return this.lookupFlag&!0}get useMarkFilteringSet(){return this.lookupFlag&!0}get markAttachmentType(){return this.lookupFlag&!0}getSubTable(e){let t=this.ctType==="GSUB"?k_:j_;return this.parser.currentPosition=this.start+this.subtableOffsets[e],t.buildSubtable(this.lookupType,this.parser)}},Vy=class extends ke{constructor(e,t,r){let{p:o,tableStart:n}=super(e,t,r);this.majorVersion=o.uint16,this.minorVersion=o.uint16,this.scriptListOffset=o.Offset16,this.featureListOffset=o.Offset16,this.lookupListOffset=o.Offset16,this.majorVersion===1&&this.minorVersion===1&&(this.featureVariationsOffset=o.Offset32);let i=!(this.scriptListOffset||this.featureListOffset||this.lookupListOffset);ae(this,"scriptList",()=>i?Ty.EMPTY:(o.currentPosition=n+this.scriptListOffset,new Ty(o))),ae(this,"featureList",()=>i?Oy.EMPTY:(o.currentPosition=n+this.featureListOffset,new Oy(o))),ae(this,"lookupList",()=>i?ky.EMPTY:(o.currentPosition=n+this.lookupListOffset,new ky(o))),this.featureVariationsOffset&&ae(this,"featureVariations",()=>i?FeatureVariations.EMPTY:(o.currentPosition=n+this.featureVariationsOffset,new FeatureVariations(o)))}getSupportedScripts(){return this.scriptList.scriptRecords.map(e=>e.scriptTag)}getScriptTable(e){let t=this.scriptList.scriptRecords.find(o=>o.scriptTag===e);this.parser.currentPosition=this.scriptList.start+t.scriptOffset;let r=new n_(this.parser);return r.scriptTag=e,r}ensureScriptTable(e){return typeof e=="string"?this.getScriptTable(e):e}getSupportedLangSys(e){e=this.ensureScriptTable(e);let t=e.defaultLangSys!==0,r=e.langSysRecords.map(o=>o.langSysTag);return t&&r.unshift("dflt"),r}getDefaultLangSysTable(e){e=this.ensureScriptTable(e);let t=e.defaultLangSys;if(t!==0){this.parser.currentPosition=e.start+t;let r=new Py(this.parser);return r.langSysTag="",r.defaultForScript=e.scriptTag,r}}getLangSysTable(e,t="dflt"){if(t==="dflt")return this.getDefaultLangSysTable(e);e=this.ensureScriptTable(e);let r=e.langSysRecords.find(n=>n.langSysTag===t);this.parser.currentPosition=e.start+r.langSysOffset;let o=new Py(this.parser);return o.langSysTag=t,o}getFeatures(e){return e.featureIndices.map(t=>this.getFeature(t))}getFeature(e){let t;if(parseInt(e)==e?t=this.featureList.featureRecords[e]:t=this.featureList.featureRecords.find(o=>o.featureTag===e),!t)return;this.parser.currentPosition=this.featureList.start+t.featureOffset;let r=new a_(this.parser);return r.featureTag=t.featureTag,r}getLookups(e){return e.lookupListIndices.map(t=>this.getLookup(t))}getLookup(e,t){let r=this.lookupList.lookups[e];return this.parser.currentPosition=this.lookupList.start+r,new z_(this.parser,t)}},H_=class extends Vy{constructor(e,t){super(e,t,"GSUB")}getLookup(e){return super.getLookup(e,"GSUB")}},U_=Object.freeze({__proto__:null,GSUB:H_}),W_=class extends Vy{constructor(e,t){super(e,t,"GPOS")}getLookup(e){return super.getLookup(e,"GPOS")}},G_=Object.freeze({__proto__:null,GPOS:W_}),Y_=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.offsetToSVGDocumentList=r.Offset32,r.currentPosition=this.tableStart+this.offsetToSVGDocumentList,this.documentList=new q_(r)}},q_=class extends lt{constructor(e){super(e),this.numEntries=e.uint16,this.documentRecords=[...new Array(this.numEntries)].map(t=>new Z_(e))}getDocument(e){let t=this.documentRecords[e];if(!t)return"";let r=this.start+t.svgDocOffset;return this.parser.currentPosition=r,this.parser.readBytes(t.svgDocLength)}getDocumentForGlyph(e){let t=this.documentRecords.findIndex(r=>r.startGlyphID<=e&&e<=r.endGlyphID);return t===-1?"":this.getDocument(t)}},Z_=class{constructor(e){this.startGlyphID=e.uint16,this.endGlyphID=e.uint16,this.svgDocOffset=e.Offset32,this.svgDocLength=e.uint32}},X_=Object.freeze({__proto__:null,SVG:Y_}),K_=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.majorVersion=r.uint16,this.minorVersion=r.uint16,this.axesArrayOffset=r.Offset16,r.uint16,this.axisCount=r.uint16,this.axisSize=r.uint16,this.instanceCount=r.uint16,this.instanceSize=r.uint16;let o=this.tableStart+this.axesArrayOffset;ae(this,"axes",()=>(r.currentPosition=o,[...new Array(this.axisCount)].map(i=>new J_(r))));let n=o+this.axisCount*this.axisSize;ae(this,"instances",()=>{let i=[];for(let s=0;se.tag)}getAxis(e){return this.axes.find(t=>t.tag===e)}},J_=class{constructor(e){this.tag=e.tag,this.minValue=e.fixed,this.defaultValue=e.fixed,this.maxValue=e.fixed,this.flags=e.flags(16),this.axisNameID=e.uint16}},Q_=class{constructor(e,t,r){let o=e.currentPosition;this.subfamilyNameID=e.uint16,e.uint16,this.coordinates=[...new Array(t)].map(n=>e.fixed),e.currentPosition-o[...new Array(o)].map(n=>r.fword))}},tR=Object.freeze({__proto__:null,cvt:eR}),rR=class extends ke{constructor(e,t){let{p:r}=super(e,t);ae(this,"instructions",()=>[...new Array(e.length)].map(o=>r.uint8))}},oR=Object.freeze({__proto__:null,fpgm:rR}),nR=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.numRanges=r.uint16,ae(this,"gaspRanges",()=>[...new Array(this.numRanges)].map(n=>new iR(r)))}},iR=class{constructor(e){this.rangeMaxPPEM=e.uint16,this.rangeGaspBehavior=e.uint16}},sR=Object.freeze({__proto__:null,gasp:nR}),aR=class extends ke{constructor(e,t){super(e,t)}getGlyphData(e,t){return this.parser.currentPosition=this.tableStart+e,this.parser.readBytes(t)}},lR=Object.freeze({__proto__:null,glyf:aR}),cR=class extends ke{constructor(e,t,r){let{p:o}=super(e,t),n=r.maxp.numGlyphs+1;r.head.indexToLocFormat===0?(this.x2=!0,ae(this,"offsets",()=>[...new Array(n)].map(i=>o.Offset16))):ae(this,"offsets",()=>[...new Array(n)].map(i=>o.Offset32))}getGlyphDataOffsetAndLength(e){let t=this.offsets[e]*this.x2?2:1,r=this.offsets[e+1]*this.x2?2:1;return{offset:t,length:r-t}}},uR=Object.freeze({__proto__:null,loca:cR}),fR=class extends ke{constructor(e,t){let{p:r}=super(e,t);ae(this,"instructions",()=>[...new Array(e.length)].map(o=>r.uint8))}},dR=Object.freeze({__proto__:null,prep:fR}),pR=class extends ke{constructor(e,t){let{p:r}=super(e,t);ae(this,"data",()=>r.readBytes())}},mR=Object.freeze({__proto__:null,CFF:pR}),hR=class extends ke{constructor(e,t){let{p:r}=super(e,t);ae(this,"data",()=>r.readBytes())}},gR=Object.freeze({__proto__:null,CFF2:hR}),yR=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.majorVersion=r.uint16,this.minorVersion=r.uint16,this.defaultVertOriginY=r.int16,this.numVertOriginYMetrics=r.uint16,ae(this,"vertORiginYMetrics",()=>[...new Array(this.numVertOriginYMetrics)].map(o=>new vR(r)))}},vR=class{constructor(e){this.glyphIndex=e.uint16,this.vertOriginY=e.int16}},bR=Object.freeze({__proto__:null,VORG:yR}),wR=class{constructor(e){this.indexSubTableArrayOffset=e.Offset32,this.indexTablesSize=e.uint32,this.numberofIndexSubTables=e.uint32,this.colorRef=e.uint32,this.hori=new fa(e),this.vert=new fa(e),this.startGlyphIndex=e.uint16,this.endGlyphIndex=e.uint16,this.ppemX=e.uint8,this.ppemY=e.uint8,this.bitDepth=e.uint8,this.flags=e.int8}},xR=class{constructor(e){this.hori=new fa(e),this.vert=new fa(e),this.ppemX=e.uint8,this.ppemY=e.uint8,this.substitutePpemX=e.uint8,this.substitutePpemY=e.uint8}},fa=class{constructor(e){this.ascender=e.int8,this.descender=e.int8,this.widthMax=e.uint8,this.caretSlopeNumerator=e.int8,this.caretSlopeDenominator=e.int8,this.caretOffset=e.int8,this.minOriginSB=e.int8,this.minAdvanceSB=e.int8,this.maxBeforeBL=e.int8,this.minAfterBL=e.int8,this.pad1=e.int8,this.pad2=e.int8}},Dy=class extends ke{constructor(e,t,r){let{p:o}=super(e,t,r);this.majorVersion=o.uint16,this.minorVersion=o.uint16,this.numSizes=o.uint32,ae(this,"bitMapSizes",()=>[...new Array(this.numSizes)].map(n=>new wR(o)))}},SR=Object.freeze({__proto__:null,EBLC:Dy}),By=class extends ke{constructor(e,t,r){let{p:o}=super(e,t,r);this.majorVersion=o.uint16,this.minorVersion=o.uint16}},CR=Object.freeze({__proto__:null,EBDT:By}),_R=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.majorVersion=r.uint16,this.minorVersion=r.uint16,this.numSizes=r.uint32,ae(this,"bitmapScales",()=>[...new Array(this.numSizes)].map(o=>new xR(r)))}},RR=Object.freeze({__proto__:null,EBSC:_R}),ER=class extends Dy{constructor(e,t){super(e,t,"CBLC")}},TR=Object.freeze({__proto__:null,CBLC:ER}),PR=class extends By{constructor(e,t){super(e,t,"CBDT")}},OR=Object.freeze({__proto__:null,CBDT:PR}),kR=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.flags=r.flags(16),this.numStrikes=r.uint32,ae(this,"strikeOffsets",()=>[...new Array(this.numStrikes)].map(o=>r.Offset32))}},FR=Object.freeze({__proto__:null,sbix:kR}),AR=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.numBaseGlyphRecords=r.uint16,this.baseGlyphRecordsOffset=r.Offset32,this.layerRecordsOffset=r.Offset32,this.numLayerRecords=r.uint16}getBaseGlyphRecord(e){let t=this.tableStart+this.baseGlyphRecordsOffset;this.parser.currentPosition=t;let r=new iu(this.parser),o=r.gID,n=this.tableStart+this.layerRecordsOffset-6;this.parser.currentPosition=n;let i=new iu(this.parser),s=i.gID;if(o===e)return r;if(s===e)return i;for(;t!==n;){let a=t+(n-t)/12;this.parser.currentPosition=a;let u=new iu(this.parser),l=u.gID;if(l===e)return u;l>e?n=a:lnew IR(p))}},iu=class{constructor(e){this.gID=e.uint16,this.firstLayerIndex=e.uint16,this.numLayers=e.uint16}},IR=class{constructor(e){this.gID=e.uint16,this.paletteIndex=e.uint16}},LR=Object.freeze({__proto__:null,COLR:AR}),NR=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.numPaletteEntries=r.uint16;let o=this.numPalettes=r.uint16;this.numColorRecords=r.uint16,this.offsetFirstColorRecord=r.Offset32,this.colorRecordIndices=[...new Array(this.numPalettes)].map(n=>r.uint16),ae(this,"colorRecords",()=>(r.currentPosition=this.tableStart+this.offsetFirstColorRecord,[...new Array(this.numColorRecords)].map(n=>new MR(r)))),this.version===1&&(this.offsetPaletteTypeArray=r.Offset32,this.offsetPaletteLabelArray=r.Offset32,this.offsetPaletteEntryLabelArray=r.Offset32,ae(this,"paletteTypeArray",()=>(r.currentPosition=this.tableStart+this.offsetPaletteTypeArray,new VR(r,o))),ae(this,"paletteLabelArray",()=>(r.currentPosition=this.tableStart+this.offsetPaletteLabelArray,new DR(r,o))),ae(this,"paletteEntryLabelArray",()=>(r.currentPosition=this.tableStart+this.offsetPaletteEntryLabelArray,new BR(r,o))))}},MR=class{constructor(e){this.blue=e.uint8,this.green=e.uint8,this.red=e.uint8,this.alpha=e.uint8}},VR=class{constructor(e,t){this.paletteTypes=[...new Array(t)].map(r=>e.uint32)}},DR=class{constructor(e,t){this.paletteLabels=[...new Array(t)].map(r=>e.uint16)}},BR=class{constructor(e,t){this.paletteEntryLabels=[...new Array(t)].map(r=>e.uint16)}},jR=Object.freeze({__proto__:null,CPAL:NR}),zR=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint32,this.numSignatures=r.uint16,this.flags=r.uint16,this.signatureRecords=[...new Array(this.numSignatures)].map(o=>new HR(r))}getData(e){let t=this.signatureRecords[e];return this.parser.currentPosition=this.tableStart+t.offset,new UR(this.parser)}},HR=class{constructor(e){this.format=e.uint32,this.length=e.uint32,this.offset=e.Offset32}},UR=class{constructor(e){e.uint16,e.uint16,this.signatureLength=e.uint32,this.signature=e.readBytes(this.signatureLength)}},WR=Object.freeze({__proto__:null,DSIG:zR}),GR=class extends ke{constructor(e,t,r){let{p:o}=super(e,t),n=r.hmtx.numGlyphs;this.version=o.uint16,this.numRecords=o.int16,this.sizeDeviceRecord=o.int32,this.records=[...new Array(numRecords)].map(i=>new YR(o,n))}},YR=class{constructor(e,t){this.pixelSize=e.uint8,this.maxWidth=e.uint8,this.widths=e.readBytes(t)}},qR=Object.freeze({__proto__:null,hdmx:GR}),ZR=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.nTables=r.uint16,ae(this,"tables",()=>{let o=this.tableStart+4,n=[];for(let i=0;i[...new Array(this.nPairs)].map(t=>new KR(e)))),this.format===2&&console.warn("Kern subtable format 2 is not supported: this parser currently only parses universal table data.")}get horizontal(){return this.coverage[0]}get minimum(){return this.coverage[1]}get crossstream(){return this.coverage[2]}get override(){return this.coverage[3]}},KR=class{constructor(e){this.left=e.uint16,this.right=e.uint16,this.value=e.fword}},JR=Object.freeze({__proto__:null,kern:ZR}),QR=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.numGlyphs=r.uint16,this.yPels=r.readBytes(this.numGlyphs)}},$R=Object.freeze({__proto__:null,LTSH:QR}),e2=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.mergeClassCount=r.uint16,this.mergeDataOffset=r.Offset16,this.classDefCount=r.uint16,this.offsetToClassDefOffsets=r.Offset16,ae(this,"mergeEntryMatrix",()=>[...new Array(this.mergeClassCount)].map(o=>r.readBytes(this.mergeClassCount))),console.warn("Full MERG parsing is currently not supported."),console.warn("If you need this table parsed, please file an issue, or better yet, a PR.")}},t2=Object.freeze({__proto__:null,MERG:e2}),r2=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint32,this.flags=r.uint32,r.uint32,this.dataMapsCount=r.uint32,this.dataMaps=[...new Array(this.dataMapsCount)].map(o=>new o2(this.tableStart,r))}},o2=class{constructor(e,t){this.tableStart=e,this.parser=t,this.tag=t.tag,this.dataOffset=t.Offset32,this.dataLength=t.uint32}getData(){return this.parser.currentField=this.tableStart+this.dataOffset,this.parser.readBytes(this.dataLength)}},n2=Object.freeze({__proto__:null,meta:r2}),i2=class extends ke{constructor(e,t){super(e,t),console.warn("This font uses a PCLT table, which is currently not supported by this parser."),console.warn("If you need this table parsed, please file an issue, or better yet, a PR.")}},s2=Object.freeze({__proto__:null,PCLT:i2}),a2=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.numRecs=r.uint16,this.numRatios=r.uint16,this.ratRanges=[...new Array(this.numRatios)].map(o=>new l2(r)),this.offsets=[...new Array(this.numRatios)].map(o=>r.Offset16),this.VDMXGroups=[...new Array(this.numRecs)].map(o=>new c2(r))}},l2=class{constructor(e){this.bCharSet=e.uint8,this.xRatio=e.uint8,this.yStartRatio=e.uint8,this.yEndRatio=e.uint8}},c2=class{constructor(e){this.recs=e.uint16,this.startsz=e.uint8,this.endsz=e.uint8,this.records=[...new Array(this.recs)].map(t=>new u2(e))}},u2=class{constructor(e){this.yPelHeight=e.uint16,this.yMax=e.int16,this.yMin=e.int16}},f2=Object.freeze({__proto__:null,VDMX:a2}),d2=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.fixed,this.ascent=this.vertTypoAscender=r.int16,this.descent=this.vertTypoDescender=r.int16,this.lineGap=this.vertTypoLineGap=r.int16,this.advanceHeightMax=r.int16,this.minTopSideBearing=r.int16,this.minBottomSideBearing=r.int16,this.yMaxExtent=r.int16,this.caretSlopeRise=r.int16,this.caretSlopeRun=r.int16,this.caretOffset=r.int16,this.reserved=r.int16,this.reserved=r.int16,this.reserved=r.int16,this.reserved=r.int16,this.metricDataFormat=r.int16,this.numOfLongVerMetrics=r.uint16,r.verifyLength()}},p2=Object.freeze({__proto__:null,vhea:d2}),m2=class extends ke{constructor(e,t,r){super(e,t);let o=r.vhea.numOfLongVerMetrics,n=r.maxp.numGlyphs,i=p.currentPosition;if(lazy(this,"vMetrics",()=>(p.currentPosition=i,[...new Array(o)].map(s=>new h2(p.uint16,p.int16)))),o(p.currentPosition=s,[...new Array(n-o)].map(a=>p.int16)))}}},h2=class{constructor(e,t){this.advanceHeight=e,this.topSideBearing=t}},g2=Object.freeze({__proto__:null,vmtx:m2});function jy(e){let t=e.reduce((r,o)=>(r[o.fontFamily]||(r[o.fontFamily]={name:o.fontFamily,fontFamily:o.fontFamily,slug:Ks(o.fontFamily.toLowerCase()),fontFace:[]}),r[o.fontFamily].fontFace.push(o),r),{});return Object.values(t)}var Qt=f(Z(),1);function y2(){let{installFonts:e}=(0,_i.useContext)(jt),[t,r]=(0,_i.useState)(!1),[o,n]=(0,_i.useState)(null),i=h=>{a(h)},s=h=>{a(h.target.files)},a=async h=>{if(!h)return;n(null),r(!0);let g=new Set,b=[...h],w=!1,C=b.map(async v=>{if(!await l(v))return w=!0,null;if(g.has(v.name))return null;let k=(((v.name??"").split(".")??[]).pop()??"").toLowerCase();return eu.includes(k)?(g.add(v.name),v):null}),x=(await Promise.all(C)).filter(v=>v!==null);if(x.length>0)u(x);else{let v=w?(0,Vn.__)("Sorry, you are not allowed to upload this file type."):(0,Vn.__)("No fonts found to install.");n({type:"error",message:v}),r(!1)}},u=async h=>{let g=await Promise.all(h.map(async b=>{let w=await m(b);return await Po(w,w.file,"all"),w}));d(g)};async function l(h){let g=new da("Uploaded Font");try{let b=await c(h);return await g.fromDataBuffer(b,"font"),!0}catch{return!1}}async function c(h){return new Promise((g,b)=>{let w=new window.FileReader;w.readAsArrayBuffer(h),w.onload=()=>g(w.result),w.onerror=b})}let m=async h=>{let g=await c(h),b=new da("Uploaded Font");b.fromDataBuffer(g,h.name);let C=(await new Promise(I=>b.onload=I)).detail.font,{name:x}=C.opentype.tables,v=x.get(16)||x.get(1),_=x.get(2).toLowerCase().includes("italic"),k=C.opentype.tables["OS/2"].usWeightClass||"normal",T=!!C.opentype.tables.fvar&&C.opentype.tables.fvar.axes.find(({tag:I})=>I==="wght"),O=T?`${T.minValue} ${T.maxValue}`:null;return{file:h,fontFamily:v,fontStyle:_?"italic":"normal",fontWeight:O||k}},d=async h=>{let g=jy(h);try{await e(g),n({type:"success",message:(0,Vn.__)("Fonts were installed successfully.")})}catch(b){let w=b;n({type:"error",message:w.message,errors:w?.installationErrors})}r(!1)};return(0,Qt.jsxs)("div",{className:"font-library__tabpanel-layout",children:[(0,Qt.jsx)(Ot.DropZone,{onFilesDrop:i}),(0,Qt.jsxs)(Ot.__experimentalVStack,{className:"font-library__local-fonts",justify:"start",children:[o&&(0,Qt.jsxs)(Ot.Notice,{status:o.type,__unstableHTML:!0,onRemove:()=>n(null),children:[o.message,o.errors&&(0,Qt.jsx)("ul",{children:o.errors.map((h,g)=>(0,Qt.jsx)("li",{children:h},g))})]}),t&&(0,Qt.jsx)(Ot.FlexItem,{children:(0,Qt.jsx)("div",{className:"font-library__upload-area",children:(0,Qt.jsx)(Ot.ProgressBar,{})})}),!t&&(0,Qt.jsx)(Ot.FormFileUpload,{accept:eu.map(h=>`.${h}`).join(","),multiple:!0,onChange:s,render:({openFileDialog:h})=>(0,Qt.jsx)(Ot.Button,{__next40pxDefaultSize:!0,className:"font-library__upload-area",onClick:h,children:(0,Vn.__)("Upload font")})}),(0,Qt.jsx)(Ot.__experimentalText,{className:"font-library__upload-area__text",children:(0,Vn.__)("Uploaded fonts appear in your library and can be used in your theme. Supported formats: .ttf, .otf, .woff, and .woff2.")})]})]})}var pa=y2;var Hy=f(Z(),1),{Tabs:WB}=Ve(au.privateApis),GB={id:"installed-fonts",title:(0,ma._x)("Library","Font library")},YB={id:"upload-fonts",title:(0,ma._x)("Upload","noun")};var Uy=f(ge(),1),lu=f(ue(),1),b2=f(Te(),1);var Wy=f(Z(),1);var cu=f(Z(),1);var Gy=f(ge(),1),ha=f(ue(),1);var Yy=f(Z(),1);var fu=f(Z(),1);var wt=f(ge(),1),du=f(ue(),1),T2=f(Te(),1);var qy=f(Dt(),1);var R2=f(Z(),1),{useSettingsForBlockElement:Sj,TypographyPanel:Cj}=Ve(qy.privateApis);var E2=f(Z(),1);var pu=f(Z(),1),Aj={text:{description:(0,wt.__)("Manage the fonts used on the site."),title:(0,wt.__)("Text")},link:{description:(0,wt.__)("Manage the fonts and typography used on the links."),title:(0,wt.__)("Links")},heading:{description:(0,wt.__)("Manage the fonts and typography used on headings."),title:(0,wt.__)("Headings")},caption:{description:(0,wt.__)("Manage the fonts and typography used on captions."),title:(0,wt.__)("Captions")},cite:{description:(0,wt.__)("Manage the fonts and typography used on citations."),title:(0,wt.__)("Citations")},button:{description:(0,wt.__)("Manage the fonts and typography used on buttons."),title:(0,wt.__)("Buttons")},textInput:{description:(0,wt.__)("Manage the fonts and typography used on inputs."),title:(0,wt.__)("Inputs")},select:{description:(0,wt.__)("Manage the fonts and typography used on selects."),title:(0,wt.__)("Selects")}};var ga=f(ge(),1),F2=f(ue(),1),Xy=f(Dt(),1);var Dn=f(ue(),1),Zy=f(ge(),1);var k2=f(Te(),1);var P2=f(ue(),1),O2=f(Z(),1);var mu=f(Z(),1);var hu=f(Z(),1),{useSettingsForBlockElement:Zj,ColorPanel:Xj}=Ve(Xy.privateApis),Kj=[{name:"cite",label:(0,ga.__)("Citations")},{name:"textInput",label:(0,ga.__)("Inputs")},{name:"select",label:(0,ga.__)("Selects")}];var H2=f(ge(),1);var L2=f(yo(),1),gu=f(ue(),1),N2=f(ge(),1);var va=f(ue(),1);var ya=f(ue(),1);var Ky=f(Z(),1);function Jy(){let{paletteColors:e}=Pn();return e.slice(0,4).map(({slug:t,color:r},o)=>(0,Ky.jsx)("div",{style:{flexGrow:1,height:"100%",background:r}},`${t}-${o}`))}var Ei=f(Z(),1),A2={start:{scale:1,opacity:1},hover:{scale:0,opacity:0}},I2=({label:e,isFocused:t,withHoverView:r})=>(0,Ei.jsx)(Fn,{label:e,isFocused:t,withHoverView:r,children:({key:o})=>(0,Ei.jsx)(ya.__unstableMotion.div,{variants:A2,style:{height:"100%",overflow:"hidden"},children:(0,Ei.jsx)(ya.__experimentalHStack,{spacing:0,justify:"center",style:{height:"100%",overflow:"hidden"},children:(0,Ei.jsx)(Jy,{})})},o)}),Qy=I2;var $o=f(Z(),1),$y=["color"];function ba({title:e,gap:t=2}){let r=Hs($y);return r?.length<=1?null:(0,$o.jsxs)(va.__experimentalVStack,{spacing:3,children:[e&&(0,$o.jsx)(Er,{level:3,children:e}),(0,$o.jsx)(va.__experimentalGrid,{gap:t,children:r.map((o,n)=>(0,$o.jsx)(An,{variation:o,isPill:!0,properties:$y,showTooltip:!0,children:()=>(0,$o.jsx)(Qy,{})},n))})]})}var ev=f(Z(),1);var M2=f(yo(),1),tv=f(ue(),1),V2=f(ge(),1);var rv=f(Z(),1);var D2=f(yo(),1),B2=f(Te(),1),j2=f(ue(),1);var z2=f(ge(),1);var ov=f(Z(),1);var yu=f(Z(),1);var W2=f(ge(),1),iv=f(Dt(),1),G2=f(ue(),1);var nv=f(Dt(),1);var U2=f(Z(),1);var{BackgroundPanel:E9}=Ve(nv.privateApis);var vu=f(Z(),1),{useHasBackgroundPanel:I9}=Ve(iv.privateApis);var av=f(ge(),1);var Ti=f(ue(),1),X2=f(ge(),1);var K2=f(Te(),1);var Y2=f(ue(),1),q2=f(ge(),1),Z2=f(Z(),1);var sv=f(Z(),1),{Menu:z9}=Ve(Ti.privateApis);var wu=f(Z(),1);var yr=f(ue(),1),uv=f(ge(),1);var wa=f(Te(),1);var Pi=f(ue(),1);var lv=f(Z(),1),{Menu:tz}=Ve(Pi.privateApis);var $2=f(ue(),1),eE=f(ge(),1),tE=f(Z(),1);var xu=f(ue(),1),rE=f(ge(),1),oE=f(Te(),1);var cv=f(Z(),1);var Su=f(Z(),1);var aE=f(Z(),1);var uE=f(ge(),1),dv=f(Dt(),1);var fv=f(Dt(),1),lE=f(Te(),1);var cE=f(Z(),1),{useSettingsForBlockElement:Ez,DimensionsPanel:Tz}=Ve(fv.privateApis);var Cu=f(Z(),1),{useHasDimensionsPanel:Lz,useSettingsForBlockElement:Nz}=Ve(dv.privateApis);var vv=f(ue(),1),mE=f(ge(),1);var dE=f(ge(),1),pE=f(ue(),1);var pv=f(sr(),1),mv=f(Kt(),1),Sa=f(Te(),1),hv=f(ue(),1),gv=f(ge(),1);var xa=f(Z(),1);function fE({gap:e=2}){let{user:t}=(0,Sa.useContext)(gt),r=t?.styles,n=(0,mv.useSelect)(s=>{let a=s(pv.store).__experimentalGetCurrentThemeGlobalStylesVariations();return Array.isArray(a)?a:void 0},[])?.filter(s=>!yi(s,["color"])&&!yi(s,["typography","spacing"])),i=(0,Sa.useMemo)(()=>[...[{title:(0,gv.__)("Default"),settings:{},styles:{}},...n??[]].map(a=>{let u=a?.styles?.blocks?{...a.styles.blocks}:{};r?.blocks&&Object.keys(r.blocks).forEach(d=>{if(r.blocks?.[d]?.css){let h=u[d]||{},g={css:`${u[d]?.css||""} ${r.blocks?.[d]?.css?.trim()||""}`};u[d]={...h,...g}}});let l=r?.css||a.styles?.css?{css:`${a.styles?.css||""} ${r?.css||""}`}:{},c=Object.keys(u).length>0?{blocks:u}:{},m={...a.styles,...l,...c};return{...a,settings:a.settings??{},styles:m}})],[n,r?.blocks,r?.css]);return!n||n.length<1?null:(0,xa.jsx)(hv.__experimentalGrid,{columns:2,className:"global-styles-ui-style-variations-container",gap:e,children:i.map((s,a)=>(0,xa.jsx)(An,{variation:s,children:u=>(0,xa.jsx)(Wc,{label:s?.title,withHoverView:!0,isFocused:u,variation:s})},a))})}var _u=fE;var yv=f(Z(),1);var Ru=f(Z(),1);var hE=f(ge(),1),gE=f(ue(),1),bv=f(Dt(),1);var Eu=f(Z(),1),{AdvancedPanel:$z}=Ve(bv.privateApis);var Tv=f(ge(),1),Pu=f(ue(),1),Ou=f(Te(),1);var yE=f(Kt(),1),vE=f(sr(),1),wv=f(Te(),1);var Cv=f(ge(),1),Ca=f(ue(),1),_a=f(Sv(),1),bE=f(sr(),1),wE=f(Kt(),1);var _v=f(Qc(),1);var Rv=f(Z(),1),{Badge:i7}=Ve(Ca.privateApis),s7=3600*1e3*24;var Tu=f(ue(),1),Oi=f(ge(),1);var Ev=f(Z(),1);var ku=f(Z(),1);var Pv=f(ge(),1),Ov=f(ue(),1);var kv=f(Z(),1);var Av=f(ge(),1),ki=f(ue(),1),Iv=f(Te(),1);var SE=f(Dt(),1),CE=f(ge(),1);var _E=f(Z(),1);var io=f(ue(),1),Fv=f(Z(),1);var Fu=f(Z(),1);var Iu=f(Z(),1);var Lu=f(Z(),1);function Bn(e){return function({value:r,baseValue:o,onChange:n,...i}){return(0,Lu.jsx)(gi,{value:r,baseValue:o,onChange:n,children:(0,Lu.jsx)(e,{...i})})}}var PE=Bn(_u);var OE=Bn(ba);var kE=Bn(Xs);var jn=f(Z(),1);function Nu({value:e,baseValue:t,onChange:r,activeTab:o="installed-fonts"}){let n;switch(o){case"upload-fonts":n=(0,jn.jsx)(pa,{});break;case"installed-fonts":n=(0,jn.jsx)(na,{});break;default:n=(0,jn.jsx)(sa,{slug:o})}return(0,jn.jsx)(gi,{value:e,baseValue:t,onChange:r,children:(0,jn.jsx)($s,{children:n})})}var Mv=f(li()),{unlock:Mu}=(0,Mv.__dangerousOptInToUnstableAPIsOnlyForCoreModules)("I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.","@wordpress/font-list-route");if(typeof document<"u"&&!document.head.querySelector("style[data-wp-hash='8316bac515']")){let e=document.createElement("style");e.setAttribute("data-wp-hash","8316bac515"),e.appendChild(document.createTextNode('@media (min-width:782px){.font-library-modal.font-library-modal{width:65vw}}.font-library-modal .components-modal__header{border-bottom:none}.font-library-modal .components-modal__content{margin-bottom:90px;padding:0}.font-library-modal .font-library__subtitle{font-size:11px;font-weight:var(--wpds-typography-font-weight-emphasis,600);text-transform:uppercase}.font-library-modal__tab-panel{height:calc(100% - 50px)}.font-library__tabpanel-layout{display:flex;flex-direction:column;height:100%}.font-library__tabpanel-layout>div{flex-grow:1}.font-library__tabpanel-layout .font-library__loading{align-items:center;box-sizing:border-box;display:flex;height:100%;justify-content:center;left:0;padding-top:124px;position:absolute;top:0;width:100%}.font-library__footer,.font-library__tabpanel-layout .components-navigator-screen{padding:24px;width:100%}.font-library__footer{background-color:#fff;border-top:1px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);bottom:0;box-sizing:border-box;flex-grow:0!important;flex-shrink:0;height:90px;position:absolute}.font-library__page-selection{font-size:11px;font-weight:var(--wpds-typography-font-weight-emphasis,600);text-transform:uppercase}@media (min-width:600px){.font-library__page-selection .components-select-control__input{font-size:11px!important;font-weight:var(--wpds-typography-font-weight-emphasis,600)}}.font-library__search{width:240px}.font-library__fonts-title{font-size:11px;font-weight:var(--wpds-typography-font-weight-emphasis,600);margin-bottom:0;margin-top:0;text-transform:uppercase}.font-library__fonts-list{list-style:none;margin-bottom:0;margin-top:0;padding:0}.font-library__fonts-list-item{margin-bottom:0}.font-library__font-demo{position:relative}.font-library__font-card{border:1px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);box-sizing:border-box;height:auto!important;margin-top:-1px;padding:16px;width:100%}.font-library__font-card:hover{background-color:#f0f0f0}.font-library__font-card:focus{position:relative}.font-library__font-card .font-library__font-card__name{font-weight:700}.font-library__font-card .font-library__font-card__count{color:#757575}.font-library__font-card .font-library__font-variant_demo-image{display:block;height:24px;width:auto}@media not (prefers-reduced-motion){.font-library__font-card .font-library__font-variant_demo-image{transition:opacity var(--wpds-motion-duration-lg,.3s) var(--wpds-motion-easing-subtle,cubic-bezier(.15,0,.15,1))}}.font-library__font-card .font-library__font-variant_demo-image.is-loading{left:0;opacity:0;position:absolute;top:0}.font-library__font-card .font-library__font-variant-demo-skeleton{border-radius:var(--wpds-border-radius-sm,2px);height:24px}.font-library__font-card .font-library__font-variant_demo-text{flex-shrink:0;white-space:nowrap}@media not (prefers-reduced-motion){.font-library__font-card .font-library__font-variant_demo-text{transition:opacity .3s ease-in-out}}.font-library-modal__tablist-container{background:#fff;border-bottom:1px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);position:sticky;top:0;z-index:1}.font-library__upload-area{align-items:center;display:flex;height:256px!important;justify-content:center;width:100%}button.font-library__upload-area{background-color:#f0f0f0}.font-library__local-fonts{margin:24px auto;width:80%}.font-library__local-fonts .font-library__upload-area__text{color:#757575}.font-library__google-fonts-confirm{align-items:center;display:flex;justify-content:center;margin-top:64px}.font-library__google-fonts-confirm p{line-height:1.4}.font-library__google-fonts-confirm h2{font-size:1.2rem;font-weight:400}.font-library__google-fonts-confirm .components-card{padding:16px;width:400px}.font-library__google-fonts-confirm .components-button{justify-content:center;width:100%}.font-library__select-all{padding:16px 16px 16px 17px}.font-library__select-all .components-checkbox-control__label{padding-left:16px}.global-styles-ui-pagination .components-button.is-tertiary{height:32px;justify-content:center;width:32px}.global-styles-ui-screen-revisions__revisions-list{flex-grow:1;list-style:none;margin:0 16px 16px}.global-styles-ui-screen-revisions__revisions-list li{margin-bottom:0}.global-styles-ui-screen-revisions__revision-item{cursor:var(--wpds-cursor-control,pointer);display:flex;flex-direction:column;position:relative}.global-styles-ui-screen-revisions__revision-item[role=option]:active,.global-styles-ui-screen-revisions__revision-item[role=option]:focus{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid transparent}.global-styles-ui-screen-revisions__revision-item:hover{background:rgba(var(--wp-admin-theme-color--rgb),.04)}.global-styles-ui-screen-revisions__revision-item:hover .global-styles-ui-screen-revisions__date{color:var(--wp-admin-theme-color)}.global-styles-ui-screen-revisions__revision-item:after,.global-styles-ui-screen-revisions__revision-item:before{content:"\\a";display:block;position:absolute}.global-styles-ui-screen-revisions__revision-item:before{background:#ddd;border:4px solid transparent;border-radius:50%;height:8px;left:17px;top:18px;transform:translate(-50%,-50%);width:8px;z-index:1}.global-styles-ui-screen-revisions__revision-item[aria-selected=true]{background:rgba(var(--wp-admin-theme-color--rgb),.04);border-radius:2px;color:var(--wp-admin-theme-color);outline:3px solid transparent;outline-offset:-2px}.global-styles-ui-screen-revisions__revision-item[aria-selected=true] .global-styles-ui-screen-revisions__date{color:var(--wp-admin-theme-color)}.global-styles-ui-screen-revisions__revision-item[aria-selected=true]:before{background:var(--wp-admin-theme-color)}.global-styles-ui-screen-revisions__revision-item[aria-selected=true] .global-styles-ui-screen-revisions__changes>li,.global-styles-ui-screen-revisions__revision-item[aria-selected=true] .global-styles-ui-screen-revisions__meta{color:#1e1e1e}.global-styles-ui-screen-revisions__revision-item:after{border:.5px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);height:100%;left:16px;top:0;width:0}.global-styles-ui-screen-revisions__revision-item:first-child:after{top:18px}.global-styles-ui-screen-revisions__revision-item:last-child:after{height:18px}.global-styles-ui-screen-revisions__revision-item-wrapper{display:block;padding:12px 12px 4px 40px}.global-styles-ui-screen-revisions__active-badge,.global-styles-ui-screen-revisions__apply-button.is-primary{align-self:flex-start;margin:0 12px 12px 40px}.global-styles-ui-screen-revisions__changes,.global-styles-ui-screen-revisions__meta{color:#757575;font-size:12px}.global-styles-ui-screen-revisions__description{align-items:flex-start;display:flex;flex-direction:column;gap:8px}.global-styles-ui-screen-revisions__description .global-styles-ui-screen-revisions__date{font-size:12px;font-weight:var(--wpds-typography-font-weight-emphasis,600);text-transform:uppercase}.global-styles-ui-screen-revisions__meta{align-items:flex-start;display:flex;justify-content:start;margin-bottom:4px;text-align:left;width:100%}.global-styles-ui-screen-revisions__meta img{border-radius:100%;height:16px;margin-right:8px;width:16px}.global-styles-ui-screen-revisions__loading{margin:24px auto!important}.global-styles-ui-screen-revisions__changes{line-height:1.4;list-style:disc;margin-left:12px;text-align:left}.global-styles-ui-screen-revisions__changes li{margin-bottom:4px}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination{gap:2px;justify-content:space-between}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .edit-site-pagination__total{height:1px;left:-1000px;margin:-1px;overflow:hidden;position:absolute}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-text{font-size:12px;will-change:opacity}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-button.is-tertiary{color:#1e1e1e}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-button.is-tertiary:disabled,.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-button.is-tertiary[aria-disabled=true]{color:#949494}.global-styles-ui-screen-revisions__footer{background:#fff;border-top:1px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);bottom:0;box-sizing:border-box;height:56px;min-width:100%;padding:12px;position:sticky;z-index:1}.global-styles-ui-variations_item{box-sizing:border-box;cursor:var(--wpds-cursor-control,pointer)}.global-styles-ui-variations_item .global-styles-ui-variations_item-preview{border-radius:2px;outline:1px solid rgba(0,0,0,.1);outline-offset:-1px;overflow:hidden;position:relative}@media not (prefers-reduced-motion){.global-styles-ui-variations_item .global-styles-ui-variations_item-preview{transition:outline .1s linear}}.global-styles-ui-variations_item .global-styles-ui-variations_item-preview.is-pill{height:32px}.global-styles-ui-variations_item .global-styles-ui-variations_item-preview.is-pill .block-editor-iframe__scale-container{overflow:hidden}.global-styles-ui-variations_item:not(.is-active):hover .global-styles-ui-variations_item-preview{outline-color:rgba(0,0,0,.3)}.global-styles-ui-variations_item.is-active .global-styles-ui-variations_item-preview,.global-styles-ui-variations_item:focus-visible .global-styles-ui-variations_item-preview{outline-color:#1e1e1e;outline-offset:1px;outline-width:var(--wp-admin-border-width-focus)}.global-styles-ui-variations_item:focus-visible .global-styles-ui-variations_item-preview{outline-color:var(--wp-admin-theme-color)}.global-styles-ui-preview__wrapper{display:block;max-width:100%;width:100%}.global-styles-ui-preview__wrapper.is-hoverable{cursor:var(--wpds-cursor-control,pointer)}.global-styles-ui-typography-preview{align-items:center;background:#f0f0f0;border-radius:2px;display:flex;justify-content:center;margin-bottom:20px;min-height:100px;overflow:hidden}.global-styles-ui-font-size__item{line-break:anywhere;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.global-styles-ui-font-size__item-value{color:#757575}.global-styles-ui-screen-typography__indicator{align-items:center;border-radius:2px;display:flex!important;font-size:14px;height:24px;justify-content:center;width:24px}.global-styles-ui-block-types-filter{margin-bottom:12px;padding:0 16px}.global-styles-ui-block-types-search{flex-grow:1}.global-styles-ui-block-types-item-list .global-styles-ui-block-types-item__icon{min-width:24px}.global-styles-ui-block-types-item-list__no-results{padding-top:16px}.global-styles-ui-block-types-item__indicator{background:var(--wp-admin-theme-color);border-radius:50%;flex:none;height:6px;margin-left:auto;width:6px}.global-styles-ui-screen-typography__font-variants-count{color:#757575}.global-styles-ui-font-families__manage-fonts{justify-content:center}.global-styles-ui-screen .color-block-support-panel{border-top:none;padding-left:0;padding-right:0;padding-top:0;row-gap:12px}.global-styles-ui-header{line-height:1.9!important;margin-bottom:0!important}.global-styles-ui-subtitle{font-size:11px!important;font-weight:var(--wpds-typography-font-weight-emphasis,600)!important;margin-bottom:0!important;text-transform:uppercase}.global-styles-ui-section-title{color:#2f2f2f;font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:1.2;margin:0;padding:16px 16px 0}.global-styles-ui-icon-with-current-color{fill:currentColor}.global-styles-ui__color-indicator-wrapper{flex-shrink:0;height:24px}.global-styles-ui__shadows-panel__options-container,.global-styles-ui__typography-panel__options-container{height:24px}.global-styles-ui__block-preview-panel{border:1px solid #ddd;border-radius:2px;overflow:hidden;position:relative;width:100%}.global-styles-ui__shadow-preview-panel{background-image:repeating-linear-gradient(45deg,#e0e0e0 25%,transparent 0,transparent 75%,#e0e0e0 0,#e0e0e0),repeating-linear-gradient(45deg,#e0e0e0 25%,transparent 0,transparent 75%,#e0e0e0 0,#e0e0e0);background-position:0 0,8px 8px;background-size:16px 16px;border:1px solid #ddd;border-radius:2px;height:144px;overflow:auto}.global-styles-ui__shadow-preview-panel .global-styles-ui__shadow-preview-block{background-color:#fff;border:1px solid #ddd;border-radius:2px;height:60px;width:60%}.global-styles-ui__shadow-editor__dropdown-content{width:280px}.global-styles-ui__shadow-editor-panel{margin-bottom:4px}.global-styles-ui__shadow-editor__dropdown{position:relative;width:100%}.global-styles-ui__shadow-editor__dropdown-toggle{border-radius:inherit;height:auto;padding-bottom:8px;padding-top:8px;text-align:left;width:100%}.global-styles-ui__shadow-editor__dropdown-toggle.is-open{background:#f0f0f0;color:var(--wp-admin-theme-color)}.global-styles-ui__shadow-editor__remove-button{opacity:0;position:absolute;right:8px;top:8px}.global-styles-ui__shadow-editor__dropdown-toggle:hover+.global-styles-ui__shadow-editor__remove-button,.global-styles-ui__shadow-editor__remove-button:focus,.global-styles-ui__shadow-editor__remove-button:hover{opacity:1}@media (hover:none){.global-styles-ui__shadow-editor__remove-button{opacity:1}}.global-styles-ui-screen-css{display:flex;flex:1 1 auto;flex-direction:column;margin:16px}.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel{flex:1 1 auto}.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel__custom-css-input,.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel__custom-css-input .components-base-control__field{display:flex;flex:1 1 auto;flex-direction:column}.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel__custom-css-input textarea{flex:1 1 auto}.global-styles-ui-screen-css-help-link{display:inline-block;margin-top:8px}.global-styles-ui-screen-variations{border-top:1px solid #ddd;margin-top:16px}.global-styles-ui-screen-variations>*{margin:24px 16px}.global-styles-ui-sidebar__navigator-provider{height:100%}.global-styles-ui-sidebar__navigator-screen{display:flex;flex-direction:column;height:100%}.global-styles-ui-color-palette__tablist-container{border-bottom:1px solid #ddd}.global-styles-ui-color-palette__tablist{margin-bottom:-1px}.global-styles-ui-sidebar__navigator-screen .single-column{grid-column:span 1}.global-styles-ui-screen-root.global-styles-ui-screen-root,.global-styles-ui-screen-style-variations.global-styles-ui-screen-style-variations{background:unset;color:inherit}.global-styles-ui-sidebar__panel .block-editor-block-icon svg{fill:currentColor}.global-styles-ui-screen-root__active-style-tile.global-styles-ui-screen-root__active-style-tile,.global-styles-ui-screen-root__active-style-tile.global-styles-ui-screen-root__active-style-tile .global-styles-ui-screen-root__active-style-tile-preview{border-radius:2px}.global-styles-ui-screen-root__active-style-tile-preview{clip-path:border-box}.global-styles-ui-color-palette-panel,.global-styles-ui-duotone-palette-panel,.global-styles-ui-gradient-palette-panel{padding:16px}.font-library-page__tablist{border-bottom:1px solid #f0f0f0;padding:0 24px}.font-library-page__tab-panel{flex-grow:1;max-height:calc(100% - 110px);overflow:auto}.font-library-page:has(.font-library__footer) .font-library-page__tab-panel{max-height:calc(100% - 198px)}')),document.head.appendChild(e)}var Gr=f(Z()),{Tabs:Ra}=Mu(Vv.privateApis),{useGlobalStyles:FE}=Mu(Dv.privateApis);function AE(){let{records:e=[]}=(0,Ea.useEntityRecords)("root","fontCollection",{_fields:"slug,name,description"}),[t,r]=(0,jv.useState)("installed-fonts"),{base:o,user:n,setUser:i,isReady:s}=FE(),a=(0,Bv.useSelect)(l=>l(Ea.store).canUser("create",{kind:"postType",name:"wp_font_family"}),[]);if(!s)return null;let u=[{id:"installed-fonts",title:(0,zn._x)("Library","Font library")}];return a&&(u.push({id:"upload-fonts",title:(0,zn._x)("Upload","noun")}),u.push(...(e||[]).map(({slug:l,name:c})=>({id:l,title:e&&e.length===1&&l==="google-fonts"?(0,zn.__)("Install Fonts"):c})))),(0,Gr.jsx)(gc,{title:(0,zn.__)("Fonts"),className:"font-library-page",children:(0,Gr.jsxs)(Ra,{selectedTabId:t,onSelect:l=>r(l),children:[(0,Gr.jsx)("div",{className:"font-library-page__tablist",children:(0,Gr.jsx)(Ra.TabList,{children:u.map(({id:l,title:c})=>(0,Gr.jsx)(Ra.Tab,{tabId:l,children:c},l))})}),u.map(({id:l})=>(0,Gr.jsx)(Ra.TabPanel,{tabId:l,focusable:!1,className:"font-library-page__tab-panel",children:(0,Gr.jsx)(Nu,{value:n,baseValue:o,onChange:i,activeTab:l})},l))]})})}function IE(){return(0,Gr.jsx)(AE,{})}var LE=IE;export{LE as stage}; /*! Bundled license information: use-sync-external-store/cjs/use-sync-external-store-shim.production.js: From 7ff053bd755f41f56694cb129c9ddc986fc265df Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Tue, 8 Sep 2026 15:58:32 +0000 Subject: [PATCH 434/634] Administration: Ensure the Activity Dashboard widget links are distinguished from surrounding text. Links within blocks of text must be distinguished in a way that does not rely on color. Developed in https://github.com/WordPress/wordpress-develop/pull/13357 Props khokansardar, afercia, joedolson. Fixes #66017. git-svn-id: https://develop.svn.wordpress.org/trunk@63536 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/css/dashboard.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-admin/css/dashboard.css b/src/wp-admin/css/dashboard.css index 7b0d0fe01c493..09f49cbe4daf9 100644 --- a/src/wp-admin/css/dashboard.css +++ b/src/wp-admin/css/dashboard.css @@ -1066,7 +1066,7 @@ body #dashboard-widgets .postbox form .submit { min-width: 0; } -#dashboard-widgets li a, +#dashboard-widgets li:not(.activity-block li):not(.comment) a, #dashboard-widgets .button-link, .community-events-footer a { text-decoration: none; From 0b05b54fce6dc00b984bd144a5337716aeb5da65 Mon Sep 17 00:00:00 2001 From: Lance Willett Date: Tue, 8 Sep 2026 16:22:58 +0000 Subject: [PATCH 435/634] Build/Test Tools: Await post title assertions in E2E tests. Await the title assertions after publishing and quick editing a post so each test waits for its assertion result before completing. Use one-time dialog handlers for application password revocation confirmations. Developed in: https://github.com/WordPress/wordpress-develop/pull/13425 Props adrianmoldovanwp, lucatume. Fixes #66068. git-svn-id: https://develop.svn.wordpress.org/trunk@63537 602fd350-edb4-49c9-b593-d223f7449a82 --- tests/e2e/specs/edit-posts.test.js | 4 ++-- tests/e2e/specs/profile/applications-passwords.test.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/e2e/specs/edit-posts.test.js b/tests/e2e/specs/edit-posts.test.js index 9b8cd37c60e50..b6d600afdebc8 100644 --- a/tests/e2e/specs/edit-posts.test.js +++ b/tests/e2e/specs/edit-posts.test.js @@ -36,7 +36,7 @@ test.describe( 'Edit Posts', () => { await expect( posts ).toHaveCount( 1 ); // Expect the title of the post to be correct. - expect( posts.first() ).toHaveText( title ); + await expect( posts.first() ).toHaveText( title ); } ); test( 'allows an existing post to be edited using the Edit button', async ( { @@ -104,7 +104,7 @@ test.describe( 'Edit Posts', () => { await expect( posts ).toHaveCount( 1 ); // Expect the title of the post to be correct. - expect( posts.first() ).toHaveText( `${ title } Edited` ); + await expect( posts.first() ).toHaveText( `${ title } Edited` ); } ); test( 'allows an existing post to be deleted using the Trash button', async ( { diff --git a/tests/e2e/specs/profile/applications-passwords.test.js b/tests/e2e/specs/profile/applications-passwords.test.js index f6c5cf7a781b7..aa7d2938d2c4f 100644 --- a/tests/e2e/specs/profile/applications-passwords.test.js +++ b/tests/e2e/specs/profile/applications-passwords.test.js @@ -50,7 +50,7 @@ test.describe( 'Manage applications passwords', () => { await expect( revokeButton ).toBeVisible(); // Revoke password. - page.on( 'dialog', ( dialog ) => dialog.accept() ); + page.once( 'dialog', ( dialog ) => dialog.accept() ); await revokeButton.click(); await expect( @@ -73,7 +73,7 @@ test.describe( 'Manage applications passwords', () => { await expect( revokeAllButton ).toBeVisible(); // Confirms revoking action. - page.on( 'dialog', ( dialog ) => dialog.accept() ); + page.once( 'dialog', ( dialog ) => dialog.accept() ); await revokeAllButton.click(); await expect( From 515a891cba4981689718d4d4d623aa845706b5c3 Mon Sep 17 00:00:00 2001 From: Jonathan Desrosiers Date: Tue, 8 Sep 2026 16:40:56 +0000 Subject: [PATCH 436/634] General: Bump the pinned hash for Gutenberg to `5a4cc50`. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This updates the pinned commit hash of the Gutenberg repository from `658c8cbe89db5d90279051d3bb816ca210fe4646 ` (version `23.8.0`) to `5a4cc502d43016f1efa66f8f6d9bd3bb4bb24d85`, which contains the latest changes up until the Node.js version was bumped from 20.x to 24.x. A full list of changes included in this commit can be found on GitHub: https://github.com/WordPress/gutenberg/compare/658c8cbe89db5d90279051d3bb816ca210fe4646..5a4cc502d43016f1efa66f8f6d9bd3bb4bb24d85. - Menu: Stabilize iframe reload test (https://github.com/WordPress/gutenberg/pull/82081) - Packages: Recover August 26 npm release metadata (https://github.com/WordPress/gutenberg/pull/82085) - Storybook: Demonstrate light, dark, and nested themes (https://github.com/WordPress/gutenberg/pull/82039) - Project Management: Add validation for missing GitHub labels configuration (https://github.com/WordPress/gutenberg/pull/76263) - Automated Testing: Enforce `.tsx` for all new React files (https://github.com/WordPress/gutenberg/pull/80123) - UI: Use root theme for portaled overlays (https://github.com/WordPress/gutenberg/pull/82038) - Menu: Stabilize portaled iframe test (https://github.com/WordPress/gutenberg/pull/82092) - Theme: Move post-release changelog entry to Unreleased (https://github.com/WordPress/gutenberg/pull/82093) - Media: Refuse a multi-file drop on a placeholder that takes one file (https://github.com/WordPress/gutenberg/pull/82046) - Font Library: Keep CSS custom properties unquoted in font previews (https://github.com/WordPress/gutenberg/pull/82010) - Add "reading settings" link to Front Page template (https://github.com/WordPress/gutenberg/pull/81987) - Docs: Fix grammar in documentation (https://github.com/WordPress/gutenberg/pull/82032) - Media Editor: refactor the panel layout (https://github.com/WordPress/gutenberg/pull/81840) - DataViews layout storybook: action names and primary status (https://github.com/WordPress/gutenberg/pull/82104) - Make `@wordpress/reusable-blocks` a no-op compatibility package (https://github.com/WordPress/gutenberg/pull/79186) - Widget Dashboard: add a Policy provider to govern what users may do (https://github.com/WordPress/gutenberg/pull/81967) - Build Package: Restore Core Boot layout compatibility (https://github.com/WordPress/gutenberg/pull/82112) - Edit Widgets: Guard canInsertBlockInWidgetArea against an empty block list (https://github.com/WordPress/gutenberg/pull/82107) - Build: Enforce NodeNext resolution for ESM packages (https://github.com/WordPress/gutenberg/pull/82088) - UI: Remove unused outset-ring--focus-within-visible class. (https://github.com/WordPress/gutenberg/pull/82077) - Inserter: Keep the block preview inside the viewport (https://github.com/WordPress/gutenberg/pull/82060) - Test: Enforce Vitest conventions and CI guardrails (https://github.com/WordPress/gutenberg/pull/81040) - Editor: Apply the showListViewByDefault preference in the shared editor (https://github.com/WordPress/gutenberg/pull/82119) - Release: Use CLI runtime for package publishing (https://github.com/WordPress/gutenberg/pull/82122) - Reusable Blocks: Remove leftover merge conflict markers from the changelog (https://github.com/WordPress/gutenberg/pull/82126) - chore: Update grep settings and remove comments (https://github.com/WordPress/gutenberg/pull/82121) - Fix: Content Guidelines: UX/UI Accessibility issues (https://github.com/WordPress/gutenberg/pull/80306) - Extensible Site Editor: Let menu items be added from the navigation screen (https://github.com/WordPress/gutenberg/pull/82125) - Navigation: Change WCText to Text (https://github.com/WordPress/gutenberg/pull/82130) - Storybook: Persist sidebar theme in URL (https://github.com/WordPress/gutenberg/pull/82111) - Editor assets endpoint: prime the theme JSON resolver before capturing (https://github.com/WordPress/gutenberg/pull/82134) - Remove unused dependencies across the monorepo (https://github.com/WordPress/gutenberg/pull/82103) - Update changelog instructions for agents (https://github.com/WordPress/gutenberg/pull/82097) - Build: Normalize JSX file extensions (https://github.com/WordPress/gutenberg/pull/80990) - Fix pattern export filenames by normalizing special characters (https://github.com/WordPress/gutenberg/pull/77033) - Site editor v2: navigation takes view config from endpoint (https://github.com/WordPress/gutenberg/pull/82138) - Extensible Site Editor: Load media assets before the media fields open (https://github.com/WordPress/gutenberg/pull/82135) - Site editor v2: pages take view config from endpoint (https://github.com/WordPress/gutenberg/pull/82140) - Extensible site editor: Add a revisions entry point to the Styles route (https://github.com/WordPress/gutenberg/pull/82142) - List: outdent an empty middle item without adding an item (https://github.com/WordPress/gutenberg/pull/82011) - Extensible site editor: Fall back to the raw title in edit route document titles (https://github.com/WordPress/gutenberg/pull/82143) - Blocks: Make BlockTransform a discriminated union over its type (https://github.com/WordPress/gutenberg/pull/81831) - Theme: add LightningCSS WPDS token fallback plugin (https://github.com/WordPress/gutenberg/pull/80401) - UI: Add popupWidth prop to item popup components (https://github.com/WordPress/gutenberg/pull/82087) - Snackbar: Restart timeout when a notice is recreated (https://github.com/WordPress/gutenberg/pull/81764) - Media: Report server upload failures in plain language (https://github.com/WordPress/gutenberg/pull/81735) - Format library: visualise non-breaking spaces (https://github.com/WordPress/gutenberg/pull/74040) - Bump the github-actions group across 1 directory with 2 updates (https://github.com/WordPress/gutenberg/pull/81932) - Try adding a Grid block variation to Gallery (https://github.com/WordPress/gutenberg/pull/81909) - Components: Keep foreign items out of a ToolsPanel menu (https://github.com/WordPress/gutenberg/pull/82127) - Enable Gallery columns and crop controls in viewport states (https://github.com/WordPress/gutenberg/pull/82003) - Query: Don't write excludeCurrent into blocks that never had it (https://github.com/WordPress/gutenberg/pull/82147) - Site title: Add fit-text support. (https://github.com/WordPress/gutenberg/pull/82074) - Accordion Panel: Reset padding-block when panel is hidden (https://github.com/WordPress/gutenberg/pull/81782) - Replace npm-run-all with native npm script chaining (https://github.com/WordPress/gutenberg/pull/82166) - Grid: per-item tile size limits (https://github.com/WordPress/gutenberg/pull/81899) - Fix: Tabs block: Anchor links in tab panels are not functional (https://github.com/WordPress/gutenberg/pull/81744) - Validate tsconfig references against declared dependencies (https://github.com/WordPress/gutenberg/pull/82106) - Performance tests: Build once and shard the suites across parallel CI jobs (https://github.com/WordPress/gutenberg/pull/82160) - Site Health widget: route the body's review link through the host (https://github.com/WordPress/gutenberg/pull/82066) - Build: allow wp-theme 2.x peer deps (https://github.com/WordPress/gutenberg/pull/82139) - Bundled packages: Add a check for transitive private API usage (https://github.com/WordPress/gutenberg/pull/82027) - List: try to preserve indentation level of children after outdenting+merging their parent (https://github.com/WordPress/gutenberg/pull/82145) - Block Library: Fix categories block handling of invalid taxonomy (https://github.com/WordPress/gutenberg/pull/82153) - useViewConfig: don't request the view config twice (https://github.com/WordPress/gutenberg/pull/82141) - Documentation: Remove invalid references to Babel in packages README (https://github.com/WordPress/gutenberg/pull/82176) - Automated Testing: Fix failing categories test on trunk (https://github.com/WordPress/gutenberg/pull/82182) - Jest: Update to 30.5.0 (https://github.com/WordPress/gutenberg/pull/82181) - Fix: Retain focus and caret position after Backspace undo of a prefix block transform (https://github.com/WordPress/gutenberg/pull/82116) - Scaffold e2e tests for the editor inspector consolidation experiment (https://github.com/WordPress/gutenberg/pull/82178) - Package lock: Deduplicate Jest dependencies (https://github.com/WordPress/gutenberg/pull/82187) - Components: Migrate remaining JSX files to TypeScript (https://github.com/WordPress/gutenberg/pull/82132) - Text: Use pretty wrapping by default (https://github.com/WordPress/gutenberg/pull/82133) - Build Tooling: Add browserslist config for build targeting (https://github.com/WordPress/gutenberg/pull/82179) - Columns: Fix appender drop zone visibility when dragging into empty column (https://github.com/WordPress/gutenberg/pull/77852) - Build: Require explicit JSX file extensions (https://github.com/WordPress/gutenberg/pull/82189) - Icons: Redraw 35 prominent icons with consistent stroke widths (https://github.com/WordPress/gutenberg/pull/78808) - Test: Classify and enforce unit test environments by filename (https://github.com/WordPress/gutenberg/pull/80991) - Test: Fix CI failures on trunk (https://github.com/WordPress/gutenberg/pull/82201) - Fix editor link colour cascade order for nested blocks (https://github.com/WordPress/gutenberg/pull/77833) - Add New Template: Show the design system focus ring instead of legacy box-shadow rings (https://github.com/WordPress/gutenberg/pull/82164) - List View: Don’t focus the last Table cell on keyboard activation (https://github.com/WordPress/gutenberg/pull/81964) - Fix spelling typos in docs and inline comments (https://github.com/WordPress/gutenberg/pull/82217) - CI: Pin npm version in the private API check job (https://github.com/WordPress/gutenberg/pull/82222) - Private APIs: Add back '@wordpress/dataviews' to the allowed core modules (https://github.com/WordPress/gutenberg/pull/82221) - Editor: Mark __unstableSaveForPreview options as optional (https://github.com/WordPress/gutenberg/pull/81858) - Docs: Explain when the Cover block's overlay controls appear (https://github.com/WordPress/gutenberg/pull/82234) - Menu: Use Text for item labels and descriptions (https://github.com/WordPress/gutenberg/pull/82237) - Test: Type pipe's supported array inputs (https://github.com/WordPress/gutenberg/pull/82210) - Widget Dashboard: keep the plain anchor for an empty-string download (https://github.com/WordPress/gutenberg/pull/82073) - CI: Read the required npm version from a single source (https://github.com/WordPress/gutenberg/pull/82235) - Components: Add `defaultShown`, `onShownChange` to `ToolsPanelItem` (https://github.com/WordPress/gutenberg/pull/78010) - Storybook: Drop unused support for js-as-jsx (https://github.com/WordPress/gutenberg/pull/82192) - Math: Declare clientNavigation interactivity support (https://github.com/WordPress/gutenberg/pull/82248) - Point to docmumentation about release assets (https://github.com/WordPress/gutenberg/pull/82250) - Change stray `ubuntu-latest` to `ubuntu-24.04`. (https://github.com/WordPress/gutenberg/pull/82156) - Performance tests: Reuse the plugin an earlier trunk run already built (https://github.com/WordPress/gutenberg/pull/82223) - Breadcrumb: Add UI component (https://github.com/WordPress/gutenberg/pull/80425) - Components: Cut the ToolsPanel render cascade (https://github.com/WordPress/gutenberg/pull/82180) - Fix: alert dialog box cancel button color (https://github.com/WordPress/gutenberg/pull/82261) - UI: Add Form best practices Storybook page (https://github.com/WordPress/gutenberg/pull/82197) - Media: Stop claiming "Upload complete" when upload failed (https://github.com/WordPress/gutenberg/pull/81397) - Boot, Site Editor: Seed content surfaces with default background color (https://github.com/WordPress/gutenberg/pull/81646) - Format Library: Fix Edit as HTML crash with background-only highlight (https://github.com/WordPress/gutenberg/pull/82215) - Remove the template activation experiment (https://github.com/WordPress/gutenberg/pull/82241) - Packages: Add cross-version compatibility skill (https://github.com/WordPress/gutenberg/pull/81890) - Show the block outline where the grab cursor shows (https://github.com/WordPress/gutenberg/pull/81798) - DataViews: Scope the search field's fixed width to the default UI search row (https://github.com/WordPress/gutenberg/pull/82128) - Background image: support setting the image from a URL (https://github.com/WordPress/gutenberg/pull/82230) - Border Box Control: Try moving the unlink button to the label row, and rename the panel to Borders (https://github.com/WordPress/gutenberg/pull/82163) - Widget Dashboard: govern Reset to default through the policy (https://github.com/WordPress/gutenberg/pull/82255) - Media: Attach unattached media to the current post on save/publish (https://github.com/WordPress/gutenberg/pull/81977) - Widget Dashboard: make the column count a host decision (https://github.com/WordPress/gutenberg/pull/82204) - Global styles: resolve theme-relative background image URLs for display (https://github.com/WordPress/gutenberg/pull/82242) - CI: Unify the automation comments into a single PR comment (https://github.com/WordPress/gutenberg/pull/82249) - Core Data: Convert hooks tests to renderHook and drop JSX (https://github.com/WordPress/gutenberg/pull/82276) - Release: Map [Type] Flaky Test to the Tools changelog section (https://github.com/WordPress/gutenberg/pull/82078) - DateTime tests: freeze the clock in the empty-value calendar test (https://github.com/WordPress/gutenberg/pull/82282) - DataForm: treat combined form fields purely as layout containers (https://github.com/WordPress/gutenberg/pull/82175) - Global styles engine: return a copy from getResolvedValue instead of mutating (https://github.com/WordPress/gutenberg/pull/82278) - Test: Migrate Node unit tests to Vitest (https://github.com/WordPress/gutenberg/pull/82211) - Icons: Redraw 64 icons to be stroke-based. (https://github.com/WordPress/gutenberg/pull/78812) - Tests: Fix Vitest setup and stale jest types under non-hoisting installs (https://github.com/WordPress/gutenberg/pull/82290) - UI: Rename Popup `popupWidth` prop to `width` (https://github.com/WordPress/gutenberg/pull/82193) - Query: Replace the "Reload full page enabled" modal with a snackbar notice (https://github.com/WordPress/gutenberg/pull/82246) - Project Management: Update CODEOWNERS to reflect current participation (https://github.com/WordPress/gutenberg/pull/82262) - Editor: Refactor the Options menu to use the Menu component (https://github.com/WordPress/gutenberg/pull/81564) - UI: Add Field.VisualLabel (https://github.com/WordPress/gutenberg/pull/82095) - Update Stylelint to v17 and related packages (https://github.com/WordPress/gutenberg/pull/80738) - Media: keep indexed PNG sub-sizes indexed (https://github.com/WordPress/gutenberg/pull/81884) - UI: Add Combobox and Autocomplete Status (https://github.com/WordPress/gutenberg/pull/82195) - UI: Drop Status and Empty live region test assertions (https://github.com/WordPress/gutenberg/pull/82300) - Project Management: Remove empty entries from CODEOWNERS (https://github.com/WordPress/gutenberg/pull/82292) - Documentation: Add recommended bulk suppressions configuration for ESLint (https://github.com/WordPress/gutenberg/pull/82303) - UI: Hide Input field ring when a slot control is focused (https://github.com/WordPress/gutenberg/pull/82257) - Widgets: Surface debugging details in the ErrorBoundary (https://github.com/WordPress/gutenberg/pull/82099) - TypeScript: Migrate format-library package to TS (https://github.com/WordPress/gutenberg/pull/79486) - BorderBoxControl: Make sure the group of controls is associated with the label (https://github.com/WordPress/gutenberg/pull/82279) - Image block cropping: Sync image size and link destination settings (https://github.com/WordPress/gutenberg/pull/82316) - Menu: Support multiple item descriptions (https://github.com/WordPress/gutenberg/pull/81825) - CI: Do not fail the type label check on a newly opened pull request (https://github.com/WordPress/gutenberg/pull/82322) - UI: Align overlay Trigger props with Base UI (https://github.com/WordPress/gutenberg/pull/81824) - Gallery block: Fix 'Crop images to fit' broken in editor (https://github.com/WordPress/gutenberg/pull/82318) - Widget Dashboard: enforce the policy on the staging layer for every instance operation (https://github.com/WordPress/gutenberg/pull/82256) - DataForm: Communicate the timezone in the datetime control (https://github.com/WordPress/gutenberg/pull/82291) - Add more e2e tests for the editor inspector consolidation experiment (https://github.com/WordPress/gutenberg/pull/82239) - Framework: Error on npm versions older than the required floor (https://github.com/WordPress/gutenberg/pull/82320) - Document every type for DataViews/DataForm/Field API (https://github.com/WordPress/gutenberg/pull/82326) - ESLint plugin: remove usage of Babel parser (https://github.com/WordPress/gutenberg/pull/82144) - DataViews: remove the rich text options from the control config type (https://github.com/WordPress/gutenberg/pull/82330) - Meta Boxes: Move meta box markup with moveBefore to keep classic editors alive (https://github.com/WordPress/gutenberg/pull/82243) - Add more e2e tests for the editor inspector consolidation experiment (https://github.com/WordPress/gutenberg/pull/82327) - Test: Enforce JavaScript test runner ownership (https://github.com/WordPress/gutenberg/pull/82299) - DataViews: clamp page after delete (https://github.com/WordPress/gutenberg/pull/82244) - Stylelint tools: Resolve test config extends from the workspace (https://github.com/WordPress/gutenberg/pull/82336) - Editor: Deprecate the `as` prop of the plugin menu item components (https://github.com/WordPress/gutenberg/pull/82319) - Icons: Convert Search icon to strokes (https://github.com/WordPress/gutenberg/pull/82338) - DataViews: Document that table column styles do not apply to the primary column (https://github.com/WordPress/gutenberg/pull/82238) - DataViews: add hierarchical levels story (https://github.com/WordPress/gutenberg/pull/82344) - CI: Add "Required changes from trunk" PR check (https://github.com/WordPress/gutenberg/pull/82272) - feat: Improve TypeScript definitions in the getEntityRecord function (https://github.com/WordPress/gutenberg/pull/81863) - Framework: Update Node.js to v24 LTS and npm to v11 (https://github.com/WordPress/gutenberg/pull/80395) - Revert "Framework: Update Node.js to v24 LTS and npm to v11 (https://github.com/WordPress/gutenberg/pull/80395)" (https://github.com/WordPress/gutenberg/pull/82355) - UI: Remove ValidityIndicator outer margin (https://github.com/WordPress/gutenberg/pull/82267) - Span the writing flow focus capture elements over the canvas (https://github.com/WordPress/gutenberg/pull/82354) - Fields: Hide the slug field for posts without a permalink (https://github.com/WordPress/gutenberg/pull/82341) - Fix: Responsive horizontal orientation does not override a vertical layout. (https://github.com/WordPress/gutenberg/pull/82364) - View Config: Move the table column style descriptions to the 7.2 compat layer (https://github.com/WordPress/gutenberg/pull/82372) - Block Library: Allow themes to override the padding added via background color (https://github.com/WordPress/gutenberg/pull/82024) - DataViews: Append an ellipsis to action labels that open a dialog (https://github.com/WordPress/gutenberg/pull/81994) - Pages: require authentication and a capability to render generated standalone pages (https://github.com/WordPress/gutenberg/pull/82254) - Build/Test Tools: Replace npx with npm exec --no (https://github.com/WordPress/gutenberg/pull/82331) - Navigation: restore flex-grow on container when accessible label is present (https://github.com/WordPress/gutenberg/pull/78447) - DOM Ready: Exclude src from published package files (https://github.com/WordPress/gutenberg/pull/77302) - UI: Support custom targets on Link and Menu.LinkItem (https://github.com/WordPress/gutenberg/pull/82347) - Escape HTML: Exclude src from published package files (https://github.com/WordPress/gutenberg/pull/77304) - keycodes: Exclude src from published files (https://github.com/WordPress/gutenberg/pull/77306) - Packages: Exclude src from block-serialization-default-parser published package (https://github.com/WordPress/gutenberg/pull/77307) - A11y: Exclude src from published package files (https://github.com/WordPress/gutenberg/pull/77309) - Packages: Exclude src from autop published package (https://github.com/WordPress/gutenberg/pull/77283) - Blob: Exclude src from published package files (https://github.com/WordPress/gutenberg/pull/77289) - Packages: Exclude src from deprecated published package (https://github.com/WordPress/gutenberg/pull/77303) - fix(list-reusable-blocks): exclude src from published files (https://github.com/WordPress/gutenberg/pull/77305) - Admin UI: Exclude src from published files and sideEffects (https://github.com/WordPress/gutenberg/pull/77285) - Standardize 'Back' and 'Go back' labels (https://github.com/WordPress/gutenberg/pull/79211) - Audio: Update autoplay help text for clarity (https://github.com/WordPress/gutenberg/pull/69978) - Theme JSON: Avoid rebuilding identical block schemas during sanitization (https://github.com/WordPress/gutenberg/pull/82203) - Docs: Improve setAttributes updater function wording (https://github.com/WordPress/gutenberg/pull/82405) - Query Loop: Rename the "Keyword" filter to "Search terms" and add help text (https://github.com/WordPress/gutenberg/pull/82387) - CI: add a per-workflow status check job and filter paths (https://github.com/WordPress/gutenberg/pull/81015) - ESLint: Thin use-recommended-components tests (https://github.com/WordPress/gutenberg/pull/82407) - UI: Fix enabled input placeholder contrast (https://github.com/WordPress/gutenberg/pull/82304) - Tab trap escape hatch: leave/enter the canvas with Escape/Enter (https://github.com/WordPress/gutenberg/pull/82314) - List: preserve client IDs on indent, just like outdent (https://github.com/WordPress/gutenberg/pull/59216) - Templates REST API: prevent fatal error when a null template reaches prepare_item_for_response (https://github.com/WordPress/gutenberg/pull/82374) - Editor: Refactor the View menu to use the Menu component (https://github.com/WordPress/gutenberg/pull/82321) - CSS Styling: Cleanup focus outline override for grid component (https://github.com/WordPress/gutenberg/pull/82337) - E2E: Run the site editor suite against the extensible site editor too (https://github.com/WordPress/gutenberg/pull/82117) - Fields: Remove unused CSS rule from slug field control (https://github.com/WordPress/gutenberg/pull/77961) - Fix: Footnote IDs can start with a digit and break CSS selectors (https://github.com/WordPress/gutenberg/pull/82398) - feat: Introduce 'Add Media' in the block controls for media-text block (https://github.com/WordPress/gutenberg/pull/82420) - fix: Audio element to have it's own name (https://github.com/WordPress/gutenberg/pull/82389) - Docs: Update Playground CLI wording (https://github.com/WordPress/gutenberg/pull/77579) - Upgrade React 19 to 19.2.8, read version from package.json (https://github.com/WordPress/gutenberg/pull/82439) - Tab Panel: Show focus with outline instead of legacy box-shadow ring (https://github.com/WordPress/gutenberg/pull/82421) - Editor: Fix disabled and link items of the more menu adapter (https://github.com/WordPress/gutenberg/pull/82428) - UI: Fix Menu.LinkItem target detection (https://github.com/WordPress/gutenberg/pull/82442) - SearchableSelect: Add form primitive to @wordpress/ui (https://github.com/WordPress/gutenberg/pull/80961) - Validated form controls: Use design token for invalid focus rings (https://github.com/WordPress/gutenberg/pull/82410) - feat: Update layout icons (https://github.com/WordPress/gutenberg/pull/82025) - Widgets: Replace {TODO} placeholder with PR number in changelog entries (https://github.com/WordPress/gutenberg/pull/82450) - UI: Remove ESLint ref suppressions and refactor AlertDialog state (https://github.com/WordPress/gutenberg/pull/82131) - Menu: Align selection indicators and prefix icons with item labels (https://github.com/WordPress/gutenberg/pull/82346) - ToggleGroupControl: Honor the root disabled prop (https://github.com/WordPress/gutenberg/pull/82259) - Block Library: Remove the form blocks experiment (https://github.com/WordPress/gutenberg/pull/82451) - List: indent and outdent multi-selected items with Tab (https://github.com/WordPress/gutenberg/pull/82411) - CodeRabbit: Only review on request, keep PR descriptions untouched (https://github.com/WordPress/gutenberg/pull/82448) - Privacy policy page badge: make it visible in Site Editor > Pages and Editor Inspector (https://github.com/WordPress/gutenberg/pull/82422) - Support `isAny` and `isNone` filter operators for numeric fields. (https://github.com/WordPress/gutenberg/pull/77942) - UI: Keep focus rings visible in overlay content (https://github.com/WordPress/gutenberg/pull/82443) - Menu: Correct alignment documentation and changelog (https://github.com/WordPress/gutenberg/pull/82455) - UI: Name unlabeled form primitive stories (https://github.com/WordPress/gutenberg/pull/82311) - UI: Re-read the native validity on blur in ControlWithError (https://github.com/WordPress/gutenberg/pull/82376) - Media Utils: Preserve arrays in multipart form data (https://github.com/WordPress/gutenberg/pull/82353) - fix: Remove stories from performance tests (https://github.com/WordPress/gutenberg/pull/82459) - Add the template e2e tests for the editor inspector consolidation experiment (https://github.com/WordPress/gutenberg/pull/82394) - UI: Fix Link target detection (https://github.com/WordPress/gutenberg/pull/82447) - Fix privacy policy page setting unit test on multisite (https://github.com/WordPress/gutenberg/pull/82467) - UI, DataViews: Give input and selection controls solid backgrounds (https://github.com/WordPress/gutenberg/pull/82391) - Fix LocationPicker popover alignment with InputGroup (https://github.com/WordPress/gutenberg/pull/82090) - List: indent and outdent a fully selected list item with Tab (https://github.com/WordPress/gutenberg/pull/82460) - UI: Fix Minimal Select popup width (https://github.com/WordPress/gutenberg/pull/82461) - Rich text: resolve owned event listeners once instead of per subscriber (https://github.com/WordPress/gutenberg/pull/80605) - UI: Keep borderless InputLayout chrome when disabled (https://github.com/WordPress/gutenberg/pull/82468) - Theme: Cache luminance for contrast checks (https://github.com/WordPress/gutenberg/pull/82445) - Add promptfoo for testing agent development setup and skills (https://github.com/WordPress/gutenberg/pull/80812) - wp-env: Fix Docker build errors with Debian Bullseye repositories (https://github.com/WordPress/gutenberg/pull/82478) - Query Loop: Fall back to `post` when the query has no `postType` (https://github.com/WordPress/gutenberg/pull/82465) - Block Supports: Bail early in state styles when a block has no style attribute (https://github.com/WordPress/gutenberg/pull/81908) - CSS Styling: Represent focus with outline for list view component (https://github.com/WordPress/gutenberg/pull/82129) - Icons: Remove the obsolete forced colors mode hack (https://github.com/WordPress/gutenberg/pull/82481) - Docs: Remove invalid `@return` tag from the `block_core_social_link_get_services` hook docblock (https://github.com/WordPress/gutenberg/pull/82488) - Site Editor: Add a root error boundary to prevent a blank screen (https://github.com/WordPress/gutenberg/pull/82486) - Writing Flow: Bail out of Enter handling when no block is selected (https://github.com/WordPress/gutenberg/pull/82424) - Docs: Remove the blank line between @param and @return in test docblocks (https://github.com/WordPress/gutenberg/pull/81907) - List View: Disable block icon colors while the block is selected (https://github.com/WordPress/gutenberg/pull/82498) - Fix: Restore layout styles for block style variations (https://github.com/WordPress/gutenberg/pull/82335) - Post slug: prefer server sanitization in the editor (https://github.com/WordPress/gutenberg/pull/78135) - Media Modal Experiment: Allow filtering by attached to the post, or unattached (https://github.com/WordPress/gutenberg/pull/81974) - Media editor: Lock the editing tools while a save is running (https://github.com/WordPress/gutenberg/pull/82417) - DataViews: Restrict the isAll filter operator to array fields (https://github.com/WordPress/gutenberg/pull/82463) - Media Fields: Pass the field's disabled state to the textarea controls (https://github.com/WordPress/gutenberg/pull/82516) - Theme: Make chroma capacity caching deterministic (https://github.com/WordPress/gutenberg/pull/82505) - Global Styles: Remove the color randomizer experiment (https://github.com/WordPress/gutenberg/pull/82452) - DataViews: Fix Field.sort TypeScript type definition (https://github.com/WordPress/gutenberg/pull/82162) - Migrate __experimentalText and __experimentalHeading to @wordpress/ui Text in Inspector Popover Header (https://github.com/WordPress/gutenberg/pull/77449) - Migrate __experimentalText to @wordpress/ui Text in Block switcher bindings hint (https://github.com/WordPress/gutenberg/pull/77366) - UI: Add Radio form primitive (https://github.com/WordPress/gutenberg/pull/82214) - Migrate __experimentalText to @wordpress/ui Text in Allowed Blocks Modal (https://github.com/WordPress/gutenberg/pull/78119) - UI: Add CheckboxControl (https://github.com/WordPress/gutenberg/pull/82213) - Core Data: Scope revisionId to the entity it is provided for (https://github.com/WordPress/gutenberg/pull/82517) - Migrate __experimentalText to @wordpress/ui Text in Pattern Overrides Dropdown (https://github.com/WordPress/gutenberg/pull/77492) - ProgressBar: Respect reduced motion preferences (https://github.com/WordPress/gutenberg/pull/82490) - Theme: Clarify color seed and warning guarantees (https://github.com/WordPress/gutenberg/pull/82526) - Theme: Build default ramps before token artifacts (https://github.com/WordPress/gutenberg/pull/82525) - CodeRabbit: Disable the review status comment (https://github.com/WordPress/gutenberg/pull/82534) - Project Management: Restore CODEOWNERS exclusions for suppression lists (https://github.com/WordPress/gutenberg/pull/82538) - Editor: merge duplicate "Enhancements" changelog sections (https://github.com/WordPress/gutenberg/pull/82533) - UI: Validate compound component context (https://github.com/WordPress/gutenberg/pull/82510) - Docs: Document isolated worktree setup (https://github.com/WordPress/gutenberg/pull/82524) - DataForm: render untyped fields without an edit control that are read-only (https://github.com/WordPress/gutenberg/pull/82514) - API Fetch: Add unregister to remove a registered middleware (https://github.com/WordPress/gutenberg/pull/82408) - Editor: Show revision data in Post Title component (https://github.com/WordPress/gutenberg/pull/82536) - Components: Add compound component composition diagnostics (https://github.com/WordPress/gutenberg/pull/82509) - Fieldset: Fix gap token to match spec (https://github.com/WordPress/gutenberg/pull/75479) - Test: Migrate deterministic JSDOM tests and harden Vitest isolation (https://github.com/WordPress/gutenberg/pull/82212) - Release: Make npm publication verification resumable (https://github.com/WordPress/gutenberg/pull/82089) - Block Library: Use 'useEntityProp' in Site Title and Tagline blocks (https://github.com/WordPress/gutenberg/pull/82518) - Theme: Migrate Terrazzo modes to resolvers (https://github.com/WordPress/gutenberg/pull/82537) - Fix auto-capitalization after Enter on iOS Safari (https://github.com/WordPress/gutenberg/pull/82475) - Update navigation link block name, use a default variation for custom link (https://github.com/WordPress/gutenberg/pull/82375) - API Fetch: Expose defaultFetchHandler so overrides can restore it (https://github.com/WordPress/gutenberg/pull/82553) - Core Data: Return a stable record for equivalent `_fields` queries (https://github.com/WordPress/gutenberg/pull/82552) - API Fetch: Rename defaultFetchHandler parameter to options (https://github.com/WordPress/gutenberg/pull/82588) - Fields: remove unused custom sort from the author fields (https://github.com/WordPress/gutenberg/pull/82559) - Fields: Declare the caption, alt text, description and ping status controls through the Field API (https://github.com/WordPress/gutenberg/pull/82539) - Docs: Align @param tag columns in phpunit/ docblocks (https://github.com/WordPress/gutenberg/pull/81904) - Docs: Align @param tag columns in lib/ docblocks (https://github.com/WordPress/gutenberg/pull/81902) - Docs: Align @param tag columns in packages/ docblocks (https://github.com/WordPress/gutenberg/pull/81903) - Fix help paragraph color contrast ratio in the Connectors page. (https://github.com/WordPress/gutenberg/pull/82378) - DataViews: Declare transitive dependencies imported by the ./wp bundle (https://github.com/WordPress/gutenberg/pull/81843) - DataForm: Add a `showPlaceholderIfEmpty` option to the panel layout (https://github.com/WordPress/gutenberg/pull/82527) - Global Styles UI: migrate revisions Active Badge to UI Badge (https://github.com/WordPress/gutenberg/pull/82560) - UI: Put overflow on Select.List instead of a nested wrapper (https://github.com/WordPress/gutenberg/pull/82470) - Editor: migrate post-card-panel Badge to UI Badge (https://github.com/WordPress/gutenberg/pull/82500) - Fields: migrate page-title Badge to UI Badge (https://github.com/WordPress/gutenberg/pull/82499) - DataViews: Skip table columns for field ids without a field definition (https://github.com/WordPress/gutenberg/pull/82601) - View config: remove stale fields from the wp_template default view (https://github.com/WordPress/gutenberg/pull/82602) - Rich text: restore contenteditable on pointercancel (https://github.com/WordPress/gutenberg/pull/82598) - Components: Add an Emotion-to-SCSS migration skill and guide (https://github.com/WordPress/gutenberg/pull/82567) See #66070. git-svn-id: https://develop.svn.wordpress.org/trunk@63538 602fd350-edb4-49c9-b593-d223f7449a82 --- package.json | 2 +- .../assets/script-loader-packages.php | 58 +- .../assets/script-modules-packages.php | 18 +- src/wp-includes/blocks/accordion-item.php | 2 +- src/wp-includes/blocks/accordion.php | 4 +- src/wp-includes/blocks/blocks-json.php | 13 +- src/wp-includes/blocks/breadcrumbs.php | 8 +- src/wp-includes/blocks/categories.php | 4 + src/wp-includes/blocks/comment-template.php | 4 +- src/wp-includes/blocks/gallery.php | 290 +++-- src/wp-includes/blocks/gallery/block.json | 7 +- src/wp-includes/blocks/heading.php | 2 +- src/wp-includes/blocks/home-link.php | 4 +- src/wp-includes/blocks/icon.php | 24 +- src/wp-includes/blocks/list.php | 2 +- src/wp-includes/blocks/math/block.json | 3 + src/wp-includes/blocks/navigation-link.php | 10 +- .../blocks/navigation-link/block.json | 2 +- src/wp-includes/blocks/navigation.php | 28 +- src/wp-includes/blocks/page-list.php | 20 +- .../blocks/post-author-biography.php | 6 +- src/wp-includes/blocks/post-author-name.php | 6 +- src/wp-includes/blocks/post-author.php | 6 +- src/wp-includes/blocks/post-comments-link.php | 8 +- src/wp-includes/blocks/post-content.php | 2 +- src/wp-includes/blocks/post-time-to-read.php | 6 +- src/wp-includes/blocks/query.php | 4 +- src/wp-includes/blocks/read-more.php | 2 +- src/wp-includes/blocks/search.php | 2 +- src/wp-includes/blocks/site-logo.php | 2 +- src/wp-includes/blocks/site-title/block.json | 1 + src/wp-includes/blocks/social-link.php | 1 - src/wp-includes/blocks/tab-list.php | 4 +- src/wp-includes/blocks/tabs.php | 3 +- src/wp-includes/blocks/widget-group.php | 6 +- src/wp-includes/build/constants.php | 2 +- .../pages/font-library/page-wp-admin.php | 8 +- .../build/pages/font-library/page.php | 16 + .../options-connectors/page-wp-admin.php | 8 +- .../build/pages/options-connectors/page.php | 16 + .../build/routes/connectors-home/content.js | 1009 +++++++++-------- .../connectors-home/content.min.asset.php | 2 +- .../routes/connectors-home/content.min.js | 2 +- .../build/routes/font-list/content.js | 597 +++++----- .../routes/font-list/content.min.asset.php | 2 +- .../build/routes/font-list/content.min.js | 10 +- .../images/icon-library/arrow-down-left.svg | 4 +- .../images/icon-library/arrow-down-right.svg | 4 +- .../images/icon-library/arrow-down.svg | 4 +- .../images/icon-library/arrow-left.svg | 4 +- .../images/icon-library/arrow-right.svg | 4 +- .../images/icon-library/arrow-up-left.svg | 4 +- .../images/icon-library/arrow-up-right.svg | 4 +- .../images/icon-library/arrow-up.svg | 4 +- .../images/icon-library/block-meta.svg | 4 +- .../images/icon-library/category.svg | 7 +- .../images/icon-library/caution.svg | 4 +- .../images/icon-library/chart-bar.svg | 4 +- src/wp-includes/images/icon-library/check.svg | 4 +- .../icon-library/chevron-down-small.svg | 4 +- .../images/icon-library/chevron-down.svg | 4 +- .../icon-library/chevron-left-small.svg | 4 +- .../images/icon-library/chevron-left.svg | 4 +- .../icon-library/chevron-right-small.svg | 4 +- .../images/icon-library/chevron-right.svg | 4 +- .../images/icon-library/chevron-up-down.svg | 4 +- .../images/icon-library/chevron-up-small.svg | 4 +- .../images/icon-library/chevron-up.svg | 4 +- src/wp-includes/images/icon-library/cover.svg | 5 +- .../images/icon-library/create.svg | 4 +- .../images/icon-library/download.svg | 4 +- src/wp-includes/images/icon-library/help.svg | 5 +- src/wp-includes/images/icon-library/image.svg | 4 +- src/wp-includes/images/icon-library/info.svg | 4 +- src/wp-includes/images/icon-library/menu.svg | 4 +- src/wp-includes/images/icon-library/next.svg | 4 +- .../images/icon-library/paragraph.svg | 5 +- .../images/icon-library/plus-circle.svg | 5 +- src/wp-includes/images/icon-library/plus.svg | 4 +- .../images/icon-library/previous.svg | 4 +- .../images/icon-library/published.svg | 5 +- src/wp-includes/images/icon-library/rss.svg | 5 +- .../images/icon-library/scheduled.svg | 5 +- .../images/icon-library/search.svg | 4 +- .../images/icon-library/star-empty.svg | 4 +- .../images/icon-library/star-filled.svg | 4 +- .../images/icon-library/star-half.svg | 5 +- .../images/icon-library/styles.svg | 5 +- src/wp-includes/images/icon-library/tip.svg | 4 +- .../images/icon-library/upload.svg | 4 +- 90 files changed, 1291 insertions(+), 1133 deletions(-) diff --git a/package.json b/package.json index 8158bc2ee96f6..7c9e99a625534 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "url": "https://develop.svn.wordpress.org/trunk" }, "gutenberg": { - "sha": "658c8cbe89db5d90279051d3bb816ca210fe4646", + "sha": "5a4cc502d43016f1efa66f8f6d9bd3bb4bb24d85", "ghcrRepo": "WordPress/gutenberg/gutenberg-wp-develop-build" }, "engines": { diff --git a/src/wp-includes/assets/script-loader-packages.php b/src/wp-includes/assets/script-loader-packages.php index 84e2e5c25f3b2..c6a755c4e2a0a 100644 --- a/src/wp-includes/assets/script-loader-packages.php +++ b/src/wp-includes/assets/script-loader-packages.php @@ -21,7 +21,7 @@ 'wp-private-apis', 'wp-url' ), - 'version' => '6f2a4faeee3c722b1e57' + 'version' => '5cae250de64a68ada734' ), 'autop.js' => array( 'dependencies' => array( @@ -67,7 +67,7 @@ 'wp-url', 'wp-warning' ), - 'version' => '251bed20addbd4898951' + 'version' => '24621af54a8dc0a92a8e' ), 'block-editor.js' => array( 'dependencies' => array( @@ -105,7 +105,7 @@ 'wp-url', 'wp-warning' ), - 'version' => '03664008984afcc5acd9' + 'version' => 'bb7e4c9d559d1e395318' ), 'block-library.js' => array( 'dependencies' => array( @@ -151,7 +151,7 @@ 'import' => 'dynamic' ) ), - 'version' => '98b1e389bb9bedd78731' + 'version' => '8e0f81358a96113469a4' ), 'block-serialization-default-parser.js' => array( 'dependencies' => array( @@ -184,7 +184,7 @@ 'wp-shortcode', 'wp-warning' ), - 'version' => '4f4d0c2b0372d76cb1cf' + 'version' => '49562ec003979bd1595c' ), 'commands.js' => array( 'dependencies' => array( @@ -201,7 +201,7 @@ 'wp-primitives', 'wp-private-apis' ), - 'version' => '709b81f6965aa3f3fad1' + 'version' => '3df8385dbb6e2a481531' ), 'components.js' => array( 'dependencies' => array( @@ -226,7 +226,7 @@ 'wp-theme', 'wp-warning' ), - 'version' => '7d125f63c887366dc3c5' + 'version' => '5b148bfc313b70dc9a4b' ), 'compose.js' => array( 'dependencies' => array( @@ -283,7 +283,7 @@ 'wp-url', 'wp-warning' ), - 'version' => '09960f621ea22390d652' + 'version' => '168b7542169d2fde8357' ), 'customize-widgets.js' => array( 'dependencies' => array( @@ -319,7 +319,7 @@ 'import' => 'static' ) ), - 'version' => 'b63345eff7801e61c8d8' + 'version' => '2483be73e6c08b1b7857' ), 'data.js' => array( 'dependencies' => array( @@ -410,7 +410,7 @@ 'import' => 'static' ) ), - 'version' => '1879e16de755e7c0c695' + 'version' => '585373eb7cbed3a73194' ), 'edit-site.js' => array( 'dependencies' => array( @@ -459,7 +459,7 @@ 'import' => 'static' ) ), - 'version' => '251e0a5d7d1c24545199' + 'version' => '0ed65d6f92588618d88d' ), 'edit-widgets.js' => array( 'dependencies' => array( @@ -501,7 +501,7 @@ 'import' => 'static' ) ), - 'version' => 'aa6a14fc303abfc52e8c' + 'version' => '3d65e74685d1cddb700a' ), 'editor.js' => array( 'dependencies' => array( @@ -552,7 +552,7 @@ 'import' => 'static' ) ), - 'version' => 'b3fca63dd478300ba9a3' + 'version' => 'ca21417bde93de2233f3' ), 'element.js' => array( 'dependencies' => array( @@ -594,7 +594,7 @@ 'import' => 'dynamic' ) ), - 'version' => '7bb348819bb9bb6642b1' + 'version' => '255ba1a7c73110ccd6b2' ), 'hooks.js' => array( 'dependencies' => array( @@ -645,7 +645,7 @@ 'wp-element', 'wp-i18n' ), - 'version' => '68a57d388ce085b9691e' + 'version' => 'da035ad6b481354267f8' ), 'media-utils.js' => array( 'dependencies' => array( @@ -672,7 +672,7 @@ 'wp-url', 'wp-warning' ), - 'version' => '957851f36fe387c2272e' + 'version' => 'ae94af80c12fd82c2a18' ), 'notices.js' => array( 'dependencies' => array( @@ -711,7 +711,7 @@ 'wp-url', 'wp-warning' ), - 'version' => '74662e7976508e52fa17' + 'version' => '10c0f0e7da90fc1de354' ), 'plugins.js' => array( 'dependencies' => array( @@ -739,7 +739,7 @@ 'wp-primitives', 'wp-private-apis' ), - 'version' => '4d5774967128e9bf2193' + 'version' => 'f7e32b791afe5c65affa' ), 'preferences-persistence.js' => array( 'dependencies' => array( @@ -764,7 +764,7 @@ 'dependencies' => array( ), - 'version' => '91c41cc1d8b79a320132' + 'version' => 'df3615fd5cb379fb7ffe' ), 'react-i18n.js' => array( 'dependencies' => array( @@ -782,20 +782,10 @@ ), 'reusable-blocks.js' => array( 'dependencies' => array( - 'react-jsx-runtime', - 'wp-block-editor', - 'wp-blocks', - 'wp-components', - 'wp-core-data', 'wp-data', - 'wp-deprecated', - 'wp-element', - 'wp-i18n', - 'wp-notices', - 'wp-primitives', - 'wp-url' + 'wp-deprecated' ), - 'version' => 'dd1bd3b09f7d73c21d0e' + 'version' => 'fd62928dce12a860a327' ), 'rich-text.js' => array( 'dependencies' => array( @@ -810,7 +800,7 @@ 'wp-keycodes', 'wp-private-apis' ), - 'version' => '3e5852e42cee1c239bae' + 'version' => '7f83233b1caefc2146bb' ), 'router.js' => array( 'dependencies' => array( @@ -864,7 +854,7 @@ 'wp-element', 'wp-private-apis' ), - 'version' => '763f42e590ad17dfa74c' + 'version' => '3543b084ef1597ce5852' ), 'token-list.js' => array( 'dependencies' => array( @@ -899,7 +889,7 @@ 'import' => 'dynamic' ) ), - 'version' => 'f7174b0617bcd68e57c3' + 'version' => '996352700f53b76866a5' ), 'url.js' => array( 'dependencies' => array( diff --git a/src/wp-includes/assets/script-modules-packages.php b/src/wp-includes/assets/script-modules-packages.php index b13e153a0fad4..38fcd0e5821fa 100644 --- a/src/wp-includes/assets/script-modules-packages.php +++ b/src/wp-includes/assets/script-modules-packages.php @@ -48,12 +48,6 @@ ), 'version' => 'a9114a756e418400594c' ), - 'block-library/form/view.js' => array( - 'dependencies' => array( - - ), - 'version' => '5542f8ad251fe43ef09e' - ), 'block-library/image/view.js' => array( 'dependencies' => array( @@ -128,7 +122,7 @@ 'import' => 'static' ) ), - 'version' => '92c832aff6e4039db1ce' + 'version' => '0684c8bb3dc8582b92ea' ), 'boot/index.js' => array( 'dependencies' => array( @@ -168,7 +162,7 @@ 'import' => 'static' ) ), - 'version' => '8cc5f2c749590d7b592a' + 'version' => '561d400a81b4d92e0ab6' ), 'connectors/index.js' => array( 'dependencies' => array( @@ -225,7 +219,7 @@ 'import' => 'static' ) ), - 'version' => 'f6fe09cfa8a820e494b9' + 'version' => 'cbb305a20ffe909edb3f' ), 'interactivity/index.js' => array( 'dependencies' => array( @@ -293,7 +287,7 @@ 'wp-private-apis', 'wp-style-engine' ), - 'version' => '26702529626be08dab3c' + 'version' => '68563009a3346a87bfa0' ), 'route/index.js' => array( 'dependencies' => array( @@ -338,7 +332,7 @@ 'dependencies' => array( ), - 'version' => '685442d334b2d3e70832' + 'version' => '7e33cd8c4128731126e8' ), 'widget-primitives/index.js' => array( 'dependencies' => array( @@ -370,6 +364,6 @@ 'import' => 'dynamic' ) ), - 'version' => '090d73e88a5ee2c08223' + 'version' => '7a2d585edd951178791a' ) ); \ No newline at end of file diff --git a/src/wp-includes/blocks/accordion-item.php b/src/wp-includes/blocks/accordion-item.php index 0b83c3a8d04bd..1bda149d97dd0 100644 --- a/src/wp-includes/blocks/accordion-item.php +++ b/src/wp-includes/blocks/accordion-item.php @@ -7,7 +7,7 @@ * @since 6.9.0 * * @param array{ openByDefault: bool } $attributes The block attributes. - * @param string $content The block content. + * @param string $content The block content. * @return string Returns the updated markup. */ function block_core_accordion_item_render( array $attributes, string $content ): string { diff --git a/src/wp-includes/blocks/accordion.php b/src/wp-includes/blocks/accordion.php index 537904a6e402d..a840fe7dfed69 100644 --- a/src/wp-includes/blocks/accordion.php +++ b/src/wp-includes/blocks/accordion.php @@ -5,8 +5,8 @@ * @package WordPress * @since 6.9.0 * - * @param array $attributes The block attributes. - * @param string $content The block content. + * @param array $attributes The block attributes. + * @param string $content The block content. * * @return string Returns the updated markup. */ diff --git a/src/wp-includes/blocks/blocks-json.php b/src/wp-includes/blocks/blocks-json.php index 208e13036dd6c..1db9063e0b42b 100644 --- a/src/wp-includes/blocks/blocks-json.php +++ b/src/wp-includes/blocks/blocks-json.php @@ -2838,7 +2838,12 @@ 'layout' => array( 'allowSwitching' => false, 'allowInheriting' => false, - 'allowEditing' => false, + 'allowEditing' => true, + 'allowOrientation' => false, + 'allowJustification' => false, + 'allowVerticalAlignment' => false, + 'allowWrap' => false, + 'allowSizingOnChildren' => true, 'default' => array( 'type' => 'flex' ) @@ -3935,6 +3940,9 @@ '__experimentalDefaultControls' => array( 'fontSize' => true ) + ), + 'interactivity' => array( + 'clientNavigation' => true ) ), 'attributes' => array( @@ -4360,7 +4368,7 @@ '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'core/navigation-link', - 'title' => 'Custom Link', + 'title' => 'Navigation Link', 'category' => 'design', 'parent' => array( 'core/navigation' @@ -7657,6 +7665,7 @@ '__experimentalFontWeight' => true, '__experimentalLetterSpacing' => true, '__experimentalWritingMode' => true, + 'fitText' => true, '__experimentalDefaultControls' => array( 'fontSize' => true ) diff --git a/src/wp-includes/blocks/breadcrumbs.php b/src/wp-includes/blocks/breadcrumbs.php index 4fd9cee4b5aad..b633a9bc62ac1 100644 --- a/src/wp-includes/blocks/breadcrumbs.php +++ b/src/wp-includes/blocks/breadcrumbs.php @@ -263,8 +263,8 @@ function block_core_breadcrumbs_create_page_number_item( $query_var = 'paged' ) * * @since 7.0.0 * - * @param string $text The text content. - * @param bool $is_paged Whether we're on a paginated view. + * @param string $text The text content. + * @param bool $is_paged Whether we're on a paginated view. * * @return array The breadcrumb item data. */ @@ -298,7 +298,7 @@ function block_core_breadcrumbs_get_post_title( $post_id_or_object ) { * * @since 7.0.0 * - * @param int $post_id The post ID. + * @param int $post_id The post ID. * * @return array Array of breadcrumb item data. */ @@ -524,7 +524,7 @@ function block_core_breadcrumbs_get_terms_breadcrumbs( $post_id, $post_type ) { * * @since 7.0.0 * - * @param array $settings { + * @param array $settings { * Array of breadcrumb settings. Default empty array. * * @type string $taxonomy Optional. Taxonomy slug to use for breadcrumbs. diff --git a/src/wp-includes/blocks/categories.php b/src/wp-includes/blocks/categories.php index 9789bf5ca5b1b..5c4d40c5f4420 100644 --- a/src/wp-includes/blocks/categories.php +++ b/src/wp-includes/blocks/categories.php @@ -23,6 +23,10 @@ function render_block_core_categories( $attributes, $content, $block ) { $taxonomy = get_taxonomy( $attributes['taxonomy'] ); + if ( ! $taxonomy ) { + return ''; + } + $args = array( 'echo' => false, 'hierarchical' => ! empty( $attributes['showHierarchy'] ), diff --git a/src/wp-includes/blocks/comment-template.php b/src/wp-includes/blocks/comment-template.php index ec462e6a050de..de74313977f80 100644 --- a/src/wp-includes/blocks/comment-template.php +++ b/src/wp-includes/blocks/comment-template.php @@ -12,8 +12,8 @@ * * @global int $comment_depth * - * @param WP_Comment[] $comments The array of comments. - * @param WP_Block $block Block instance. + * @param WP_Comment[] $comments The array of comments. + * @param WP_Block $block Block instance. * @return string */ function block_core_comment_template_render_comments( $comments, $block ) { diff --git a/src/wp-includes/blocks/gallery.php b/src/wp-includes/blocks/gallery.php index 7823921975d0c..1a323e4fbb61c 100644 --- a/src/wp-includes/blocks/gallery.php +++ b/src/wp-includes/blocks/gallery.php @@ -87,6 +87,91 @@ function block_core_gallery_get_column_gap_value( $gap, $fallback_gap ) { return '0' === $gap_column ? '0px' : $gap_column; } +/** + * Returns Gallery-specific responsive Flex rules for a viewport. + * + * @since 7.1.0 + * + * @param string $selector Gallery block selector. + * @param mixed $viewport_style Viewport style data. + * @param string $media_query Viewport media query. + * @return array[] Gallery responsive Flex rules. + */ +function block_core_gallery_get_responsive_flex_style_rules( $selector, $viewport_style, $media_query ) { + if ( ! is_array( $viewport_style ) || ! is_string( $media_query ) ) { + return array(); + } + + $rules = array(); + $gallery_selector = "{$selector}.wp-block-gallery.has-nested-images:where(.is-layout-flex)"; + $image_selector = "{$gallery_selector} figure.wp-block-image:not(#individual-image)"; + $columns = $viewport_style['columns'] ?? null; + + if ( is_int( $columns ) && $columns >= 1 && $columns <= 8 ) { + $width = 1 === $columns + ? '100%' + : sprintf( + 'calc((100%% - (var(--wp--style--unstable-gallery-gap, 16px) * %1$d)) / %2$d)', + $columns - 1, + $columns + ); + $rules[] = array( + 'selector' => $image_selector, + 'declarations' => array( 'width' => "{$width} !important" ), + 'rules_group' => $media_query, + ); + } + + $image_crop = $viewport_style['imageCrop'] ?? null; + if ( ! is_bool( $image_crop ) ) { + return $rules; + } + + $rules[] = array( + 'selector' => $image_selector, + 'declarations' => $image_crop + ? array( + 'align-self' => 'inherit !important', + 'margin-bottom' => '0 !important', + ) + : array( + 'align-self' => 'auto !important', + 'margin-top' => '0 !important', + 'margin-bottom' => 'auto !important', + ), + 'rules_group' => $media_query, + ); + $rules[] = array( + 'selector' => "{$image_selector} > div:not(.components-drop-zone)", + 'declarations' => array( 'display' => $image_crop ? 'flex !important' : 'block !important' ), + 'rules_group' => $media_query, + ); + $rules[] = array( + 'selector' => "{$image_selector} > a", + 'declarations' => array( 'display' => $image_crop ? 'flex !important' : 'inline-block !important' ), + 'rules_group' => $media_query, + ); + $rules[] = array( + 'selector' => "{$image_selector} a,{$image_selector} img", + 'declarations' => $image_crop + ? array( + 'width' => '100% !important', + 'flex' => '1 0 0% !important', + 'height' => '100% !important', + 'object-fit' => 'cover !important', + ) + : array( + 'width' => 'auto !important', + 'flex' => '0 1 auto !important', + 'height' => 'auto !important', + 'object-fit' => 'fill !important', + ), + 'rules_group' => $media_query, + ); + + return $rules; +} + /** * Resolves a Gallery block's `dynamicContent` to an ordered list of image * attachment IDs. @@ -309,8 +394,15 @@ function block_core_gallery_render_dynamic_image( $attachment_id, $attributes, $ function block_core_gallery_render( $attributes, $content, $block ) { static $global_styles = null; + // Gallery blocks created before layout variations existed do not have an + // explicit layout attribute. Missing and malformed layout data therefore + // falls back to Flex so existing galleries retain their current appearance. + $layout = is_array( $attributes['layout'] ?? null ) ? $attributes['layout'] : array(); + $layout_type = $layout['type'] ?? null; + $is_flex_layout = ! is_string( $layout_type ) || '' === $layout_type || 'flex' === $layout_type; + // In dynamic mode the gallery's images are resolved at render time instead of - // being authored as inner blocks, so `save.js` persists at most the + // being authored as inner blocks, so `save.jsx` persists at most the // gallery-level caption — a bare `
`, or nothing when there is no // caption. Resolve the configured source to a list of attachments, render an // image block for each, and build the gallery `
` wrapper from scratch. @@ -357,124 +449,134 @@ function block_core_gallery_render( $attributes, $content, $block ) { // Build the wrapper rather than parsing/splicing saved markup. // `get_block_wrapper_attributes()` supplies the block-support // classes/styles (align, color, border, spacing, anchor id); the layout - // render filter adds the flex layout classes downstream — the same way a + // render filter adds the active layout classes downstream — the same way a // static gallery's wrapper is composed (`useBlockProps.save()` plus that // filter). Only the gallery-specific classes are added explicitly, and - // they mirror `save.js` (kept in sync deliberately — see that file). - $gallery_classes = 'wp-block-gallery has-nested-images'; - $gallery_classes .= isset( $attributes['columns'] ) - ? ' columns-' . (int) $attributes['columns'] - : ' columns-default'; - if ( $attributes['imageCrop'] ?? true ) { - $gallery_classes .= ' is-cropped'; + // they mirror `save.jsx` (kept in sync deliberately — see that file). + $gallery_classes = 'wp-block-gallery has-nested-images'; + if ( $is_flex_layout ) { + $gallery_classes .= isset( $attributes['columns'] ) + ? ' columns-' . (int) $attributes['columns'] + : ' columns-default'; + if ( $attributes['imageCrop'] ?? true ) { + $gallery_classes .= ' is-cropped'; + } } $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $gallery_classes ) ); - // In dynamic mode `save.js` persists only the gallery-level caption, so + // In dynamic mode `save.jsx` persists only the gallery-level caption, so // `$content` is the saved `
` (or empty). Append it after the // resolved images — matching the static gallery's `{images}{caption}` // order — without parsing it. $content = sprintf( '
%s%s
', $wrapper_attributes, $images_markup, $content ); } - // Adds a style tag for the --wp--style--unstable-gallery-gap var. - // The Gallery block needs to recalculate Image block width based on - // the current gap setting in order to maintain the number of flex columns - // so a css var is added to allow this. - - $style_attr = is_array( $attributes['style'] ?? null ) - ? $attributes['style'] - : array(); - if ( - defined( 'IS_GUTENBERG_PLUGIN' ) && - IS_GUTENBERG_PLUGIN && - function_exists( 'gutenberg_resolve_style_state_aliases' ) - ) { - $style_attr = gutenberg_resolve_style_state_aliases( $style_attr, 'core/gallery' ); - } - - $unique_gallery_classname = wp_unique_id( 'wp-block-gallery-' ); - $processed_content = new WP_HTML_Tag_Processor( $content ); + $processed_content = new WP_HTML_Tag_Processor( $content ); $processed_content->next_tag(); - $processed_content->add_class( $unique_gallery_classname ); - // --gallery-block--gutter-size is deprecated. --wp--style--gallery-gap-default should be used by themes that want to set a default - // gap on the gallery. - $fallback_gap = 'var( --wp--style--gallery-gap-default, var( --gallery-block--gutter-size, var( --wp--style--block-gap, 0.5em ) ) )'; + if ( $is_flex_layout ) { + // Add a style tag for the --wp--style--unstable-gallery-gap var. The + // Gallery's custom Flex layout recalculates Image block widths based on + // the current gap so it can maintain the selected number of columns. + $style_attr = is_array( $attributes['style'] ?? null ) + ? $attributes['style'] + : array(); + if ( + defined( 'IS_GUTENBERG_PLUGIN' ) && + IS_GUTENBERG_PLUGIN && + function_exists( 'gutenberg_resolve_style_state_aliases' ) + ) { + $style_attr = gutenberg_resolve_style_state_aliases( $style_attr, 'core/gallery' ); + } - if ( null === $global_styles ) { - $global_styles = function_exists( 'wp_get_global_styles' ) ? wp_get_global_styles() : array(); - } + $unique_gallery_classname = wp_unique_id( 'wp-block-gallery-' ); + $processed_content->add_class( $unique_gallery_classname ); - $global_gallery_styles = $global_styles['blocks']['core/gallery'] ?? array(); - $global_gallery_gap = $global_gallery_styles['spacing']['blockGap'] ?? $fallback_gap; - $has_block_gap = is_array( $style_attr['spacing'] ?? null ) && array_key_exists( 'blockGap', $style_attr['spacing'] ); - // Prefer the block's own gap value, then Gallery global styles. Missing - // values fall back to the Gallery blockGap default. - $block_gap = $has_block_gap - ? $style_attr['spacing']['blockGap'] - : $global_gallery_gap; - $gap_column = block_core_gallery_get_column_gap_value( $block_gap, $fallback_gap ); - - // Set the CSS variable to the column value for Gallery's flex width calculations. - $gallery_styles = array( - array( - 'selector' => ".wp-block-gallery.{$unique_gallery_classname}", - 'declarations' => array( - '--wp--style--unstable-gallery-gap' => $gap_column, - ), - ), - ); + // --gallery-block--gutter-size is deprecated. --wp--style--gallery-gap-default should be used by themes that want to set a default + // gap on the gallery. + $fallback_gap = 'var( --wp--style--gallery-gap-default, var( --gallery-block--gutter-size, var( --wp--style--block-gap, 0.5em ) ) )'; - $global_settings = wp_get_global_settings(); - $viewport_settings = $global_settings['viewport'] ?? null; - $responsive_media_queries = array(); - foreach ( array( 'WP_Theme_JSON_Gutenberg', 'WP_Theme_JSON' ) as $theme_json_class_name ) { - if ( method_exists( $theme_json_class_name, 'get_viewport_media_queries' ) ) { - $responsive_media_queries = $theme_json_class_name::get_viewport_media_queries( $viewport_settings ); - break; + if ( null === $global_styles ) { + $global_styles = function_exists( 'wp_get_global_styles' ) ? wp_get_global_styles() : array(); } - } - foreach ( $responsive_media_queries as $breakpoint => $media_query ) { - $viewport_style = $style_attr[ $breakpoint ] ?? null; - $has_viewport_block_gap = is_array( $viewport_style ) && - is_array( $viewport_style['spacing'] ?? null ) && - array_key_exists( 'blockGap', $viewport_style['spacing'] ); - $has_global_viewport_block_gap = is_array( $global_gallery_styles[ $breakpoint ]['spacing'] ?? null ) && - array_key_exists( 'blockGap', $global_gallery_styles[ $breakpoint ]['spacing'] ); - - // Viewport-specific block values win. Gallery global viewport values - // only apply when the block has no base gap, so they do not override an instance value. - if ( $has_viewport_block_gap ) { - $viewport_gap = $viewport_style['spacing']['blockGap']; - } elseif ( ! $has_block_gap && $has_global_viewport_block_gap ) { - $viewport_gap = $global_gallery_styles[ $breakpoint ]['spacing']['blockGap']; - } else { - continue; + $global_gallery_styles = $global_styles['blocks']['core/gallery'] ?? array(); + $global_gallery_gap = $global_gallery_styles['spacing']['blockGap'] ?? $fallback_gap; + $has_block_gap = is_array( $style_attr['spacing'] ?? null ) && array_key_exists( 'blockGap', $style_attr['spacing'] ); + // Prefer the block's own gap value, then Gallery global styles. Missing + // values fall back to the Gallery blockGap default. + $block_gap = $has_block_gap + ? $style_attr['spacing']['blockGap'] + : $global_gallery_gap; + $gap_column = block_core_gallery_get_column_gap_value( $block_gap, $fallback_gap ); + + // Set the CSS variable to the column value for Gallery's flex width calculations. + $gallery_styles = array( + array( + 'selector' => ".wp-block-gallery.{$unique_gallery_classname}", + 'declarations' => array( + '--wp--style--unstable-gallery-gap' => $gap_column, + ), + ), + ); + + $global_settings = wp_get_global_settings(); + $viewport_settings = $global_settings['viewport'] ?? null; + $responsive_media_queries = array(); + foreach ( array( 'WP_Theme_JSON_Gutenberg', 'WP_Theme_JSON' ) as $theme_json_class_name ) { + if ( method_exists( $theme_json_class_name, 'get_viewport_media_queries' ) ) { + $responsive_media_queries = $theme_json_class_name::get_viewport_media_queries( $viewport_settings ); + break; + } } - if ( null === $viewport_gap ) { - continue; + foreach ( $responsive_media_queries as $breakpoint => $media_query ) { + $viewport_style = $style_attr[ $breakpoint ] ?? null; + $has_viewport_block_gap = is_array( $viewport_style ) && + is_array( $viewport_style['spacing'] ?? null ) && + array_key_exists( 'blockGap', $viewport_style['spacing'] ); + $has_global_viewport_block_gap = is_array( $global_gallery_styles[ $breakpoint ]['spacing'] ?? null ) && + array_key_exists( 'blockGap', $global_gallery_styles[ $breakpoint ]['spacing'] ); + + // Viewport-specific block values win. Gallery global viewport values + // only apply when the block has no base gap, so they do not override an instance value. + if ( $has_viewport_block_gap ) { + $viewport_gap = $viewport_style['spacing']['blockGap']; + } elseif ( ! $has_block_gap && $has_global_viewport_block_gap ) { + $viewport_gap = $global_gallery_styles[ $breakpoint ]['spacing']['blockGap']; + } else { + $viewport_gap = null; + } + + if ( null !== $viewport_gap ) { + $gallery_styles[] = array( + 'selector' => ".wp-block-gallery.{$unique_gallery_classname}", + 'declarations' => array( + '--wp--style--unstable-gallery-gap' => block_core_gallery_get_column_gap_value( + $viewport_gap, + $fallback_gap + ), + ), + 'rules_group' => $media_query, + ); + } + + $gallery_styles = array_merge( + $gallery_styles, + block_core_gallery_get_responsive_flex_style_rules( + ".{$unique_gallery_classname}", + $viewport_style, + $media_query + ) + ); } - $gallery_styles[] = array( - 'selector' => ".wp-block-gallery.{$unique_gallery_classname}", - 'declarations' => array( - '--wp--style--unstable-gallery-gap' => block_core_gallery_get_column_gap_value( - $viewport_gap, - $fallback_gap - ), - ), - 'rules_group' => $media_query, + wp_style_engine_get_stylesheet_from_css_rules( + $gallery_styles, + array( 'context' => 'block-supports' ) ); } - wp_style_engine_get_stylesheet_from_css_rules( - $gallery_styles, - array( 'context' => 'block-supports' ) - ); - // The WP_HTML_Tag_Processor class calls get_updated_html() internally // when the instance is treated as a string, but here we explicitly // convert it to a string. diff --git a/src/wp-includes/blocks/gallery/block.json b/src/wp-includes/blocks/gallery/block.json index 1c53921757918..5f0ae512718ec 100644 --- a/src/wp-includes/blocks/gallery/block.json +++ b/src/wp-includes/blocks/gallery/block.json @@ -160,7 +160,12 @@ "layout": { "allowSwitching": false, "allowInheriting": false, - "allowEditing": false, + "allowEditing": true, + "allowOrientation": false, + "allowJustification": false, + "allowVerticalAlignment": false, + "allowWrap": false, + "allowSizingOnChildren": true, "default": { "type": "flex" } diff --git a/src/wp-includes/blocks/heading.php b/src/wp-includes/blocks/heading.php index 471e31f19f2ee..b712e9b631670 100644 --- a/src/wp-includes/blocks/heading.php +++ b/src/wp-includes/blocks/heading.php @@ -17,7 +17,7 @@ * @since 6.2.0 * * @param array $attributes Attributes of the block being rendered. - * @param string $content Content of the block being rendered. + * @param string $content Content of the block being rendered. * * @return string The content of the block being rendered. */ diff --git a/src/wp-includes/blocks/home-link.php b/src/wp-includes/blocks/home-link.php index fc2d18592ee75..d3b52c7ca946f 100644 --- a/src/wp-includes/blocks/home-link.php +++ b/src/wp-includes/blocks/home-link.php @@ -11,7 +11,7 @@ * * @since 6.0.0 * - * @param array $context home link block context. + * @param array $context home link block context. * @return array Colors CSS classes and inline styles. */ function block_core_home_link_build_css_colors( $context ) { @@ -64,7 +64,7 @@ function block_core_home_link_build_css_colors( $context ) { * * @since 6.0.0 * - * @param array $context Home link block context. + * @param array $context Home link block context. * @return string The li wrapper attributes. */ function block_core_home_link_build_li_wrapper_attributes( $context ) { diff --git a/src/wp-includes/blocks/icon.php b/src/wp-includes/blocks/icon.php index c010e7148346b..749ea140b27b4 100644 --- a/src/wp-includes/blocks/icon.php +++ b/src/wp-includes/blocks/icon.php @@ -96,7 +96,17 @@ function render_block_core_icon( $attributes ) { $processor = new WP_HTML_Tag_Processor( $svg ); if ( $processor->next_tag( 'svg' ) ) { if ( ! empty( $styles['css'] ) ) { - $processor->set_attribute( 'style', $styles['css'] ); + // Merge with the SVG's intrinsic style (e.g. `fill: none` on + // stroke-based icons) so it is preserved. The block styles come last + // so they win on any conflicting property. + $existing_style = $processor->get_attribute( 'style' ); + $trimmed_style = is_string( $existing_style ) + ? rtrim( trim( $existing_style ), ';' ) + : ''; + $merged_style = '' !== $trimmed_style + ? $trimmed_style . '; ' . $styles['css'] + : $styles['css']; + $processor->set_attribute( 'style', $merged_style ); } // Apply flip classes to the SVG. @@ -115,11 +125,13 @@ function render_block_core_icon( $attributes ) { if ( $rotation ) { $current_style = $processor->get_attribute( 'style' ) ?? ''; $rotation_css = 'rotate: ' . $rotation . 'deg;'; - if ( $current_style ) { - $processor->set_attribute( 'style', $current_style . ' ' . $rotation_css ); - } else { - $processor->set_attribute( 'style', $rotation_css ); - } + $trimmed_style = is_string( $current_style ) + ? rtrim( trim( $current_style ), ';' ) + : ''; + $merged_style = '' !== $trimmed_style + ? $trimmed_style . '; ' . $rotation_css + : $rotation_css; + $processor->set_attribute( 'style', $merged_style ); } $svg = $processor->get_updated_html(); diff --git a/src/wp-includes/blocks/list.php b/src/wp-includes/blocks/list.php index 1bffd81324857..5a5aecfb28078 100644 --- a/src/wp-includes/blocks/list.php +++ b/src/wp-includes/blocks/list.php @@ -15,7 +15,7 @@ * @see https://github.com/WordPress/gutenberg/issues/12420 * * @param array $attributes Attributes of the block being rendered. - * @param string $content Content of the block being rendered. + * @param string $content Content of the block being rendered. * * @return string The content of the block being rendered. */ diff --git a/src/wp-includes/blocks/math/block.json b/src/wp-includes/blocks/math/block.json index a305900ab9961..e8a09d5443300 100644 --- a/src/wp-includes/blocks/math/block.json +++ b/src/wp-includes/blocks/math/block.json @@ -36,6 +36,9 @@ "__experimentalDefaultControls": { "fontSize": true } + }, + "interactivity": { + "clientNavigation": true } }, "attributes": { diff --git a/src/wp-includes/blocks/navigation-link.php b/src/wp-includes/blocks/navigation-link.php index b941e35857c40..d6f329939b9e4 100644 --- a/src/wp-includes/blocks/navigation-link.php +++ b/src/wp-includes/blocks/navigation-link.php @@ -14,9 +14,9 @@ * * @since 5.9.0 * - * @param array $context Navigation block context. - * @param array $attributes Block attributes. - * @param bool $is_sub_menu Whether the link is part of a sub-menu. Default false. + * @param array $context Navigation block context. + * @param array $attributes Block attributes. + * @param bool $is_sub_menu Whether the link is part of a sub-menu. Default false. * @return array Colors CSS classes and inline styles. */ function block_core_navigation_link_build_css_colors( $context, $attributes, $is_sub_menu = false ) { @@ -90,7 +90,7 @@ function block_core_navigation_link_build_css_colors( $context, $attributes, $is * @since 5.9.0 * @deprecated 7.0.0 * - * @param array $context Navigation block context. + * @param array $context Navigation block context. * @return array Font size CSS classes and inline styles. */ function block_core_navigation_link_build_css_font_sizes( $context ) { @@ -308,7 +308,7 @@ function render_block_core_navigation_link( $attributes, $content, $block ) { * @since 5.9.0 * * @param WP_Taxonomy|WP_Post_Type $entity post type or taxonomy entity. - * @param string $kind string of value 'taxonomy' or 'post-type'. + * @param string $kind string of value 'taxonomy' or 'post-type'. * * @return array */ diff --git a/src/wp-includes/blocks/navigation-link/block.json b/src/wp-includes/blocks/navigation-link/block.json index 8cab34bc4d064..1e63f70a5cb3e 100644 --- a/src/wp-includes/blocks/navigation-link/block.json +++ b/src/wp-includes/blocks/navigation-link/block.json @@ -2,7 +2,7 @@ "$schema": "https://schemas.wp.org/trunk/block.json", "apiVersion": 3, "name": "core/navigation-link", - "title": "Custom Link", + "title": "Navigation Link", "category": "design", "parent": [ "core/navigation" ], "allowedBlocks": [ diff --git a/src/wp-includes/blocks/navigation.php b/src/wp-includes/blocks/navigation.php index 48af8ba468626..e67f727c60542 100644 --- a/src/wp-includes/blocks/navigation.php +++ b/src/wp-includes/blocks/navigation.php @@ -417,7 +417,7 @@ private static function disable_overlay_menu_for_nested_navigation_blocks( $bloc * @since 6.5.0 * * @param string $overlay_template_part_id The overlay template part ID in format "theme//slug". - * @param array $attributes The block attributes. + * @param array $attributes The block attributes. * @return WP_Block_List Returns the inner blocks for the overlay template part. */ private static function get_overlay_blocks_from_template_part( $overlay_template_part_id, $attributes ) { @@ -518,7 +518,7 @@ private static function get_overlay_blocks_from_template_part( $overlay_template * @since 6.5.0 * * @param array $attributes The block attributes. - * @param WP_Block $block The parsed block. + * @param WP_Block $block The parsed block. * @return WP_Block_List Returns the inner blocks for the navigation block. */ private static function get_inner_blocks( $attributes, $block ) { @@ -740,8 +740,8 @@ private static function get_overlay_inline_styles( $has_custom_overlay, $colors * * @since 6.5.0 * - * @param array $attributes The block attributes. - * @param WP_Block_List $inner_blocks The list of inner blocks. + * @param array $attributes The block attributes. + * @param WP_Block_List $inner_blocks The list of inner blocks. * @param string $inner_blocks_html The markup for the inner blocks. * @return string Returns the container markup. */ @@ -892,8 +892,8 @@ private static function get_responsive_container_markup( $attributes, $inner_blo * * @since 6.5.0 * - * @param array $attributes The block attributes. - * @param WP_Block_List $inner_blocks A list of inner blocks. + * @param array $attributes The block attributes. + * @param WP_Block_List $inner_blocks A list of inner blocks. * @return string Returns the navigation block markup. */ private static function get_nav_attributes( $attributes, $inner_blocks ) { @@ -979,7 +979,7 @@ private static function handle_view_script_module_loading( $attributes, $block, * * @since 6.5.0 * - * @param array $attributes The block attributes. + * @param array $attributes The block attributes. * @param WP_Block_List $inner_blocks The list of inner blocks. * @return string Returns the navigation wrapper markup. */ @@ -1786,12 +1786,12 @@ function block_core_navigation_typographic_presets_backcompatibility( $parsed_bl * * @deprecated 6.3.0 Use WP_Navigation_Fallback::parse_blocks_from_menu_items() instead. * - * @param array $menu_items An array of menu items that represent - * an individual level of a menu. - * @param array $menu_items_by_parent_id An array keyed by the id of the - * parent menu where each element is an - * array of menu items that belong to - * that parent. + * @param array $menu_items An array of menu items that represent + * an individual level of a menu. + * @param array $menu_items_by_parent_id An array keyed by the id of the + * parent menu where each element is an + * array of menu items that belong to + * that parent. * @return array An array of parsed block data. */ function block_core_navigation_parse_blocks_from_menu_items( $menu_items, $menu_items_by_parent_id ) { @@ -1891,7 +1891,7 @@ static function ( $a, $b ) { * * @deprecated 6.3.0 Use WP_Navigation_Fallback::get_classic_menu_fallback_blocks() instead. * - * @param object $classic_nav_menu WP_Term The classic navigation object to convert. + * @param object $classic_nav_menu WP_Term The classic navigation object to convert. * @return array the normalized parsed blocks. */ function block_core_navigation_get_classic_menu_fallback_blocks( $classic_nav_menu ) { diff --git a/src/wp-includes/blocks/page-list.php b/src/wp-includes/blocks/page-list.php index 395702068ec83..cf812a67d0ccb 100644 --- a/src/wp-includes/blocks/page-list.php +++ b/src/wp-includes/blocks/page-list.php @@ -36,8 +36,8 @@ function block_core_page_list_get_submenu_visibility( $context ) { * * @since 5.8.0 * - * @param array $attributes Block attributes. - * @param array $context Navigation block context. + * @param array $attributes Block attributes. + * @param array $context Navigation block context. * @return array Colors CSS classes and inline styles. */ function block_core_page_list_build_css_colors( $attributes, $context ) { @@ -128,14 +128,14 @@ function block_core_page_list_build_css_colors( $attributes, $context ) { * * @since 5.8.0 * - * @param string $submenu_visibility The submenu visibility mode: 'hover', 'click', or 'always'. - * @param boolean $show_submenu_icons Whether to show submenu indicator icons. - * @param boolean $is_navigation_child If block is a child of Navigation block. - * @param array $nested_pages The array of nested pages. - * @param boolean $is_nested Whether the submenu is nested or not. + * @param string $submenu_visibility The submenu visibility mode: 'hover', 'click', or 'always'. + * @param boolean $show_submenu_icons Whether to show submenu indicator icons. + * @param boolean $is_navigation_child If block is a child of Navigation block. + * @param array $nested_pages The array of nested pages. + * @param boolean $is_nested Whether the submenu is nested or not. * @param array $active_page_ancestor_ids An array of ancestor ids for active page. - * @param array $colors Color information for overlay styles. - * @param integer $depth The nesting depth. + * @param array $colors Color information for overlay styles. + * @param integer $depth The nesting depth. * * @return string List markup. */ @@ -227,7 +227,7 @@ function block_core_page_list_render_nested_page_list( $submenu_visibility, $sho * @since 5.8.0 * * @param array $current_level The level being iterated through. - * @param array $children The children grouped by parent post ID. + * @param array $children The children grouped by parent post ID. * * @return array The nested array of pages. */ diff --git a/src/wp-includes/blocks/post-author-biography.php b/src/wp-includes/blocks/post-author-biography.php index bd983f79e7609..5ef7f433d7709 100644 --- a/src/wp-includes/blocks/post-author-biography.php +++ b/src/wp-includes/blocks/post-author-biography.php @@ -10,9 +10,9 @@ * * @since 6.0.0 * - * @param array $attributes Block attributes. - * @param string $content Block default content. - * @param WP_Block $block Block instance. + * @param array $attributes Block attributes. + * @param string $content Block default content. + * @param WP_Block $block Block instance. * @return string Returns the rendered post author biography block. */ function render_block_core_post_author_biography( $attributes, $content, $block ) { diff --git a/src/wp-includes/blocks/post-author-name.php b/src/wp-includes/blocks/post-author-name.php index 73113eb1efc4b..f729696b781e8 100644 --- a/src/wp-includes/blocks/post-author-name.php +++ b/src/wp-includes/blocks/post-author-name.php @@ -10,9 +10,9 @@ * * @since 6.2.0 * - * @param array $attributes Block attributes. - * @param string $content Block default content. - * @param WP_Block $block Block instance. + * @param array $attributes Block attributes. + * @param string $content Block default content. + * @param WP_Block $block Block instance. * @return string Returns the rendered post author name block. */ function render_block_core_post_author_name( $attributes, $content, $block ) { diff --git a/src/wp-includes/blocks/post-author.php b/src/wp-includes/blocks/post-author.php index a4880f8a9e744..682fabb2805f1 100644 --- a/src/wp-includes/blocks/post-author.php +++ b/src/wp-includes/blocks/post-author.php @@ -10,9 +10,9 @@ * * @since 5.9.0 * - * @param array $attributes Block attributes. - * @param string $content Block default content. - * @param WP_Block $block Block instance. + * @param array $attributes Block attributes. + * @param string $content Block default content. + * @param WP_Block $block Block instance. * @return string Returns the rendered author block. */ function render_block_core_post_author( $attributes, $content, $block ) { diff --git a/src/wp-includes/blocks/post-comments-link.php b/src/wp-includes/blocks/post-comments-link.php index c6d33eb0cd65c..6f183a79eac2c 100644 --- a/src/wp-includes/blocks/post-comments-link.php +++ b/src/wp-includes/blocks/post-comments-link.php @@ -10,10 +10,10 @@ * * @since 6.9.0 * - * @param array $attributes Block attributes. - * @param string $content Block default content. - * @param WP_Block $block Block instance. - * @return string Returns the rendered link. + * @param array $attributes Block attributes. + * @param string $content Block default content. + * @param WP_Block $block Block instance. + * @return string Returns the rendered link. */ function render_block_core_post_comments_link( $attributes, $content, $block ) { if ( diff --git a/src/wp-includes/blocks/post-content.php b/src/wp-includes/blocks/post-content.php index b75d7144dab98..56429cd22a165 100644 --- a/src/wp-includes/blocks/post-content.php +++ b/src/wp-includes/blocks/post-content.php @@ -60,7 +60,7 @@ function render_block_core_post_content( $attributes, $content, $block ) { /** * The allowed tag names match the options offered in the editor. * - * @see packages/block-library/src/post-content/edit.js + * @see packages/block-library/src/post-content/edit.jsx */ $allowed_tag_names = array( 'div', 'main', 'section', 'article' ); $normalized_tag_name = strtolower( $attributes['tagName'] ); diff --git a/src/wp-includes/blocks/post-time-to-read.php b/src/wp-includes/blocks/post-time-to-read.php index 74a091d97c335..f3f336fbe932d 100644 --- a/src/wp-includes/blocks/post-time-to-read.php +++ b/src/wp-includes/blocks/post-time-to-read.php @@ -92,9 +92,9 @@ function block_core_post_time_to_read_word_count( $text, $type ) { * * @since 6.9.0 * - * @param array $attributes Block attributes. - * @param string $content Block default content. - * @param WP_Block $block Block instance. + * @param array $attributes Block attributes. + * @param string $content Block default content. + * @param WP_Block $block Block instance. * @return string Returns the rendered post author name block. */ function render_block_core_post_time_to_read( $attributes, $content, $block ) { diff --git a/src/wp-includes/blocks/query.php b/src/wp-includes/blocks/query.php index 73fc9a50928c1..404d8ac1b66e3 100644 --- a/src/wp-includes/blocks/query.php +++ b/src/wp-includes/blocks/query.php @@ -108,8 +108,8 @@ function block_core_query_disable_enhanced_pagination( $parsed_block ) { * by adding an attribute called `data-wp-navigation-disabled` which * is later handled by the front-end logic. * - * @param string $content The block content. - * @param array $block The full block, including name and attributes. + * @param string $content The block content. + * @param array $block The full block, including name and attributes. * @return string Returns the modified output of the query block. */ $render_query_callback = static function ( $content, $block ) use ( &$enhanced_query_stack, &$dirty_enhanced_queries, &$render_query_callback ) { diff --git a/src/wp-includes/blocks/read-more.php b/src/wp-includes/blocks/read-more.php index bf14f8ea242e8..81c4f0f0ba69d 100644 --- a/src/wp-includes/blocks/read-more.php +++ b/src/wp-includes/blocks/read-more.php @@ -13,7 +13,7 @@ * @param array $attributes Block attributes. * @param string $content Block default content. * @param WP_Block $block Block instance. - * @return string Returns the post link. + * @return string Returns the post link. */ function render_block_core_read_more( $attributes, $content, $block ) { if ( ! isset( $block->context['postId'] ) ) { diff --git a/src/wp-includes/blocks/search.php b/src/wp-includes/blocks/search.php index 8811e005e7f01..8a453bcfd1908 100644 --- a/src/wp-includes/blocks/search.php +++ b/src/wp-includes/blocks/search.php @@ -360,7 +360,7 @@ function apply_block_core_search_border_styles( $attributes, $property, &$wrappe * * @since 5.8.0 * - * @param array $attributes The block attributes. + * @param array $attributes The block attributes. * * @return array Style HTML attribute. */ diff --git a/src/wp-includes/blocks/site-logo.php b/src/wp-includes/blocks/site-logo.php index 915563461e30c..29357c9a8f3cf 100644 --- a/src/wp-includes/blocks/site-logo.php +++ b/src/wp-includes/blocks/site-logo.php @@ -139,7 +139,7 @@ function _override_custom_logo_theme_mod( $custom_logo ) { * * @since 5.8.0 * - * @param mixed $value Attachment ID of the custom logo or an empty value. + * @param mixed $value Attachment ID of the custom logo or an empty value. * @return mixed */ function _sync_custom_logo_to_site_logo( $value ) { diff --git a/src/wp-includes/blocks/site-title/block.json b/src/wp-includes/blocks/site-title/block.json index 0631de6560ba4..8bf5202643003 100644 --- a/src/wp-includes/blocks/site-title/block.json +++ b/src/wp-includes/blocks/site-title/block.json @@ -61,6 +61,7 @@ "__experimentalFontWeight": true, "__experimentalLetterSpacing": true, "__experimentalWritingMode": true, + "fitText": true, "__experimentalDefaultControls": { "fontSize": true } diff --git a/src/wp-includes/blocks/social-link.php b/src/wp-includes/blocks/social-link.php index 85a907c234e7a..60064f64a525c 100644 --- a/src/wp-includes/blocks/social-link.php +++ b/src/wp-includes/blocks/social-link.php @@ -349,7 +349,6 @@ function block_core_social_link_services( $service = '', $field = '' ) { * @since 6.9.0 * * @param array $services_data The list of services. Each item is an array containing a 'name' and 'icon' key. - * @return array The list of social services. */ $services_data = apply_filters( 'block_core_social_link_get_services', $services_data ); diff --git a/src/wp-includes/blocks/tab-list.php b/src/wp-includes/blocks/tab-list.php index eb587ef78fd2d..f45de5def38e9 100644 --- a/src/wp-includes/blocks/tab-list.php +++ b/src/wp-includes/blocks/tab-list.php @@ -9,14 +9,14 @@ * Render callback for core/tab-list. * * Injects IAPI directives into the saved button HTML. The buttons already - * carry color/border/padding styles from save.js; this callback adds + * carry color/border/padding styles from save.jsx; this callback adds * tab-specific attributes (id, aria-controls, context) and interactivity * directives using data from the tabs-list context. * * @since 7.1.0 * * @param array $attributes Block attributes. - * @param string $content Block content (rendered buttons from save.js). + * @param string $content Block content (rendered buttons from save.jsx). * @param \WP_Block $block WP_Block instance. * * @return string Updated HTML. diff --git a/src/wp-includes/blocks/tabs.php b/src/wp-includes/blocks/tabs.php index e7a3d63775886..a8d9dcc4b0327 100644 --- a/src/wp-includes/blocks/tabs.php +++ b/src/wp-includes/blocks/tabs.php @@ -104,7 +104,8 @@ function block_core_tabs_render_block_callback( array $attributes, string $conte ) ) ); - $tag_processor->set_attribute( 'data-wp-init', 'callbacks.onTabsInit' ); + $tag_processor->set_attribute( 'data-wp-init', 'callbacks.activateTabByHash' ); + $tag_processor->set_attribute( 'data-wp-on-window--hashchange', 'callbacks.activateTabByHash' ); $tag_processor->set_attribute( 'data-wp-on--keydown', 'actions.handleTabKeyDown' ); $output = $tag_processor->get_updated_html(); diff --git a/src/wp-includes/blocks/widget-group.php b/src/wp-includes/blocks/widget-group.php index e8769612a2f17..ac4474deef5ea 100644 --- a/src/wp-includes/blocks/widget-group.php +++ b/src/wp-includes/blocks/widget-group.php @@ -14,8 +14,8 @@ * @global int|string $_sidebar_being_rendered * * @param array $attributes The block attributes. - * @param string $content The block content. - * @param WP_Block $block The block. + * @param string $content The block content. + * @param WP_Block $block The block. * * @return string Rendered block. */ @@ -70,7 +70,7 @@ function register_block_core_widget_group() { * * @global int|string $_sidebar_being_rendered * - * @param int|string $index Index, name, or ID of the dynamic sidebar. + * @param int|string $index Index, name, or ID of the dynamic sidebar. */ function note_sidebar_being_rendered( $index ) { global $_sidebar_being_rendered; diff --git a/src/wp-includes/build/constants.php b/src/wp-includes/build/constants.php index c2a539ac31272..365f89d9e3ecf 100644 --- a/src/wp-includes/build/constants.php +++ b/src/wp-includes/build/constants.php @@ -9,6 +9,6 @@ */ return array( - 'version' => '23.9.0', + 'version' => '23.9.1', 'build_url' => includes_url( 'build/' ), ); diff --git a/src/wp-includes/build/pages/font-library/page-wp-admin.php b/src/wp-includes/build/pages/font-library/page-wp-admin.php index 98cb4028c9541..bc5625319a725 100644 --- a/src/wp-includes/build/pages/font-library/page-wp-admin.php +++ b/src/wp-includes/build/pages/font-library/page-wp-admin.php @@ -328,10 +328,14 @@ function wp_font_library_wp_admin_render_page() { ); ?>
-
+ +
-
+ +
*{pointer-events:auto}}}"); } -var style_default3 = { "button": "_97b0fc33c028be1a__button", "is-unstyled": "abbb272e2ce49bd6__is-unstyled", "is-loading": "_914b42f315c0e580__is-loading", "is-small": "_908205475f9f2a92__is-small", "icon": "_9f6fc6553aeb36fe__icon", "is-brand": "dd460c965226cc77__is-brand", "is-outline": "_62d5a778b7b258ee__is-outline", "is-minimal": "ad0619a3217c6a5b__is-minimal", "is-neutral": "e722a8f96726aa99__is-neutral", "is-solid": "b50b3358c5fb4d0b__is-solid", "is-compact": "cf59cf1b69629838__is-compact", "loading-animation": "_5a1d53da6f830c8d__loading-animation" }; -if (typeof process === "undefined" || true) { - registerStyle3("10f3806643", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}"); +var wp_compat_overlay_slot_default = { "slot": "_11fc52b637ff8a7e__slot" }; +var WP_COMPAT_OVERLAY_SLOT_ATTRIBUTE = "data-wp-compat-overlay-slot"; +function resolveOwnerDocument() { + return typeof document === "undefined" ? null : document; } -var resets_default = { "box-sizing": "_336cd3e4e743482f__box-sizing" }; -if (typeof process === "undefined" || true) { - registerStyle3("96553466c8", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._64de9947bf305b7a__outset-ring--focus-within-visible:focus-within:has(:focus-visible),.af79fb116edb0dd7__outset-ring--focus:focus,.dfcfdc28396e5d98__outset-ring--focus-visible:focus-visible,.e5cd9ee879f6403a__outset-ring--focus-within:focus-within,:focus-visible ._81935a08e952f267__outset-ring--focus-parent-visible{--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within,.abc777e9713fa711__outset-ring--focus-except-active:focus{outline:none}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within:not(:has(:active)),.abc777e9713fa711__outset-ring--focus-except-active:focus:not(:active){--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}}}"); +function isInWordPressEnvironment() { + let topWp; + try { + topWp = window.top?.wp; + } catch { + } + const wp = topWp ?? window.wp; + return typeof wp?.components === "object" && wp.components !== null; } -var focus_module_default = { "outset-ring--focus": "af79fb116edb0dd7__outset-ring--focus", "outset-ring--focus-visible": "dfcfdc28396e5d98__outset-ring--focus-visible", "outset-ring--focus-within": "e5cd9ee879f6403a__outset-ring--focus-within", "outset-ring--focus-within-visible": "_64de9947bf305b7a__outset-ring--focus-within-visible", "outset-ring--focus-parent-visible": "_81935a08e952f267__outset-ring--focus-parent-visible", "outset-ring--focus-except-active": "abc777e9713fa711__outset-ring--focus-except-active", "outset-ring--focus-within-except-active": "_3c9f5ee9fc9c136d__outset-ring--focus-within-except-active" }; -if (typeof process === "undefined" || true) { - registerStyle3("af6d9984a6", "._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}"); +var cachedSlot = null; +function ensureSlotIsAccessible(element) { + element.setAttribute("aria-hidden", "false"); + return element; } -var global_css_defense_default2 = { "button": "_6defc79820e382c6__button", "input": "d2cff2e5dea83bd1__input", "textarea": "_547d86373d02e108__textarea", "div": "_8c15fd0ed9f28ba4__div", "p": "_43cec3e1eec1066d__p", "heading": "e97669c6d9a38497__heading", "a": "_2c0831b0499dbd6e__a" }; -var Button3 = (0, import_element12.forwardRef)( - function Button22({ - tone = "brand", - variant = "solid", - size: size4 = "default", - className, - focusableWhenDisabled = true, - disabled: disabled2, - loading, - loadingAnnouncement = (0, import_i18n.__)("Loading"), - children, - ...props - }, ref) { - const mergedClassName = clsx_default( - global_css_defense_default2.button, - resets_default["box-sizing"], - focus_module_default["outset-ring--focus-except-active"], - variant !== "unstyled" && style_default3.button, - style_default3[`is-${tone}`], - style_default3[`is-${variant}`], - style_default3[`is-${size4}`], - loading && style_default3["is-loading"], - className - ); - (0, import_element12.useEffect)(() => { - if (loading && loadingAnnouncement) { - speak(loadingAnnouncement); - } - }, [loading, loadingAnnouncement]); +function createSlot(ownerDocument2) { + const element = ownerDocument2.createElement("div"); + element.setAttribute(WP_COMPAT_OVERLAY_SLOT_ATTRIBUTE, ""); + if (wp_compat_overlay_slot_default.slot) { + element.classList.add(wp_compat_overlay_slot_default.slot); + } + ownerDocument2.body.appendChild(element); + return element; +} +function getWpCompatOverlaySlot() { + if (typeof window === "undefined") { + return void 0; + } + if (!isInWordPressEnvironment() && window.__wpUiCompatOverlaySlotEnabled !== true) { + return void 0; + } + const ownerDocument2 = resolveOwnerDocument(); + if (!ownerDocument2 || !ownerDocument2.body) { + return void 0; + } + if (cachedSlot && cachedSlot.ownerDocument === ownerDocument2 && cachedSlot.isConnected) { + return ensureSlotIsAccessible(cachedSlot); + } + const existing = ownerDocument2.querySelector( + `[${WP_COMPAT_OVERLAY_SLOT_ATTRIBUTE}]` + ); + if (existing instanceof HTMLDivElement) { + cachedSlot = ensureSlotIsAccessible(existing); + return cachedSlot; + } + if (cachedSlot?.isConnected) { + cachedSlot.remove(); + } + cachedSlot = ensureSlotIsAccessible(createSlot(ownerDocument2)); + return cachedSlot; +} + +// packages/ui/build-module/tooltip/portal.mjs +var import_jsx_runtime13 = __toESM(require_jsx_runtime(), 1); +var Portal = (0, import_element12.forwardRef)( + function TooltipPortal3({ container, ...restProps }, ref) { return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)( - Button, + index_parts_exports.Portal, { - ref, - className: mergedClassName, - focusableWhenDisabled, - disabled: disabled2 ?? loading, - ...props, - children + container: container ?? getWpCompatOverlaySlot(), + ...restProps, + ref } ); } ); -// packages/ui/build-module/button/icon.mjs -var import_element14 = __toESM(require_element(), 1); - -// packages/ui/build-module/icon/icon.mjs +// packages/ui/build-module/tooltip/positioner.mjs var import_element13 = __toESM(require_element(), 1); -var import_primitives = __toESM(require_primitives(), 1); var import_jsx_runtime14 = __toESM(require_jsx_runtime(), 1); -var Icon = (0, import_element13.forwardRef)(function Icon2({ icon, size: size4 = 24, ...restProps }, ref) { - return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)( - import_primitives.SVG, - { - ref, - ...icon.props, - ...restProps, - width: size4, - height: size4 - } - ); -}); - -// packages/ui/build-module/button/icon.mjs -var import_jsx_runtime15 = __toESM(require_jsx_runtime(), 1); var STYLE_HASH_ATTRIBUTE4 = "data-wp-hash"; function getRuntime4() { const globalScope = globalThis; @@ -9129,69 +9127,68 @@ function registerStyle4(hash, css) { } } if (typeof process === "undefined" || true) { - registerStyle4("effc4e3032", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._97b0fc33c028be1a__button,.abbb272e2ce49bd6__is-unstyled{appearance:none;padding:0}._97b0fc33c028be1a__button{--wp-ui-button-font-weight:var(--wpds-typography-font-weight-emphasis,600);--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-strong,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-strong-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 93%,#000));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand-strong,#fff);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-strong-active,#fff);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-strong-disabled,#8d8d8d);--wp-ui-button-padding-block:var(--wpds-dimension-padding-xs,4px);--wp-ui-button-padding-inline:var(--wpds-dimension-padding-md,12px);--wp-ui-button-height:var(--wpds-dimension-size-lg,40px);--wp-ui-button-aspect-ratio:auto;--wp-ui-button-font-size:var(--wpds-typography-font-size-md,13px);--wp-ui-button-min-width:calc(4ch + var(--wp-ui-button-padding-inline)*2);--wp-ui-button-icon-margin:calc((var(--wpds-dimension-size-2xs, 16px) - var(--wpds-dimension-size-sm, 24px))/2);--wp-ui-button-border-color:var(--wp-ui-button-background-color);--wp-ui-button-border-color-active:var(--wp-ui-button-background-color-active);--wp-ui-button-border-color-disabled:var(--wp-ui-button-background-color-disabled);--_gcd-button-font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);--_gcd-button-font-size:var(--wp-ui-button-font-size);--_gcd-button-font-weight:var(--wp-ui-button-font-weight);align-items:center;aspect-ratio:var(--wp-ui-button-aspect-ratio);background-clip:border-box;background-color:var(--wp-ui-button-background-color);border-color:var(--wp-ui-button-border-color);border-radius:var(--wpds-border-radius-sm,2px);border-style:solid;border-width:1px;color:var(--wp-ui-button-foreground-color);display:inline-flex;font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wp-ui-button-font-size);font-weight:var(--wp-ui-button-font-weight);gap:var(--wpds-dimension-gap-sm,8px);justify-content:center;line-height:var(--wpds-typography-line-height-sm,20px);max-width:100%;min-height:var(--wp-ui-button-height);min-width:var(--wp-ui-button-min-width);overflow-wrap:anywhere;padding-block:var(--wp-ui-button-padding-block);padding-inline:var(--wp-ui-button-padding-inline);position:relative;text-align:center;text-decoration:none;&:not([data-disabled]){cursor:var(--wpds-cursor-control,pointer)}@media not (prefers-reduced-motion){transition:color .1s ease-out;*{transition:opacity .1s ease-out}}&[href]{cursor:pointer}[href]{color:inherit;text-decoration:inherit}&:not([data-disabled]):is(:hover,:active,:focus){background-color:var(--wp-ui-button-background-color-active);border-color:var(--wp-ui-button-border-color-active);color:var(--wp-ui-button-foreground-color-active)}&[data-disabled]:not(._914b42f315c0e580__is-loading){background-color:var(--wp-ui-button-background-color-disabled);border-color:var(--wp-ui-button-border-color-disabled);color:var(--wp-ui-button-foreground-color-disabled);@media (forced-colors:active){border-bottom-color:GrayText;border-left-color:GrayText;border-right-color:GrayText;border-top-color:GrayText;color:GrayText}}&:before{aspect-ratio:1;border:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid;border-block-end-color:transparent;border-block-start-color:var(--wp-ui-button-foreground-color);border-inline-end-color:var(--wp-ui-button-foreground-color);border-inline-start-color:transparent;border-radius:50%;box-sizing:border-box;content:"";display:block;height:var(--wp-ui-button-font-size);left:50%;opacity:0;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);@media not (prefers-reduced-motion){transition:opacity .1s ease-out}@media (forced-colors:active){border-block-end-style:none;border-bottom-color:ButtonText;border-inline-start-style:none;border-left-color:ButtonText;border-right-color:ButtonText;border-top-color:ButtonText}}}._908205475f9f2a92__is-small{--wp-ui-button-padding-block:0px;--wp-ui-button-padding-inline:var(--wpds-dimension-padding-sm,8px);--wp-ui-button-height:var(--wpds-dimension-size-sm,24px)}._9f6fc6553aeb36fe__icon{margin:var(--wp-ui-button-icon-margin)}.dd460c965226cc77__is-brand{&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 85%,#000));--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-brand-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000)}}.e722a8f96726aa99__is-neutral{&.ad0619a3217c6a5b__is-minimal[aria-pressed=true],&.b50b3358c5fb4d0b__is-solid{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-strong,#2d2d2d);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-strong-active,#1e1e1e);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral-strong,#f0f0f0);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-strong-active,#f0f0f0);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-strong-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d);--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-neutral-active,#6e6e6e);--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-neutral-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000)}}.abbb272e2ce49bd6__is-unstyled{background:none;border:none;min-width:unset}.cf59cf1b69629838__is-compact{--wp-ui-button-height:var(--wpds-dimension-size-md,32px)}._914b42f315c0e580__is-loading:not(.abbb272e2ce49bd6__is-unstyled){color:transparent;&:not([data-disabled]):is(:hover,:active,:focus){color:transparent}@media (forced-colors:active){color:ButtonFace}*{opacity:0}&:before{opacity:1;transition-delay:.05s;@media not (prefers-reduced-motion){animation:_5a1d53da6f830c8d__loading-animation 1s linear infinite}}}}@keyframes _5a1d53da6f830c8d__loading-animation{0%{transform:translate(-50%,-50%) rotate(0deg)}to{transform:translate(-50%,-50%) rotate(1turn)}}}'); + registerStyle4("10f3806643", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}"); } -var style_default4 = { "button": "_97b0fc33c028be1a__button", "is-unstyled": "abbb272e2ce49bd6__is-unstyled", "is-loading": "_914b42f315c0e580__is-loading", "is-small": "_908205475f9f2a92__is-small", "icon": "_9f6fc6553aeb36fe__icon", "is-brand": "dd460c965226cc77__is-brand", "is-outline": "_62d5a778b7b258ee__is-outline", "is-minimal": "ad0619a3217c6a5b__is-minimal", "is-neutral": "e722a8f96726aa99__is-neutral", "is-solid": "b50b3358c5fb4d0b__is-solid", "is-compact": "cf59cf1b69629838__is-compact", "loading-animation": "_5a1d53da6f830c8d__loading-animation" }; -var ButtonIcon = (0, import_element14.forwardRef)( - function ButtonIcon2({ className, icon, ...props }, ref) { - return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)( - Icon, +var resets_default = { "box-sizing": "_336cd3e4e743482f__box-sizing" }; +if (typeof process === "undefined" || true) { + registerStyle4("19fcc06039", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}'); +} +var style_default3 = { "positioner": "_480b748dd3510e64__positioner", "popup": "_50096b232db7709d__popup" }; +var Positioner = (0, import_element13.forwardRef)( + function TooltipPositioner3({ align = "center", className, side = "top", sideOffset = 4, ...props }, ref) { + return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)( + index_parts_exports.Positioner, { ref, - icon, - className: clsx_default(style_default4.icon, className), - size: 24, - ...props + align, + side, + sideOffset, + ...props, + className: clsx_default( + resets_default["box-sizing"], + style_default3.positioner, + className + ) } ); } ); -// packages/ui/build-module/button/index.mjs -ButtonIcon.displayName = "Button.Icon"; -var Button4 = Object.assign(Button3, { - /** - * An icon component specifically designed to work well when rendered inside - * a `Button` component. - */ - Icon: ButtonIcon -}); - -// packages/icons/build-module/library/caution.mjs -var import_primitives2 = __toESM(require_primitives(), 1); -var import_jsx_runtime16 = __toESM(require_jsx_runtime(), 1); -var caution_default = /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_primitives2.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_primitives2.Path, { fillRule: "evenodd", clipRule: "evenodd", d: "M5.5 12a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0ZM12 4a8 8 0 1 0 0 16 8 8 0 0 0 0-16Zm-.75 12v-1.5h1.5V16h-1.5Zm0-8v5h1.5V8h-1.5Z" }) }); - -// packages/icons/build-module/library/close-small.mjs -var import_primitives3 = __toESM(require_primitives(), 1); -var import_jsx_runtime17 = __toESM(require_jsx_runtime(), 1); -var close_small_default = /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_primitives3.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_primitives3.Path, { d: "M12 13.06l3.712 3.713 1.061-1.06L13.061 12l3.712-3.712-1.06-1.06L12 10.938 8.288 7.227l-1.061 1.06L10.939 12l-3.712 3.712 1.06 1.061L12 13.061z" }) }); - -// packages/icons/build-module/library/error.mjs -var import_primitives4 = __toESM(require_primitives(), 1); -var import_jsx_runtime18 = __toESM(require_jsx_runtime(), 1); -var error_default = /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_primitives4.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_primitives4.Path, { fillRule: "evenodd", clipRule: "evenodd", d: "M12.218 5.377a.25.25 0 0 0-.436 0l-7.29 12.96a.25.25 0 0 0 .218.373h14.58a.25.25 0 0 0 .218-.372l-7.29-12.96Zm-1.743-.735c.669-1.19 2.381-1.19 3.05 0l7.29 12.96a1.75 1.75 0 0 1-1.525 2.608H4.71a1.75 1.75 0 0 1-1.525-2.608l7.29-12.96ZM12.75 17.46h-1.5v-1.5h1.5v1.5Zm-1.5-3h1.5v-5h-1.5v5Z" }) }); +// packages/ui/build-module/utils/render-slot-with-children.mjs +var import_element14 = __toESM(require_element(), 1); +function renderSlotWithChildren(slot, defaultSlot, children) { + return (0, import_element14.cloneElement)(slot ?? defaultSlot, { children }); +} -// packages/icons/build-module/library/info.mjs -var import_primitives5 = __toESM(require_primitives(), 1); -var import_jsx_runtime19 = __toESM(require_jsx_runtime(), 1); -var info_default = /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_primitives5.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_primitives5.Path, { fillRule: "evenodd", clipRule: "evenodd", d: "M5.5 12a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0ZM12 4a8 8 0 1 0 0 16 8 8 0 0 0 0-16Zm.75 4v1.5h-1.5V8h1.5Zm0 8v-5h-1.5v5h1.5Z" }) }); +// packages/ui/build-module/utils/theme-provider.mjs +var theme = __toESM(require_theme(), 1); -// packages/icons/build-module/library/published.mjs -var import_primitives6 = __toESM(require_primitives(), 1); -var import_jsx_runtime20 = __toESM(require_jsx_runtime(), 1); -var published_default = /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_primitives6.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_primitives6.Path, { fillRule: "evenodd", clipRule: "evenodd", d: "M12 18.5a6.5 6.5 0 1 1 0-13 6.5 6.5 0 0 1 0 13ZM4 12a8 8 0 1 1 16 0 8 8 0 0 1-16 0Zm11.53-1.47-1.06-1.06L11 12.94l-1.47-1.47-1.06 1.06L11 15.06l4.53-4.53Z" }) }); +// packages/ui/build-module/lock-unlock.mjs +var import_private_apis = __toESM(require_private_apis(), 1); +var { lock, unlock } = (0, import_private_apis.__dangerousOptInToUnstableAPIsOnlyForCoreModules)( + "I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.", + "@wordpress/ui" +); -// packages/ui/build-module/icon-button/icon-button.mjs -var import_element22 = __toESM(require_element(), 1); +// packages/ui/build-module/utils/theme-provider.mjs +function getThemeProvider() { + const themePackage = theme; + if (themePackage.ThemeProvider) { + return themePackage.ThemeProvider; + } + if (!themePackage.privateApis) { + throw new Error( + "@wordpress/ui: @wordpress/theme must expose `ThemeProvider` or `privateApis.ThemeProvider`." + ); + } + return unlock( + themePackage.privateApis + ).ThemeProvider; +} +var ThemeProvider = getThemeProvider(); // packages/ui/build-module/tooltip/popup.mjs -var import_element18 = __toESM(require_element(), 1); - -// packages/ui/build-module/tooltip/portal.mjs -var import_element15 = __toESM(require_element(), 1); - -// packages/ui/build-module/utils/wp-compat-overlay-slot.mjs +var import_jsx_runtime15 = __toESM(require_jsx_runtime(), 1); var STYLE_HASH_ATTRIBUTE5 = "data-wp-hash"; function getRuntime5() { const globalScope = globalThis; @@ -9273,82 +9270,54 @@ function registerStyle5(hash, css) { } } if (typeof process === "undefined" || true) { - registerStyle5("be37f31c1e", "._11fc52b637ff8a7e__slot{inset:0;isolation:isolate;pointer-events:none;position:fixed;z-index:1000000003}@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._11fc52b637ff8a7e__slot>*{pointer-events:auto}}}"); -} -var wp_compat_overlay_slot_default = { "slot": "_11fc52b637ff8a7e__slot" }; -var WP_COMPAT_OVERLAY_SLOT_ATTRIBUTE = "data-wp-compat-overlay-slot"; -function resolveOwnerDocument() { - return typeof document === "undefined" ? null : document; + registerStyle5("19fcc06039", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}'); } -function isInWordPressEnvironment() { - let topWp; - try { - topWp = window.top?.wp; - } catch { +var style_default4 = { "positioner": "_480b748dd3510e64__positioner", "popup": "_50096b232db7709d__popup" }; +var POPUP_COLOR = { background: "#1e1e1e" }; +var Popup = (0, import_element15.forwardRef)(function TooltipPopup3({ portal, positioner, children, className, ...props }, ref) { + const popupContent = /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ThemeProvider, { color: POPUP_COLOR, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)( + index_parts_exports.Popup, + { + ref, + className: clsx_default(style_default4.popup, className), + ...props, + children + } + ) }); + const positionedPopup = renderSlotWithChildren( + positioner, + /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Positioner, {}), + popupContent + ); + return renderSlotWithChildren(portal, /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Portal, {}), positionedPopup); +}); + +// packages/ui/build-module/tooltip/trigger.mjs +var import_element16 = __toESM(require_element(), 1); +var import_jsx_runtime16 = __toESM(require_jsx_runtime(), 1); +var Trigger = (0, import_element16.forwardRef)( + function TooltipTrigger3(props, ref) { + return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(index_parts_exports.Trigger, { ref, ...props }); } - const wp = topWp ?? window.wp; - return typeof wp?.components === "object" && wp.components !== null; +); + +// packages/ui/build-module/utils/direction-provider.mjs +var import_i18n = __toESM(require_i18n(), 1); +var import_jsx_runtime17 = __toESM(require_jsx_runtime(), 1); +function DirectionProvider3({ children }) { + return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DirectionProvider, { direction: (0, import_i18n.isRTL)() ? "rtl" : "ltr", children }); } -var cachedSlot = null; -function ensureSlotIsAccessible(element) { - element.setAttribute("aria-hidden", "false"); - return element; + +// packages/ui/build-module/tooltip/root.mjs +var import_jsx_runtime18 = __toESM(require_jsx_runtime(), 1); +function Root(props) { + return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DirectionProvider3, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(index_parts_exports.Root, { ...props }) }); } -function createSlot(ownerDocument2) { - const element = ownerDocument2.createElement("div"); - element.setAttribute(WP_COMPAT_OVERLAY_SLOT_ATTRIBUTE, ""); - if (wp_compat_overlay_slot_default.slot) { - element.classList.add(wp_compat_overlay_slot_default.slot); - } - ownerDocument2.body.appendChild(element); - return element; -} -function getWpCompatOverlaySlot() { - if (typeof window === "undefined") { - return void 0; - } - if (!isInWordPressEnvironment() && window.__wpUiCompatOverlaySlotEnabled !== true) { - return void 0; - } - const ownerDocument2 = resolveOwnerDocument(); - if (!ownerDocument2 || !ownerDocument2.body) { - return void 0; - } - if (cachedSlot && cachedSlot.ownerDocument === ownerDocument2 && cachedSlot.isConnected) { - return ensureSlotIsAccessible(cachedSlot); - } - const existing = ownerDocument2.querySelector( - `[${WP_COMPAT_OVERLAY_SLOT_ATTRIBUTE}]` - ); - if (existing instanceof HTMLDivElement) { - cachedSlot = ensureSlotIsAccessible(existing); - return cachedSlot; - } - if (cachedSlot?.isConnected) { - cachedSlot.remove(); - } - cachedSlot = ensureSlotIsAccessible(createSlot(ownerDocument2)); - return cachedSlot; -} - -// packages/ui/build-module/tooltip/portal.mjs -var import_jsx_runtime21 = __toESM(require_jsx_runtime(), 1); -var Portal = (0, import_element15.forwardRef)( - function TooltipPortal3({ container, ...restProps }, ref) { - return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)( - index_parts_exports.Portal, - { - container: container ?? getWpCompatOverlaySlot(), - ...restProps, - ref - } - ); - } -); -// packages/ui/build-module/tooltip/positioner.mjs -var import_element16 = __toESM(require_element(), 1); -var import_jsx_runtime22 = __toESM(require_jsx_runtime(), 1); +// packages/ui/build-module/link/link.mjs +var import_element17 = __toESM(require_element(), 1); +var import_i18n2 = __toESM(require_i18n(), 1); +var import_jsx_runtime19 = __toESM(require_jsx_runtime(), 1); var STYLE_HASH_ATTRIBUTE6 = "data-wp-hash"; function getRuntime6() { const globalScope = globalThis; @@ -9434,64 +9403,115 @@ if (typeof process === "undefined" || true) { } var resets_default2 = { "box-sizing": "_336cd3e4e743482f__box-sizing" }; if (typeof process === "undefined" || true) { - registerStyle6("19fcc06039", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}'); + registerStyle6("08122b3d53", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{.af79fb116edb0dd7__outset-ring--focus:focus,.dfcfdc28396e5d98__outset-ring--focus-visible:focus-visible,.e5cd9ee879f6403a__outset-ring--focus-within:focus-within,:focus-visible ._81935a08e952f267__outset-ring--focus-parent-visible{--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within,.abc777e9713fa711__outset-ring--focus-except-active:focus{outline:none}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within:not(:has(:active)),.abc777e9713fa711__outset-ring--focus-except-active:focus:not(:active){--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}}}"); } -var style_default5 = { "positioner": "_480b748dd3510e64__positioner", "popup": "_50096b232db7709d__popup" }; -var Positioner = (0, import_element16.forwardRef)( - function TooltipPositioner3({ align = "center", className, side = "top", sideOffset = 4, ...props }, ref) { - return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)( - index_parts_exports.Positioner, - { - ref, - align, - side, - sideOffset, - ...props, - className: clsx_default( - resets_default2["box-sizing"], - style_default5.positioner, - className - ) - } - ); - } -); - -// packages/ui/build-module/utils/render-slot-with-children.mjs -var import_element17 = __toESM(require_element(), 1); -function renderSlotWithChildren(slot, defaultSlot, children) { - return (0, import_element17.cloneElement)(slot ?? defaultSlot, { children }); +var focus_module_default = { "outset-ring--focus": "af79fb116edb0dd7__outset-ring--focus", "outset-ring--focus-visible": "dfcfdc28396e5d98__outset-ring--focus-visible", "outset-ring--focus-within": "e5cd9ee879f6403a__outset-ring--focus-within", "outset-ring--focus-parent-visible": "_81935a08e952f267__outset-ring--focus-parent-visible", "outset-ring--focus-except-active": "abc777e9713fa711__outset-ring--focus-except-active", "outset-ring--focus-within-except-active": "_3c9f5ee9fc9c136d__outset-ring--focus-within-except-active" }; +if (typeof process === "undefined" || true) { + registerStyle6("e8e6a9be37", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.d4250949359b05ce__link{text-decoration-thickness:from-font;text-underline-offset:.2em}.c6055659b8e2cd2c__is-brand,.c6055659b8e2cd2c__is-brand:visited{--_gcd-a-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9))}.c6055659b8e2cd2c__is-brand:active,.c6055659b8e2cd2c__is-brand:hover{--_gcd-a-color:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));color:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000))}._92e0dfcaeee15b88__is-neutral,._92e0dfcaeee15b88__is-neutral:visited{--_gcd-a-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);text-decoration-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d)}._92e0dfcaeee15b88__is-neutral:active,._92e0dfcaeee15b88__is-neutral:hover{--_gcd-a-color:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);color:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e)}.cf122a9bf1035d42__is-unstyled{--_gcd-a-color:inherit;color:inherit;text-decoration:none}._0cb411afac4c86c7__link-icon{display:inline-block;font-weight:var(--wpds-typography-font-weight-default,400);line-height:1;margin-inline-start:var(--wpds-dimension-padding-xs,4px);text-decoration:none}._0cb411afac4c86c7__link-icon:after{content:"\\2197"}._0cb411afac4c86c7__link-icon:dir(rtl):after{content:"\\2196"}}}'); } +var style_default5 = { "link": "d4250949359b05ce__link", "is-brand": "c6055659b8e2cd2c__is-brand", "is-neutral": "_92e0dfcaeee15b88__is-neutral", "is-unstyled": "cf122a9bf1035d42__is-unstyled", "link-icon": "_0cb411afac4c86c7__link-icon" }; +if (typeof process === "undefined" || true) { + registerStyle6("e8e31009f5", "._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-weak,#707070))}&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}.c59a0ebebd71fa4a__ol{list-style:var(--_gcd-ol-list-style,none);margin:var(--_gcd-ol-margin,0);padding-block:var(--_gcd-ol-padding-block,0);padding-inline:var(--_gcd-ol-padding-inline,0)}._46b5cb0c8e24e8c9__li{margin:var(--_gcd-li-margin,0)}"); +} +var global_css_defense_default2 = { "button": "_6defc79820e382c6__button", "input": "d2cff2e5dea83bd1__input", "textarea": "_547d86373d02e108__textarea", "div": "_8c15fd0ed9f28ba4__div", "p": "_43cec3e1eec1066d__p", "heading": "e97669c6d9a38497__heading", "a": "_2c0831b0499dbd6e__a", "ol": "c59a0ebebd71fa4a__ol", "li": "_46b5cb0c8e24e8c9__li" }; +var Link = (0, import_element17.forwardRef)(function Link2({ + children, + variant = "default", + tone = "brand", + openInNewTab = false, + target, + render, + className, + ...props +}, ref) { + const shouldShowNewTabIndicator = openInNewTab || /^_blank$/i.test(target ?? ""); + const element = useRender({ + render, + defaultTagName: "a", + ref, + props: mergeProps(props, { + className: clsx_default( + global_css_defense_default2.a, + resets_default2["box-sizing"], + focus_module_default["outset-ring--focus-except-active"], + variant !== "unstyled" && style_default5.link, + variant !== "unstyled" && style_default5[`is-${tone}`], + variant === "unstyled" && style_default5["is-unstyled"], + className + ), + target: target ?? (openInNewTab ? "_blank" : void 0), + children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [ + children, + shouldShowNewTabIndicator && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)( + "span", + { + className: style_default5["link-icon"], + role: "img", + "aria-label": ( + /* translators: accessibility text appended to link text */ + (0, import_i18n2.__)("(opens in a new tab)") + ) + } + ) + ] }) + }) + }); + return element; +}); -// packages/ui/build-module/utils/theme-provider.mjs -var theme = __toESM(require_theme(), 1); +// packages/icons/build-module/library/caution.mjs +var import_primitives = __toESM(require_primitives(), 1); +var import_jsx_runtime20 = __toESM(require_jsx_runtime(), 1); +var caution_default = /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_primitives.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", style: { fill: "none" }, stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_primitives.Path, { d: "M12 8L12 13M12 14.5L12 16M4.75 12C4.75 7.99593 7.99594 4.75 12 4.75C16.0041 4.75 19.25 7.99594 19.25 12C19.25 16.0041 16.0041 19.25 12 19.25C7.99594 19.25 4.75 16.0041 4.75 12Z", strokeLinejoin: "round", vectorEffect: "non-scaling-stroke" }) }); -// packages/ui/build-module/lock-unlock.mjs -var import_private_apis = __toESM(require_private_apis(), 1); -var { lock, unlock } = (0, import_private_apis.__dangerousOptInToUnstableAPIsOnlyForCoreModules)( - "I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.", - "@wordpress/ui" -); +// packages/icons/build-module/library/close-small.mjs +var import_primitives2 = __toESM(require_primitives(), 1); +var import_jsx_runtime21 = __toESM(require_jsx_runtime(), 1); +var close_small_default = /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_primitives2.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", style: { fill: "none" }, stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_primitives2.Path, { d: "M7.75 16.25L16.25 7.75M16.25 16.25L7.75 7.75", vectorEffect: "non-scaling-stroke" }) }); -// packages/ui/build-module/utils/theme-provider.mjs -function getThemeProvider() { - const themePackage = theme; - if (themePackage.ThemeProvider) { - return themePackage.ThemeProvider; - } - if (!themePackage.privateApis) { - throw new Error( - "@wordpress/ui: @wordpress/theme must expose `ThemeProvider` or `privateApis.ThemeProvider`." - ); - } - return unlock( - themePackage.privateApis - ).ThemeProvider; -} -var ThemeProvider = getThemeProvider(); +// packages/icons/build-module/library/error.mjs +var import_primitives3 = __toESM(require_primitives(), 1); +var import_jsx_runtime22 = __toESM(require_jsx_runtime(), 1); +var error_default = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_primitives3.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_primitives3.Path, { fillRule: "evenodd", clipRule: "evenodd", d: "M12.218 5.377a.25.25 0 0 0-.436 0l-7.29 12.96a.25.25 0 0 0 .218.373h14.58a.25.25 0 0 0 .218-.372l-7.29-12.96Zm-1.743-.735c.669-1.19 2.381-1.19 3.05 0l7.29 12.96a1.75 1.75 0 0 1-1.525 2.608H4.71a1.75 1.75 0 0 1-1.525-2.608l7.29-12.96ZM12.75 17.46h-1.5v-1.5h1.5v1.5Zm-1.5-3h1.5v-5h-1.5v5Z" }) }); -// packages/ui/build-module/tooltip/popup.mjs +// packages/icons/build-module/library/info.mjs +var import_primitives4 = __toESM(require_primitives(), 1); var import_jsx_runtime23 = __toESM(require_jsx_runtime(), 1); +var info_default = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_primitives4.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", style: { fill: "none" }, stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_primitives4.Path, { d: "M12 16V11M12 9.5V8M19.25 12C19.25 16.0041 16.0041 19.25 12 19.25C7.99594 19.25 4.75 16.0041 4.75 12C4.75 7.99594 7.99594 4.75 12 4.75C16.0041 4.75 19.25 7.99594 19.25 12Z", strokeLinejoin: "round", vectorEffect: "non-scaling-stroke" }) }); + +// packages/icons/build-module/library/published.mjs +var import_primitives5 = __toESM(require_primitives(), 1); +var import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1); +var published_default = /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_primitives5.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", style: { fill: "none" }, stroke: "currentColor", strokeWidth: "1.5", children: [ + /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_primitives5.Path, { d: "M12 19.25C16.0041 19.25 19.25 16.0041 19.25 12C19.25 7.99594 16.0041 4.75 12 4.75C7.99594 4.75 4.75 7.99594 4.75 12C4.75 16.0041 7.99594 19.25 12 19.25Z", strokeLinejoin: "round", vectorEffect: "non-scaling-stroke" }), + /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_primitives5.Path, { d: "M9 12L11 14L15 10", vectorEffect: "non-scaling-stroke" }) +] }); + +// packages/ui/build-module/icon/icon.mjs +var import_element18 = __toESM(require_element(), 1); +var import_primitives6 = __toESM(require_primitives(), 1); +var import_jsx_runtime25 = __toESM(require_jsx_runtime(), 1); +var Icon = (0, import_element18.forwardRef)(function Icon2({ icon, size: size4 = 24, style, ...restProps }, ref) { + const mergedStyle = icon.props.style || style ? { ...icon.props.style, ...style } : void 0; + return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)( + import_primitives6.SVG, + { + ref, + ...icon.props, + ...restProps, + ...mergedStyle ? { style: mergedStyle } : {}, + width: size4, + height: size4 + } + ); +}); + +// packages/ui/build-module/utils/keyboard-shortcut.mjs +var import_element20 = __toESM(require_element(), 1); +var import_i18n3 = __toESM(require_i18n(), 1); + +// packages/ui/build-module/visually-hidden/visually-hidden.mjs +var import_element19 = __toESM(require_element(), 1); var STYLE_HASH_ATTRIBUTE7 = "data-wp-hash"; function getRuntime7() { const globalScope = globalThis; @@ -9573,56 +9593,69 @@ function registerStyle7(hash, css) { } } if (typeof process === "undefined" || true) { - registerStyle7("19fcc06039", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}'); + registerStyle7("fa606a57ae", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.f37b9e2e191ebd66__visually-hidden{word-wrap:normal;border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-break:normal}}}"); } -var style_default6 = { "positioner": "_480b748dd3510e64__positioner", "popup": "_50096b232db7709d__popup" }; -var POPUP_COLOR = { background: "#1e1e1e" }; -var Popup = (0, import_element18.forwardRef)(function TooltipPopup3({ portal, positioner, children, className, ...props }, ref) { - const popupContent = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ThemeProvider, { color: POPUP_COLOR, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)( - index_parts_exports.Popup, - { +var style_default6 = { "visually-hidden": "f37b9e2e191ebd66__visually-hidden" }; +var VisuallyHidden = (0, import_element19.forwardRef)( + function VisuallyHidden2({ render, ...restProps }, ref) { + const element = useRender({ + render, ref, - className: clsx_default(style_default6.popup, className), - ...props, - children - } - ) }); - const positionedPopup = renderSlotWithChildren( - positioner, - /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Positioner, {}), - popupContent - ); - return renderSlotWithChildren(portal, /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Portal, {}), positionedPopup); -}); - -// packages/ui/build-module/tooltip/trigger.mjs -var import_element19 = __toESM(require_element(), 1); -var import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1); -var Trigger = (0, import_element19.forwardRef)( - function TooltipTrigger3(props, ref) { - return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(index_parts_exports.Trigger, { ref, ...props }); + props: mergeProps( + { className: style_default6["visually-hidden"] }, + restProps, + { + // @ts-expect-error Arbitrary data-* attributes aren't indexable on the typed div props. Kept hardcoded so consumers can't change or remove it. + "data-visually-hidden": "" + } + ) + }); + return element; } ); -// packages/ui/build-module/utils/direction-provider.mjs -var import_i18n2 = __toESM(require_i18n(), 1); -var import_jsx_runtime25 = __toESM(require_jsx_runtime(), 1); -function DirectionProvider3({ children }) { - return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(DirectionProvider, { direction: (0, import_i18n2.isRTL)() ? "rtl" : "ltr", children }); -} - -// packages/ui/build-module/tooltip/root.mjs +// packages/ui/build-module/utils/keyboard-shortcut.mjs var import_jsx_runtime26 = __toESM(require_jsx_runtime(), 1); -function Root(props) { - return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DirectionProvider3, { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(index_parts_exports.Root, { ...props }) }); +function useKeyboardShortcutProps({ + "aria-describedby": ariaDescribedBy, + "aria-keyshortcuts": ariaKeyShortcuts, + shortcut +}) { + const generatedDescriptionId = (0, import_element20.useId)(); + const descriptionId = shortcut ? generatedDescriptionId : void 0; + const describedBy = [ariaDescribedBy, descriptionId].filter(Boolean).join(" "); + return { + descriptionId, + targetProps: { + "aria-describedby": describedBy || void 0, + "aria-keyshortcuts": shortcut?.ariaKeyShortcut ?? ariaKeyShortcuts + } + }; } +var KeyboardShortcutDescription = (0, import_element20.forwardRef)(function KeyboardShortcutDescription2({ descriptionId, shortcut }, ref) { + return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)( + VisuallyHidden, + { + id: descriptionId, + "aria-hidden": "true", + render: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { ref }), + children: (0, import_i18n3.sprintf)( + /* translators: %s: keyboard shortcut. */ + (0, import_i18n3.__)("Keyboard shortcut: %s"), + shortcut.label ?? shortcut.ariaKeyShortcut + ) + } + ); +}); +var KeyboardShortcutDisplay = (0, import_element20.forwardRef)(function KeyboardShortcutDisplay2({ className, shortcut }, ref) { + return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { ref, "aria-hidden": "true", className, dir: "ltr", children: shortcut.displayShortcut }); +}); -// packages/ui/build-module/utils/keyboard-shortcut.mjs +// packages/ui/build-module/button/button.mjs var import_element21 = __toESM(require_element(), 1); -var import_i18n3 = __toESM(require_i18n(), 1); - -// packages/ui/build-module/visually-hidden/visually-hidden.mjs -var import_element20 = __toESM(require_element(), 1); +var import_i18n4 = __toESM(require_i18n(), 1); +var import_jsx_runtime27 = __toESM(require_jsx_runtime(), 1); +import { speak } from "@wordpress/a11y"; var STYLE_HASH_ATTRIBUTE8 = "data-wp-hash"; function getRuntime8() { const globalScope = globalThis; @@ -9704,65 +9737,66 @@ function registerStyle8(hash, css) { } } if (typeof process === "undefined" || true) { - registerStyle8("fa606a57ae", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.f37b9e2e191ebd66__visually-hidden{word-wrap:normal;border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-break:normal}}}"); + registerStyle8("effc4e3032", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._97b0fc33c028be1a__button,.abbb272e2ce49bd6__is-unstyled{appearance:none;padding:0}._97b0fc33c028be1a__button{--wp-ui-button-font-weight:var(--wpds-typography-font-weight-emphasis,600);--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-strong,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-strong-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 93%,#000));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand-strong,#fff);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-strong-active,#fff);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-strong-disabled,#8d8d8d);--wp-ui-button-padding-block:var(--wpds-dimension-padding-xs,4px);--wp-ui-button-padding-inline:var(--wpds-dimension-padding-md,12px);--wp-ui-button-height:var(--wpds-dimension-size-lg,40px);--wp-ui-button-aspect-ratio:auto;--wp-ui-button-font-size:var(--wpds-typography-font-size-md,13px);--wp-ui-button-min-width:calc(4ch + var(--wp-ui-button-padding-inline)*2);--wp-ui-button-icon-margin:calc((var(--wpds-dimension-size-2xs, 16px) - var(--wpds-dimension-size-sm, 24px))/2);--wp-ui-button-border-color:var(--wp-ui-button-background-color);--wp-ui-button-border-color-active:var(--wp-ui-button-background-color-active);--wp-ui-button-border-color-disabled:var(--wp-ui-button-background-color-disabled);--_gcd-button-font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);--_gcd-button-font-size:var(--wp-ui-button-font-size);--_gcd-button-font-weight:var(--wp-ui-button-font-weight);align-items:center;aspect-ratio:var(--wp-ui-button-aspect-ratio);background-clip:border-box;background-color:var(--wp-ui-button-background-color);border-color:var(--wp-ui-button-border-color);border-radius:var(--wpds-border-radius-sm,2px);border-style:solid;border-width:1px;color:var(--wp-ui-button-foreground-color);display:inline-flex;font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wp-ui-button-font-size);font-weight:var(--wp-ui-button-font-weight);gap:var(--wpds-dimension-gap-sm,8px);justify-content:center;line-height:var(--wpds-typography-line-height-sm,20px);max-width:100%;min-height:var(--wp-ui-button-height);min-width:var(--wp-ui-button-min-width);overflow-wrap:anywhere;padding-block:var(--wp-ui-button-padding-block);padding-inline:var(--wp-ui-button-padding-inline);position:relative;text-align:center;text-decoration:none;&:not([data-disabled]){cursor:var(--wpds-cursor-control,pointer)}@media not (prefers-reduced-motion){transition:color .1s ease-out;*{transition:opacity .1s ease-out}}&[href]{cursor:pointer}[href]{color:inherit;text-decoration:inherit}&:not([data-disabled]):is(:hover,:active,:focus){background-color:var(--wp-ui-button-background-color-active);border-color:var(--wp-ui-button-border-color-active);color:var(--wp-ui-button-foreground-color-active)}&[data-disabled]:not(._914b42f315c0e580__is-loading){background-color:var(--wp-ui-button-background-color-disabled);border-color:var(--wp-ui-button-border-color-disabled);color:var(--wp-ui-button-foreground-color-disabled);@media (forced-colors:active){border-bottom-color:GrayText;border-left-color:GrayText;border-right-color:GrayText;border-top-color:GrayText;color:GrayText}}&:before{aspect-ratio:1;border:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid;border-block-end-color:transparent;border-block-start-color:var(--wp-ui-button-foreground-color);border-inline-end-color:var(--wp-ui-button-foreground-color);border-inline-start-color:transparent;border-radius:50%;box-sizing:border-box;content:"";display:block;height:var(--wp-ui-button-font-size);left:50%;opacity:0;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);@media not (prefers-reduced-motion){transition:opacity .1s ease-out}@media (forced-colors:active){border-block-end-style:none;border-bottom-color:ButtonText;border-inline-start-style:none;border-left-color:ButtonText;border-right-color:ButtonText;border-top-color:ButtonText}}}._908205475f9f2a92__is-small{--wp-ui-button-padding-block:0px;--wp-ui-button-padding-inline:var(--wpds-dimension-padding-sm,8px);--wp-ui-button-height:var(--wpds-dimension-size-sm,24px)}._9f6fc6553aeb36fe__icon{margin:var(--wp-ui-button-icon-margin)}.dd460c965226cc77__is-brand{&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 85%,#000));--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-brand-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000)}}.e722a8f96726aa99__is-neutral{&.ad0619a3217c6a5b__is-minimal[aria-pressed=true],&.b50b3358c5fb4d0b__is-solid{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-strong,#2d2d2d);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-strong-active,#1e1e1e);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral-strong,#f0f0f0);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-strong-active,#f0f0f0);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-strong-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d);--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-neutral-active,#6e6e6e);--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-neutral-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000)}}.abbb272e2ce49bd6__is-unstyled{background:none;border:none;min-width:unset}.cf59cf1b69629838__is-compact{--wp-ui-button-height:var(--wpds-dimension-size-md,32px)}._914b42f315c0e580__is-loading:not(.abbb272e2ce49bd6__is-unstyled){color:transparent;&:not([data-disabled]):is(:hover,:active,:focus){color:transparent}@media (forced-colors:active){color:ButtonFace}*{opacity:0}&:before{opacity:1;transition-delay:.05s;@media not (prefers-reduced-motion){animation:_5a1d53da6f830c8d__loading-animation 1s linear infinite}}}}@keyframes _5a1d53da6f830c8d__loading-animation{0%{transform:translate(-50%,-50%) rotate(0deg)}to{transform:translate(-50%,-50%) rotate(1turn)}}}'); } -var style_default7 = { "visually-hidden": "f37b9e2e191ebd66__visually-hidden" }; -var VisuallyHidden = (0, import_element20.forwardRef)( - function VisuallyHidden2({ render, ...restProps }, ref) { - const element = useRender({ - render, - ref, - props: mergeProps( - { className: style_default7["visually-hidden"] }, - restProps, - { - // @ts-expect-error Arbitrary data-* attributes aren't indexable on the typed div props. Kept hardcoded so consumers can't change or remove it. - "data-visually-hidden": "" - } - ) - }); - return element; +var style_default7 = { "button": "_97b0fc33c028be1a__button", "is-unstyled": "abbb272e2ce49bd6__is-unstyled", "is-loading": "_914b42f315c0e580__is-loading", "is-small": "_908205475f9f2a92__is-small", "icon": "_9f6fc6553aeb36fe__icon", "is-brand": "dd460c965226cc77__is-brand", "is-outline": "_62d5a778b7b258ee__is-outline", "is-minimal": "ad0619a3217c6a5b__is-minimal", "is-neutral": "e722a8f96726aa99__is-neutral", "is-solid": "b50b3358c5fb4d0b__is-solid", "is-compact": "cf59cf1b69629838__is-compact", "loading-animation": "_5a1d53da6f830c8d__loading-animation" }; +if (typeof process === "undefined" || true) { + registerStyle8("10f3806643", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}"); +} +var resets_default3 = { "box-sizing": "_336cd3e4e743482f__box-sizing" }; +if (typeof process === "undefined" || true) { + registerStyle8("08122b3d53", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{.af79fb116edb0dd7__outset-ring--focus:focus,.dfcfdc28396e5d98__outset-ring--focus-visible:focus-visible,.e5cd9ee879f6403a__outset-ring--focus-within:focus-within,:focus-visible ._81935a08e952f267__outset-ring--focus-parent-visible{--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within,.abc777e9713fa711__outset-ring--focus-except-active:focus{outline:none}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within:not(:has(:active)),.abc777e9713fa711__outset-ring--focus-except-active:focus:not(:active){--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}}}"); +} +var focus_module_default2 = { "outset-ring--focus": "af79fb116edb0dd7__outset-ring--focus", "outset-ring--focus-visible": "dfcfdc28396e5d98__outset-ring--focus-visible", "outset-ring--focus-within": "e5cd9ee879f6403a__outset-ring--focus-within", "outset-ring--focus-parent-visible": "_81935a08e952f267__outset-ring--focus-parent-visible", "outset-ring--focus-except-active": "abc777e9713fa711__outset-ring--focus-except-active", "outset-ring--focus-within-except-active": "_3c9f5ee9fc9c136d__outset-ring--focus-within-except-active" }; +if (typeof process === "undefined" || true) { + registerStyle8("e8e31009f5", "._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-weak,#707070))}&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}.c59a0ebebd71fa4a__ol{list-style:var(--_gcd-ol-list-style,none);margin:var(--_gcd-ol-margin,0);padding-block:var(--_gcd-ol-padding-block,0);padding-inline:var(--_gcd-ol-padding-inline,0)}._46b5cb0c8e24e8c9__li{margin:var(--_gcd-li-margin,0)}"); +} +var global_css_defense_default3 = { "button": "_6defc79820e382c6__button", "input": "d2cff2e5dea83bd1__input", "textarea": "_547d86373d02e108__textarea", "div": "_8c15fd0ed9f28ba4__div", "p": "_43cec3e1eec1066d__p", "heading": "e97669c6d9a38497__heading", "a": "_2c0831b0499dbd6e__a", "ol": "c59a0ebebd71fa4a__ol", "li": "_46b5cb0c8e24e8c9__li" }; +var Button3 = (0, import_element21.forwardRef)( + function Button22({ + tone = "brand", + variant = "solid", + size: size4 = "default", + className, + focusableWhenDisabled = true, + disabled: disabled2, + loading, + loadingAnnouncement = (0, import_i18n4.__)("Loading"), + children, + ...props + }, ref) { + const mergedClassName = clsx_default( + global_css_defense_default3.button, + resets_default3["box-sizing"], + focus_module_default2["outset-ring--focus-except-active"], + variant !== "unstyled" && style_default7.button, + style_default7[`is-${tone}`], + style_default7[`is-${variant}`], + style_default7[`is-${size4}`], + loading && style_default7["is-loading"], + className + ); + (0, import_element21.useEffect)(() => { + if (loading && loadingAnnouncement) { + speak(loadingAnnouncement); + } + }, [loading, loadingAnnouncement]); + return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)( + Button, + { + ref, + className: mergedClassName, + focusableWhenDisabled, + disabled: disabled2 ?? loading, + ...props, + children + } + ); } ); -// packages/ui/build-module/utils/keyboard-shortcut.mjs -var import_jsx_runtime27 = __toESM(require_jsx_runtime(), 1); -function useKeyboardShortcutProps({ - "aria-describedby": ariaDescribedBy, - "aria-keyshortcuts": ariaKeyShortcuts, - shortcut -}) { - const generatedDescriptionId = (0, import_element21.useId)(); - const descriptionId = shortcut ? generatedDescriptionId : void 0; - const describedBy = [ariaDescribedBy, descriptionId].filter(Boolean).join(" "); - return { - descriptionId, - targetProps: { - "aria-describedby": describedBy || void 0, - "aria-keyshortcuts": shortcut?.ariaKeyShortcut ?? ariaKeyShortcuts - } - }; -} -var KeyboardShortcutDescription = (0, import_element21.forwardRef)(function KeyboardShortcutDescription2({ descriptionId, shortcut }, ref) { - return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)( - VisuallyHidden, - { - id: descriptionId, - "aria-hidden": "true", - render: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { ref }), - children: (0, import_i18n3.sprintf)( - /* translators: %s: keyboard shortcut. */ - (0, import_i18n3.__)("Keyboard shortcut: %s"), - shortcut.label ?? shortcut.ariaKeyShortcut - ) - } - ); -}); -var KeyboardShortcutDisplay = (0, import_element21.forwardRef)(function KeyboardShortcutDisplay2({ className, shortcut }, ref) { - return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { ref, "aria-hidden": "true", className, dir: "ltr", children: shortcut.displayShortcut }); -}); - -// packages/ui/build-module/icon-button/icon-button.mjs +// packages/ui/build-module/button/icon.mjs +var import_element22 = __toESM(require_element(), 1); var import_jsx_runtime28 = __toESM(require_jsx_runtime(), 1); var STYLE_HASH_ATTRIBUTE9 = "data-wp-hash"; function getRuntime9() { @@ -9845,74 +9879,37 @@ function registerStyle9(hash, css) { } } if (typeof process === "undefined" || true) { - registerStyle9("c5cdafb1bc", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer compositions{._28cfdc260e755391__icon-button{--wp-ui-button-aspect-ratio:1;--wp-ui-button-padding-inline:0px;--wp-ui-button-min-width:unset}.f1c70d719989a85a__icon{margin:-1px}}}"); + registerStyle9("effc4e3032", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._97b0fc33c028be1a__button,.abbb272e2ce49bd6__is-unstyled{appearance:none;padding:0}._97b0fc33c028be1a__button{--wp-ui-button-font-weight:var(--wpds-typography-font-weight-emphasis,600);--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-strong,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-strong-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 93%,#000));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand-strong,#fff);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-strong-active,#fff);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-strong-disabled,#8d8d8d);--wp-ui-button-padding-block:var(--wpds-dimension-padding-xs,4px);--wp-ui-button-padding-inline:var(--wpds-dimension-padding-md,12px);--wp-ui-button-height:var(--wpds-dimension-size-lg,40px);--wp-ui-button-aspect-ratio:auto;--wp-ui-button-font-size:var(--wpds-typography-font-size-md,13px);--wp-ui-button-min-width:calc(4ch + var(--wp-ui-button-padding-inline)*2);--wp-ui-button-icon-margin:calc((var(--wpds-dimension-size-2xs, 16px) - var(--wpds-dimension-size-sm, 24px))/2);--wp-ui-button-border-color:var(--wp-ui-button-background-color);--wp-ui-button-border-color-active:var(--wp-ui-button-background-color-active);--wp-ui-button-border-color-disabled:var(--wp-ui-button-background-color-disabled);--_gcd-button-font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);--_gcd-button-font-size:var(--wp-ui-button-font-size);--_gcd-button-font-weight:var(--wp-ui-button-font-weight);align-items:center;aspect-ratio:var(--wp-ui-button-aspect-ratio);background-clip:border-box;background-color:var(--wp-ui-button-background-color);border-color:var(--wp-ui-button-border-color);border-radius:var(--wpds-border-radius-sm,2px);border-style:solid;border-width:1px;color:var(--wp-ui-button-foreground-color);display:inline-flex;font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wp-ui-button-font-size);font-weight:var(--wp-ui-button-font-weight);gap:var(--wpds-dimension-gap-sm,8px);justify-content:center;line-height:var(--wpds-typography-line-height-sm,20px);max-width:100%;min-height:var(--wp-ui-button-height);min-width:var(--wp-ui-button-min-width);overflow-wrap:anywhere;padding-block:var(--wp-ui-button-padding-block);padding-inline:var(--wp-ui-button-padding-inline);position:relative;text-align:center;text-decoration:none;&:not([data-disabled]){cursor:var(--wpds-cursor-control,pointer)}@media not (prefers-reduced-motion){transition:color .1s ease-out;*{transition:opacity .1s ease-out}}&[href]{cursor:pointer}[href]{color:inherit;text-decoration:inherit}&:not([data-disabled]):is(:hover,:active,:focus){background-color:var(--wp-ui-button-background-color-active);border-color:var(--wp-ui-button-border-color-active);color:var(--wp-ui-button-foreground-color-active)}&[data-disabled]:not(._914b42f315c0e580__is-loading){background-color:var(--wp-ui-button-background-color-disabled);border-color:var(--wp-ui-button-border-color-disabled);color:var(--wp-ui-button-foreground-color-disabled);@media (forced-colors:active){border-bottom-color:GrayText;border-left-color:GrayText;border-right-color:GrayText;border-top-color:GrayText;color:GrayText}}&:before{aspect-ratio:1;border:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid;border-block-end-color:transparent;border-block-start-color:var(--wp-ui-button-foreground-color);border-inline-end-color:var(--wp-ui-button-foreground-color);border-inline-start-color:transparent;border-radius:50%;box-sizing:border-box;content:"";display:block;height:var(--wp-ui-button-font-size);left:50%;opacity:0;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);@media not (prefers-reduced-motion){transition:opacity .1s ease-out}@media (forced-colors:active){border-block-end-style:none;border-bottom-color:ButtonText;border-inline-start-style:none;border-left-color:ButtonText;border-right-color:ButtonText;border-top-color:ButtonText}}}._908205475f9f2a92__is-small{--wp-ui-button-padding-block:0px;--wp-ui-button-padding-inline:var(--wpds-dimension-padding-sm,8px);--wp-ui-button-height:var(--wpds-dimension-size-sm,24px)}._9f6fc6553aeb36fe__icon{margin:var(--wp-ui-button-icon-margin)}.dd460c965226cc77__is-brand{&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 85%,#000));--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-brand-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000)}}.e722a8f96726aa99__is-neutral{&.ad0619a3217c6a5b__is-minimal[aria-pressed=true],&.b50b3358c5fb4d0b__is-solid{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-strong,#2d2d2d);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-strong-active,#1e1e1e);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral-strong,#f0f0f0);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-strong-active,#f0f0f0);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-strong-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d);--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-neutral-active,#6e6e6e);--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-neutral-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000)}}.abbb272e2ce49bd6__is-unstyled{background:none;border:none;min-width:unset}.cf59cf1b69629838__is-compact{--wp-ui-button-height:var(--wpds-dimension-size-md,32px)}._914b42f315c0e580__is-loading:not(.abbb272e2ce49bd6__is-unstyled){color:transparent;&:not([data-disabled]):is(:hover,:active,:focus){color:transparent}@media (forced-colors:active){color:ButtonFace}*{opacity:0}&:before{opacity:1;transition-delay:.05s;@media not (prefers-reduced-motion){animation:_5a1d53da6f830c8d__loading-animation 1s linear infinite}}}}@keyframes _5a1d53da6f830c8d__loading-animation{0%{transform:translate(-50%,-50%) rotate(0deg)}to{transform:translate(-50%,-50%) rotate(1turn)}}}'); } -var style_default8 = { "icon-button": "_28cfdc260e755391__icon-button", "icon": "f1c70d719989a85a__icon" }; -var IconButton = (0, import_element22.forwardRef)( - function IconButton2({ - label, - className, - // Prevent accidental forwarding of `children` - children: _children, - disabled: disabled2, - focusableWhenDisabled = true, - icon, - size: size4, - shortcut, - positioner, - "aria-describedby": ariaDescribedBy, - "aria-keyshortcuts": ariaKeyShortcuts, - ...restProps - }, ref) { - const classes = clsx_default(style_default8["icon-button"], className); - const { descriptionId, targetProps } = useKeyboardShortcutProps({ - "aria-describedby": ariaDescribedBy, - "aria-keyshortcuts": ariaKeyShortcuts, - shortcut - }); - return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(Root, { children: [ - /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)( - Trigger, - { - ref, - ...targetProps, - disabled: disabled2 && !focusableWhenDisabled, - render: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)( - Button4, - { - ...restProps, - size: size4, - "aria-label": label, - disabled: disabled2, - focusableWhenDisabled - } - ), - className: classes, - children: [ - /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Icon, { icon, size: 24, className: style_default8.icon }), - shortcut && descriptionId && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)( - KeyboardShortcutDescription, - { - descriptionId, - shortcut - } - ) - ] - } - ), - /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(Popup, { positioner, children: [ - label, - shortcut && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [ - " ", - /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(KeyboardShortcutDisplay, { shortcut }) - ] }) - ] }) - ] }); +var style_default8 = { "button": "_97b0fc33c028be1a__button", "is-unstyled": "abbb272e2ce49bd6__is-unstyled", "is-loading": "_914b42f315c0e580__is-loading", "is-small": "_908205475f9f2a92__is-small", "icon": "_9f6fc6553aeb36fe__icon", "is-brand": "dd460c965226cc77__is-brand", "is-outline": "_62d5a778b7b258ee__is-outline", "is-minimal": "ad0619a3217c6a5b__is-minimal", "is-neutral": "e722a8f96726aa99__is-neutral", "is-solid": "b50b3358c5fb4d0b__is-solid", "is-compact": "cf59cf1b69629838__is-compact", "loading-animation": "_5a1d53da6f830c8d__loading-animation" }; +var ButtonIcon = (0, import_element22.forwardRef)( + function ButtonIcon2({ className, icon, ...props }, ref) { + return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)( + Icon, + { + ref, + icon, + className: clsx_default(style_default8.icon, className), + size: 24, + ...props + } + ); } ); -// packages/ui/build-module/stack/stack.mjs +// packages/ui/build-module/button/index.mjs +ButtonIcon.displayName = "Button.Icon"; +var Button4 = Object.assign(Button3, { + /** + * An icon component specifically designed to work well when rendered inside + * a `Button` component. + */ + Icon: ButtonIcon +}); + +// packages/ui/build-module/icon-button/icon-button.mjs var import_element23 = __toESM(require_element(), 1); +var import_jsx_runtime29 = __toESM(require_jsx_runtime(), 1); var STYLE_HASH_ATTRIBUTE10 = "data-wp-hash"; function getRuntime10() { const globalScope = globalThis; @@ -9994,38 +9991,74 @@ function registerStyle10(hash, css) { } } if (typeof process === "undefined" || true) { - registerStyle10("32aba35fe1", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._19ce0419607e1896__stack{display:flex}}}"); + registerStyle10("c5cdafb1bc", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer compositions{._28cfdc260e755391__icon-button{--wp-ui-button-aspect-ratio:1;--wp-ui-button-padding-inline:0px;--wp-ui-button-min-width:unset}.f1c70d719989a85a__icon{margin:-1px}}}"); } -var style_default9 = { "stack": "_19ce0419607e1896__stack" }; -var gapTokens = { - xs: "var(--wpds-dimension-gap-xs, 4px)", - sm: "var(--wpds-dimension-gap-sm, 8px)", - md: "var(--wpds-dimension-gap-md, 12px)", - lg: "var(--wpds-dimension-gap-lg, 16px)", - xl: "var(--wpds-dimension-gap-xl, 24px)", - "2xl": "var(--wpds-dimension-gap-2xl, 32px)", - "3xl": "var(--wpds-dimension-gap-3xl, 40px)" -}; -var Stack = (0, import_element23.forwardRef)(function Stack2({ direction, gap, align, justify, wrap, render, ...props }, ref) { - const style = { - gap: gap && gapTokens[gap], - alignItems: align, - justifyContent: justify, - flexDirection: direction, - flexWrap: wrap - }; - const element = useRender({ - render, - ref, - props: mergeProps(props, { style, className: style_default9.stack }) - }); - return element; -}); +var style_default9 = { "icon-button": "_28cfdc260e755391__icon-button", "icon": "f1c70d719989a85a__icon" }; +var IconButton = (0, import_element23.forwardRef)( + function IconButton2({ + label, + className, + // Prevent accidental forwarding of `children` + children: _children, + disabled: disabled2, + focusableWhenDisabled = true, + icon, + size: size4, + shortcut, + positioner, + "aria-describedby": ariaDescribedBy, + "aria-keyshortcuts": ariaKeyShortcuts, + ...restProps + }, ref) { + const classes = clsx_default(style_default9["icon-button"], className); + const { descriptionId, targetProps } = useKeyboardShortcutProps({ + "aria-describedby": ariaDescribedBy, + "aria-keyshortcuts": ariaKeyShortcuts, + shortcut + }); + return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(Root, { children: [ + /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)( + Trigger, + { + ref, + ...targetProps, + disabled: disabled2 && !focusableWhenDisabled, + render: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)( + Button4, + { + ...restProps, + size: size4, + "aria-label": label, + disabled: disabled2, + focusableWhenDisabled + } + ), + className: classes, + children: [ + /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Icon, { icon, size: 24, className: style_default9.icon }), + shortcut && descriptionId && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)( + KeyboardShortcutDescription, + { + descriptionId, + shortcut + } + ) + ] + } + ), + /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(Popup, { positioner, children: [ + label, + shortcut && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [ + " ", + /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(KeyboardShortcutDisplay, { shortcut }) + ] }) + ] }) + ] }); + } +); -// packages/ui/build-module/link/link.mjs +// packages/ui/build-module/stack/stack.mjs var import_element24 = __toESM(require_element(), 1); -var import_i18n4 = __toESM(require_i18n(), 1); -var import_jsx_runtime29 = __toESM(require_jsx_runtime(), 1); var STYLE_HASH_ATTRIBUTE11 = "data-wp-hash"; function getRuntime11() { const globalScope = globalThis; @@ -10107,60 +10140,30 @@ function registerStyle11(hash, css) { } } if (typeof process === "undefined" || true) { - registerStyle11("10f3806643", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}"); -} -var resets_default3 = { "box-sizing": "_336cd3e4e743482f__box-sizing" }; -if (typeof process === "undefined" || true) { - registerStyle11("96553466c8", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._64de9947bf305b7a__outset-ring--focus-within-visible:focus-within:has(:focus-visible),.af79fb116edb0dd7__outset-ring--focus:focus,.dfcfdc28396e5d98__outset-ring--focus-visible:focus-visible,.e5cd9ee879f6403a__outset-ring--focus-within:focus-within,:focus-visible ._81935a08e952f267__outset-ring--focus-parent-visible{--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within,.abc777e9713fa711__outset-ring--focus-except-active:focus{outline:none}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within:not(:has(:active)),.abc777e9713fa711__outset-ring--focus-except-active:focus:not(:active){--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}}}"); -} -var focus_module_default2 = { "outset-ring--focus": "af79fb116edb0dd7__outset-ring--focus", "outset-ring--focus-visible": "dfcfdc28396e5d98__outset-ring--focus-visible", "outset-ring--focus-within": "e5cd9ee879f6403a__outset-ring--focus-within", "outset-ring--focus-within-visible": "_64de9947bf305b7a__outset-ring--focus-within-visible", "outset-ring--focus-parent-visible": "_81935a08e952f267__outset-ring--focus-parent-visible", "outset-ring--focus-except-active": "abc777e9713fa711__outset-ring--focus-except-active", "outset-ring--focus-within-except-active": "_3c9f5ee9fc9c136d__outset-ring--focus-within-except-active" }; -if (typeof process === "undefined" || true) { - registerStyle11("e8e6a9be37", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.d4250949359b05ce__link{text-decoration-thickness:from-font;text-underline-offset:.2em}.c6055659b8e2cd2c__is-brand,.c6055659b8e2cd2c__is-brand:visited{--_gcd-a-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9))}.c6055659b8e2cd2c__is-brand:active,.c6055659b8e2cd2c__is-brand:hover{--_gcd-a-color:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));color:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000))}._92e0dfcaeee15b88__is-neutral,._92e0dfcaeee15b88__is-neutral:visited{--_gcd-a-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);text-decoration-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d)}._92e0dfcaeee15b88__is-neutral:active,._92e0dfcaeee15b88__is-neutral:hover{--_gcd-a-color:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);color:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e)}.cf122a9bf1035d42__is-unstyled{--_gcd-a-color:inherit;color:inherit;text-decoration:none}._0cb411afac4c86c7__link-icon{display:inline-block;font-weight:var(--wpds-typography-font-weight-default,400);line-height:1;margin-inline-start:var(--wpds-dimension-padding-xs,4px);text-decoration:none}._0cb411afac4c86c7__link-icon:after{content:"\\2197"}._0cb411afac4c86c7__link-icon:dir(rtl):after{content:"\\2196"}}}'); -} -var style_default10 = { "link": "d4250949359b05ce__link", "is-brand": "c6055659b8e2cd2c__is-brand", "is-neutral": "_92e0dfcaeee15b88__is-neutral", "is-unstyled": "cf122a9bf1035d42__is-unstyled", "link-icon": "_0cb411afac4c86c7__link-icon" }; -if (typeof process === "undefined" || true) { - registerStyle11("af6d9984a6", "._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}"); + registerStyle11("32aba35fe1", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._19ce0419607e1896__stack{display:flex}}}"); } -var global_css_defense_default3 = { "button": "_6defc79820e382c6__button", "input": "d2cff2e5dea83bd1__input", "textarea": "_547d86373d02e108__textarea", "div": "_8c15fd0ed9f28ba4__div", "p": "_43cec3e1eec1066d__p", "heading": "e97669c6d9a38497__heading", "a": "_2c0831b0499dbd6e__a" }; -var Link = (0, import_element24.forwardRef)(function Link2({ - children, - variant = "default", - tone = "brand", - openInNewTab = false, - render, - className, - ...props -}, ref) { +var style_default10 = { "stack": "_19ce0419607e1896__stack" }; +var gapTokens = { + xs: "var(--wpds-dimension-gap-xs, 4px)", + sm: "var(--wpds-dimension-gap-sm, 8px)", + md: "var(--wpds-dimension-gap-md, 12px)", + lg: "var(--wpds-dimension-gap-lg, 16px)", + xl: "var(--wpds-dimension-gap-xl, 24px)", + "2xl": "var(--wpds-dimension-gap-2xl, 32px)", + "3xl": "var(--wpds-dimension-gap-3xl, 40px)" +}; +var Stack = (0, import_element24.forwardRef)(function Stack2({ direction, gap, align, justify, wrap, render, ...props }, ref) { + const style = { + gap: gap && gapTokens[gap], + alignItems: align, + justifyContent: justify, + flexDirection: direction, + flexWrap: wrap + }; const element = useRender({ render, - defaultTagName: "a", ref, - props: mergeProps(props, { - className: clsx_default( - global_css_defense_default3.a, - resets_default3["box-sizing"], - focus_module_default2["outset-ring--focus-except-active"], - variant !== "unstyled" && style_default10.link, - variant !== "unstyled" && style_default10[`is-${tone}`], - variant === "unstyled" && style_default10["is-unstyled"], - className - ), - target: openInNewTab ? "_blank" : void 0, - children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [ - children, - openInNewTab && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)( - "span", - { - className: style_default10["link-icon"], - role: "img", - "aria-label": ( - /* translators: accessibility text appended to link text */ - (0, import_i18n4.__)("(opens in a new tab)") - ) - } - ) - ] }) - }) + props: mergeProps(props, { style, className: style_default10.stack }) }); return element; }); @@ -10266,7 +10269,7 @@ if (typeof process === "undefined" || true) { } var resets_default4 = { "box-sizing": "_336cd3e4e743482f__box-sizing" }; if (typeof process === "undefined" || true) { - registerStyle12("726c480820", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}"); + registerStyle12("42aad93a67", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#aac6e5);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1be80);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#936400)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#92d19d);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#007f2f)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dfafa8);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}"); } var style_default11 = { "notice": "_4145abab73d17514__notice", "icon": "d0a25570cb528528__icon", "title": "b5397fb9d05389e3__title", "description": "_1904b570a89bb815__description", "actions": "_0a1270dcdd79c031__actions", "action-button": "_983740ab855c4e09__action-button", "action-link": "d329e7416d368d31__action-link", "close-icon": "_487e6a5c1375f7dc__close-icon", "is-info": "_531c140826094795__is-info", "is-warning": "ae2e1004697cce95__is-warning", "is-success": "_2e614a76af494837__is-success", "is-error": "af00331ae17a0065__is-error", "is-action-button-outline": "_8ddb8fb33fbf3d38__is-action-button-outline", "is-action-button-minimal": "_77bbde495a8a0af3__is-action-button-minimal" }; var icons = { @@ -10424,7 +10427,7 @@ function registerStyle13(hash, css) { } } if (typeof process === "undefined" || true) { - registerStyle13("726c480820", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}"); + registerStyle13("42aad93a67", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#aac6e5);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1be80);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#936400)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#92d19d);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#007f2f)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dfafa8);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}"); } var style_default12 = { "notice": "_4145abab73d17514__notice", "icon": "d0a25570cb528528__icon", "title": "b5397fb9d05389e3__title", "description": "_1904b570a89bb815__description", "actions": "_0a1270dcdd79c031__actions", "action-button": "_983740ab855c4e09__action-button", "action-link": "d329e7416d368d31__action-link", "close-icon": "_487e6a5c1375f7dc__close-icon", "is-info": "_531c140826094795__is-info", "is-warning": "ae2e1004697cce95__is-warning", "is-success": "_2e614a76af494837__is-success", "is-error": "af00331ae17a0065__is-error", "is-action-button-outline": "_8ddb8fb33fbf3d38__is-action-button-outline", "is-action-button-minimal": "_77bbde495a8a0af3__is-action-button-minimal" }; var Title = (0, import_element26.forwardRef)( @@ -10525,7 +10528,7 @@ function registerStyle14(hash, css) { } } if (typeof process === "undefined" || true) { - registerStyle14("726c480820", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}"); + registerStyle14("42aad93a67", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#aac6e5);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1be80);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#936400)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#92d19d);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#007f2f)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dfafa8);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}"); } var style_default13 = { "notice": "_4145abab73d17514__notice", "icon": "d0a25570cb528528__icon", "title": "b5397fb9d05389e3__title", "description": "_1904b570a89bb815__description", "actions": "_0a1270dcdd79c031__actions", "action-button": "_983740ab855c4e09__action-button", "action-link": "d329e7416d368d31__action-link", "close-icon": "_487e6a5c1375f7dc__close-icon", "is-info": "_531c140826094795__is-info", "is-warning": "ae2e1004697cce95__is-warning", "is-success": "_2e614a76af494837__is-success", "is-error": "af00331ae17a0065__is-error", "is-action-button-outline": "_8ddb8fb33fbf3d38__is-action-button-outline", "is-action-button-minimal": "_77bbde495a8a0af3__is-action-button-minimal" }; var Description = (0, import_element27.forwardRef)( @@ -10625,7 +10628,7 @@ function registerStyle15(hash, css) { } } if (typeof process === "undefined" || true) { - registerStyle15("726c480820", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}"); + registerStyle15("42aad93a67", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#aac6e5);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1be80);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#936400)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#92d19d);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#007f2f)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dfafa8);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}"); } var style_default14 = { "notice": "_4145abab73d17514__notice", "icon": "d0a25570cb528528__icon", "title": "b5397fb9d05389e3__title", "description": "_1904b570a89bb815__description", "actions": "_0a1270dcdd79c031__actions", "action-button": "_983740ab855c4e09__action-button", "action-link": "d329e7416d368d31__action-link", "close-icon": "_487e6a5c1375f7dc__close-icon", "is-info": "_531c140826094795__is-info", "is-warning": "ae2e1004697cce95__is-warning", "is-success": "_2e614a76af494837__is-success", "is-error": "af00331ae17a0065__is-error", "is-action-button-outline": "_8ddb8fb33fbf3d38__is-action-button-outline", "is-action-button-minimal": "_77bbde495a8a0af3__is-action-button-minimal" }; var Actions = (0, import_element28.forwardRef)( @@ -10730,7 +10733,7 @@ function registerStyle16(hash, css) { } } if (typeof process === "undefined" || true) { - registerStyle16("726c480820", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}"); + registerStyle16("42aad93a67", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#aac6e5);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1be80);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#936400)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#92d19d);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#007f2f)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dfafa8);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}"); } var style_default15 = { "notice": "_4145abab73d17514__notice", "icon": "d0a25570cb528528__icon", "title": "b5397fb9d05389e3__title", "description": "_1904b570a89bb815__description", "actions": "_0a1270dcdd79c031__actions", "action-button": "_983740ab855c4e09__action-button", "action-link": "d329e7416d368d31__action-link", "close-icon": "_487e6a5c1375f7dc__close-icon", "is-info": "_531c140826094795__is-info", "is-warning": "ae2e1004697cce95__is-warning", "is-success": "_2e614a76af494837__is-success", "is-error": "af00331ae17a0065__is-error", "is-action-button-outline": "_8ddb8fb33fbf3d38__is-action-button-outline", "is-action-button-minimal": "_77bbde495a8a0af3__is-action-button-minimal" }; var CloseIcon = (0, import_element29.forwardRef)( @@ -10835,7 +10838,7 @@ function registerStyle17(hash, css) { } } if (typeof process === "undefined" || true) { - registerStyle17("726c480820", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}"); + registerStyle17("42aad93a67", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#aac6e5);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1be80);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#936400)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#92d19d);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#007f2f)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dfafa8);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}"); } var style_default16 = { "notice": "_4145abab73d17514__notice", "icon": "d0a25570cb528528__icon", "title": "b5397fb9d05389e3__title", "description": "_1904b570a89bb815__description", "actions": "_0a1270dcdd79c031__actions", "action-button": "_983740ab855c4e09__action-button", "action-link": "d329e7416d368d31__action-link", "close-icon": "_487e6a5c1375f7dc__close-icon", "is-info": "_531c140826094795__is-info", "is-warning": "ae2e1004697cce95__is-warning", "is-success": "_2e614a76af494837__is-success", "is-error": "af00331ae17a0065__is-error", "is-action-button-outline": "_8ddb8fb33fbf3d38__is-action-button-outline", "is-action-button-minimal": "_77bbde495a8a0af3__is-action-button-minimal" }; var ActionButton = (0, import_element30.forwardRef)( @@ -10944,7 +10947,7 @@ function registerStyle18(hash, css) { } } if (typeof process === "undefined" || true) { - registerStyle18("726c480820", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}"); + registerStyle18("42aad93a67", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#aac6e5);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1be80);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#936400)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#92d19d);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#007f2f)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dfafa8);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}"); } var style_default17 = { "notice": "_4145abab73d17514__notice", "icon": "d0a25570cb528528__icon", "title": "b5397fb9d05389e3__title", "description": "_1904b570a89bb815__description", "actions": "_0a1270dcdd79c031__actions", "action-button": "_983740ab855c4e09__action-button", "action-link": "d329e7416d368d31__action-link", "close-icon": "_487e6a5c1375f7dc__close-icon", "is-info": "_531c140826094795__is-info", "is-warning": "ae2e1004697cce95__is-warning", "is-success": "_2e614a76af494837__is-success", "is-error": "af00331ae17a0065__is-error", "is-action-button-outline": "_8ddb8fb33fbf3d38__is-action-button-outline", "is-action-button-minimal": "_77bbde495a8a0af3__is-action-button-minimal" }; var ActionLink = (0, import_element31.forwardRef)( @@ -11476,10 +11479,10 @@ var { lock: lock2, unlock: unlock2 } = (0, import_private_apis2.__dangerousOptIn ); // routes/connectors-home/style.scss -if (typeof document !== "undefined" && true && !document.head.querySelector("style[data-wp-hash='09e9b056ea']")) { +if (typeof document !== "undefined" && true && !document.head.querySelector("style[data-wp-hash='3ac7d2cc0e']")) { const style = document.createElement("style"); - style.setAttribute("data-wp-hash", "09e9b056ea"); - style.appendChild(document.createTextNode(".connectors-page{box-sizing:border-box;margin:0 auto;max-width:680px;padding:24px;width:100%}.connectors-page .components-item{background:#fff;border:1px solid #ddd;border-radius:8px;overflow:hidden;padding:20px;scroll-margin-top:120px}.connectors-page .connector-settings__error{color:#cc1818}.connectors-page .connector-settings .components-text-control__input{font-family:monospace;scroll-margin-top:120px}.connectors-page__file-mods-notice{margin-bottom:16px}.connectors-page--empty{align-items:center;display:flex;flex-direction:column;flex-grow:1;gap:32px;justify-content:center;text-align:center}.connectors-page .ai-plugin-callout{background-color:#e7d4e4;background-image:radial-gradient(ellipse 70% 120% at 18% 115%,rgba(202,158,198,.75) 0,rgba(202,158,198,0) 60%),radial-gradient(ellipse 55% 110% at 92% -15%,rgba(208,175,217,.7) 0,rgba(208,175,217,0) 65%),radial-gradient(ellipse 40% 85% at 58% -10%,rgba(170,130,184,.45) 0,rgba(170,130,184,0) 70%);border-radius:8px;overflow:hidden;padding:24px;padding-inline-end:150px;position:relative}[dir=rtl] .connectors-page .ai-plugin-callout{background-image:radial-gradient(ellipse 70% 120% at 82% 115%,rgba(202,158,198,.75) 0,rgba(202,158,198,0) 60%),radial-gradient(ellipse 55% 110% at 8% -15%,rgba(208,175,217,.7) 0,rgba(208,175,217,0) 65%),radial-gradient(ellipse 40% 85% at 42% -10%,rgba(170,130,184,.45) 0,rgba(170,130,184,0) 70%)}.connectors-page .ai-plugin-callout__content{align-items:flex-start;display:flex;flex-direction:column;gap:12px;padding-top:2px}.connectors-page .ai-plugin-callout__content p{font-size:13px;line-height:20px;margin:0}.connectors-page .ai-plugin-callout__decoration{height:110px;inset-inline-end:16px;position:absolute;top:12px;width:110px}.connectors-page>p{color:#949494}@media (max-width:680px){.connectors-page .ai-plugin-callout{padding:12px;padding-inline-end:100px}.connectors-page .ai-plugin-callout__decoration{height:75px;inset-inline-end:8px;top:8px;width:75px}}@media (max-width:480px){.connectors-page{padding:8px}.connectors-page .ai-plugin-callout{padding-inline-end:130px}.connectors-page .components-item{padding:12px}.connectors-page .components-item>.components-v-stack>.components-h-stack:first-child svg{height:32px;width:32px}.connectors-page .components-item>.components-v-stack>.components-h-stack:first-child>.components-h-stack:last-child{align-items:flex-end;flex-direction:column}}")); + style.setAttribute("data-wp-hash", "3ac7d2cc0e"); + style.appendChild(document.createTextNode(".connectors-page{box-sizing:border-box;margin:0 auto;max-width:680px;padding:24px;width:100%}.connectors-page .components-item{background:#fff;border:1px solid #ddd;border-radius:8px;overflow:hidden;padding:20px;scroll-margin-top:120px}.connectors-page .connector-settings__error{color:#cc1818}.connectors-page .connector-settings .components-text-control__input{font-family:monospace;scroll-margin-top:120px}.connectors-page__file-mods-notice{margin-bottom:16px}.connectors-page--empty{align-items:center;display:flex;flex-direction:column;flex-grow:1;gap:32px;justify-content:center;text-align:center}.connectors-page .ai-plugin-callout{background-color:#e7d4e4;background-image:radial-gradient(ellipse 70% 120% at 18% 115%,rgba(202,158,198,.75) 0,rgba(202,158,198,0) 60%),radial-gradient(ellipse 55% 110% at 92% -15%,rgba(208,175,217,.7) 0,rgba(208,175,217,0) 65%),radial-gradient(ellipse 40% 85% at 58% -10%,rgba(170,130,184,.45) 0,rgba(170,130,184,0) 70%);border-radius:8px;overflow:hidden;padding:24px;padding-inline-end:150px;position:relative}[dir=rtl] .connectors-page .ai-plugin-callout{background-image:radial-gradient(ellipse 70% 120% at 82% 115%,rgba(202,158,198,.75) 0,rgba(202,158,198,0) 60%),radial-gradient(ellipse 55% 110% at 8% -15%,rgba(208,175,217,.7) 0,rgba(208,175,217,0) 65%),radial-gradient(ellipse 40% 85% at 42% -10%,rgba(170,130,184,.45) 0,rgba(170,130,184,0) 70%)}.connectors-page .ai-plugin-callout__content{align-items:flex-start;display:flex;flex-direction:column;gap:12px;padding-top:2px}.connectors-page .ai-plugin-callout__content p{font-size:13px;line-height:20px;margin:0}.connectors-page .ai-plugin-callout__decoration{height:110px;inset-inline-end:16px;position:absolute;top:12px;width:110px}.connectors-page__help-text{color:#757575}@media (max-width:680px){.connectors-page .ai-plugin-callout{padding:12px;padding-inline-end:100px}.connectors-page .ai-plugin-callout__decoration{height:75px;inset-inline-end:8px;top:8px;width:75px}}@media (max-width:480px){.connectors-page{padding:8px}.connectors-page .ai-plugin-callout{padding-inline-end:130px}.connectors-page .components-item{padding:12px}.connectors-page .components-item>.components-v-stack>.components-h-stack:first-child svg{height:32px;width:32px}.connectors-page .components-item>.components-v-stack>.components-h-stack:first-child>.components-h-stack:last-child{align-items:flex-end;flex-direction:column}}")); document.head.appendChild(style); } @@ -12690,7 +12693,7 @@ function ConnectorsPage() { } ) }) ] }), - canInstallPlugins && !isFileModDisabled && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("p", { children: (0, import_element36.createInterpolateElement)( + canInstallPlugins && !isFileModDisabled && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("p", { className: "connectors-page__help-text", children: (0, import_element36.createInterpolateElement)( (0, import_i18n10.__)( "If the connector you need is not listed, search the plugin directory to see if a connector is available." ), diff --git a/src/wp-includes/build/routes/connectors-home/content.min.asset.php b/src/wp-includes/build/routes/connectors-home/content.min.asset.php index 1dda70de8f9a3..218d4f7011497 100644 --- a/src/wp-includes/build/routes/connectors-home/content.min.asset.php +++ b/src/wp-includes/build/routes/connectors-home/content.min.asset.php @@ -1 +1 @@ - array('react', 'react-dom', 'react-jsx-runtime', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-element', 'wp-i18n', 'wp-notices', 'wp-primitives', 'wp-private-apis', 'wp-theme', 'wp-url', 'wp-warning'), 'module_dependencies' => array(array('id' => '@wordpress/a11y', 'import' => 'static'), array('id' => '@wordpress/connectors', 'import' => 'static'), array('id' => '@wordpress/route', 'import' => 'static')), 'version' => '9c97839e08e086000847'); \ No newline at end of file + array('react', 'react-dom', 'react-jsx-runtime', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-element', 'wp-i18n', 'wp-notices', 'wp-primitives', 'wp-private-apis', 'wp-theme', 'wp-url', 'wp-warning'), 'module_dependencies' => array(array('id' => '@wordpress/a11y', 'import' => 'static'), array('id' => '@wordpress/connectors', 'import' => 'static'), array('id' => '@wordpress/route', 'import' => 'static')), 'version' => '16b7fec75bfa6a8fa4db'); \ No newline at end of file diff --git a/src/wp-includes/build/routes/connectors-home/content.min.js b/src/wp-includes/build/routes/connectors-home/content.min.js index 2296c11a9ccd8..341bc8c92e33d 100644 --- a/src/wp-includes/build/routes/connectors-home/content.min.js +++ b/src/wp-includes/build/routes/connectors-home/content.min.js @@ -1,4 +1,4 @@ -var Zf=Object.create;var Ir=Object.defineProperty;var Qf=Object.getOwnPropertyDescriptor;var Jf=Object.getOwnPropertyNames;var $f=Object.getPrototypeOf,ep=Object.prototype.hasOwnProperty;var Te=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),Mt=(e,t)=>{for(var o in t)Ir(e,o,{get:t[o],enumerable:!0})},tp=(e,t,o,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of Jf(t))!ep.call(e,r)&&r!==o&&Ir(e,r,{get:()=>t[r],enumerable:!(n=Qf(t,r))||n.enumerable});return e};var b=(e,t,o)=>(o=e!=null?Zf($f(e)):{},tp(t||!e||!e.__esModule?Ir(o,"default",{value:e,enumerable:!0}):o,e));var st=Te(($h,da)=>{da.exports=window.wp.i18n});var ce=Te((t0,fa)=>{fa.exports=window.wp.element});var z=Te((o0,pa)=>{pa.exports=window.React});var W=Te((l0,ha)=>{ha.exports=window.ReactJSXRuntime});var Ht=Te((bw,Ua)=>{Ua.exports=window.ReactDOM});var Gc=Te(Uc=>{"use strict";var xo=z();function ng(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var rg=typeof Object.is=="function"?Object.is:ng,ig=xo.useState,sg=xo.useEffect,ag=xo.useLayoutEffect,cg=xo.useDebugValue;function lg(e,t){var o=t(),n=ig({inst:{value:o,getSnapshot:t}}),r=n[0].inst,i=n[1];return ag(function(){r.value=o,r.getSnapshot=t,bi(r)&&i({inst:r})},[e,o,t]),sg(function(){return bi(r)&&i({inst:r}),e(function(){bi(r)&&i({inst:r})})},[e]),cg(o),o}function bi(e){var t=e.getSnapshot;e=e.value;try{var o=t();return!rg(e,o)}catch{return!0}}function dg(e,t){return t()}var ug=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?dg:lg;Uc.useSyncExternalStore=xo.useSyncExternalStore!==void 0?xo.useSyncExternalStore:ug});var Un=Te((av,Kc)=>{"use strict";Kc.exports=Gc()});var qc=Te(Xc=>{"use strict";var Gn=z(),fg=Un();function pg(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var mg=typeof Object.is=="function"?Object.is:pg,gg=fg.useSyncExternalStore,bg=Gn.useRef,hg=Gn.useEffect,wg=Gn.useMemo,vg=Gn.useDebugValue;Xc.useSyncExternalStoreWithSelector=function(e,t,o,n,r){var i=bg(null);if(i.current===null){var s={hasValue:!1,value:null};i.current=s}else s=i.current;i=wg(function(){function l(f){if(!c){if(c=!0,d=f,f=n(f),r!==void 0&&s.hasValue){var p=s.value;if(r(p,f))return m=p}return m=f}if(p=m,mg(d,f))return p;var g=n(f);return r!==void 0&&r(p,g)?(d=f,p):(d=f,m=g)}var c=!1,d,m,u=o===void 0?null:o;return[function(){return l(t())},u===null?void 0:function(){return l(u())}]},[t,o,n,r]);var a=gg(e,i[0],i[1]);return hg(function(){s.hasValue=!0,s.value=a},[a]),vg(a),a}});var Qc=Te((lv,Zc)=>{"use strict";Zc.exports=qc()});var so=Te((C4,Bd)=>{Bd.exports=window.wp.primitives});var nu=Te((r3,ou)=>{ou.exports=window.wp.theme});var fs=Te((i3,ru)=>{ru.exports=window.wp.privateApis});var rn=Te((U5,lf)=>{lf.exports=window.wp.components});var an=Te((i8,hf)=>{hf.exports=window.wp.data});var Tr=Te((s8,wf)=>{wf.exports=window.wp.coreData});var ea=Te((l8,_f)=>{_f.exports=window.wp.notices});var xf=Te((d8,yf)=>{yf.exports=window.wp.url});function ua(e){var t,o,n="";if(typeof e=="string"||typeof e=="number")n+=e;else if(typeof e=="object")if(Array.isArray(e)){var r=e.length;for(t=0;te();function Y(e){let t=ke(ip).current;return t.next=e,rp(t.effect),t.trampoline}function ip(){let e={next:void 0,callback:sp,trampoline:(...t)=>e.callback?.(...t),effect:()=>{e.callback=e.next}};return e}function sp(){}var ba=b(z(),1),ap=()=>{},F=typeof document<"u"?ba.useLayoutEffect:ap;function cp(e,t){return function(n,...r){let i=new URL(e);return i.searchParams.set("code",n.toString()),r.forEach(s=>i.searchParams.append("args[]",s)),`${t} error #${n}; visit ${i} for the full message.`}}var lp=cp("https://base-ui.com/production-error","Base UI"),De=lp;var qt=b(z(),1);function Mr(e,t,o,n){let r=ke(va).current;return dp(r,e,t,o,n)&&_a(r,[e,t,o,n]),r.callback}function wa(e){let t=ke(va).current;return up(t,e)&&_a(t,e),t.callback}function va(){return{callback:null,cleanup:null,refs:[]}}function dp(e,t,o,n,r){return e.refs[0]!==t||e.refs[1]!==o||e.refs[2]!==n||e.refs[3]!==r}function up(e,t){return e.refs.length!==t.length||e.refs.some((o,n)=>o!==t[n])}function _a(e,t){if(e.refs=t,t.every(o=>o==null)){e.callback=null;return}e.callback=o=>{if(e.cleanup&&(e.cleanup(),e.cleanup=null),o!=null){let n=Array(t.length).fill(null);for(let r=0;r{for(let r=0;r=e}function Br(e){if(!xa.isValidElement(e))return null;let t=e,o=t.props;return(po(19)?o?.ref:t.ref)??null}function zo(e,t){if(e&&!t)return e;if(!e&&t)return t;if(e||t)return{...e,...t}}function Ge(){}var Sa=Object.freeze([]),me=Object.freeze({});function Ra(e,t){let o={};for(let n in e){let r=e[n];if(t?.hasOwnProperty(n)){let i=t[n](r);i!=null&&Object.assign(o,i);continue}r===!0?o[`data-${n.toLowerCase()}`]="":r&&(o[`data-${n.toLowerCase()}`]=r.toString())}return o}function Ea(e,t){return typeof e=="function"?e(t):e}function Ta(e,t){return typeof e=="function"?e(t):e}var Hr={};function ve(e,t,o,n,r){if(!o&&!n&&!r&&!e)return _n(t);let i=_n(e);return t&&(i=Do(i,t)),o&&(i=Do(i,o)),n&&(i=Do(i,n)),r&&(i=Do(i,r)),i}function ka(e){if(e.length===0)return Hr;if(e.length===1)return _n(e[0]);let t=_n(e[0]);for(let o=1;o=65&&r<=90&&(typeof t=="function"||typeof t>"u")}function zr(e){return typeof e=="function"}function Ca(e,t){return zr(e)?e(t):e??Hr}function gp(e,t){return t?e?(...o)=>{let n=o[0];if(Oa(n)){let i=n;jo(i);let s=t(...o);return i.baseUIHandlerPrevented||e?.(...o),s}let r=t(...o);return e?.(...o),r}:Aa(t):e}function Aa(e){return e&&((...t)=>{let o=t[0];return Oa(o)&&jo(o),e(...t)})}function jo(e){return e.preventBaseUIHandler=()=>{e.baseUIHandlerPrevented=!0},e}function Dr(e,t){return t?e?t+" "+e:t:e}function Oa(e){return e!=null&&typeof e=="object"&&"nativeEvent"in e}var jr=b(z(),1);function Oe(e,t,o={}){let n=t.render,r=bp(t,o);if(o.enabled===!1)return null;let i=o.state??me;return vp(e,n,r,i)}function bp(e,t={}){let{className:o,style:n,render:r}=e,{state:i=me,ref:s,props:a,stateAttributesMapping:l,enabled:c=!0}=t,d=c?Ea(o,i):void 0,m=c?Ta(n,i):void 0,u=c?Ra(i,l):me,f=c&&a?hp(a):void 0,p=c?zo(u,f)??{}:me;return typeof document<"u"&&(c?Array.isArray(s)?p.ref=wa([p.ref,Br(r),...s]):p.ref=Mr(p.ref,Br(r),s):Mr(null,null)),c?(d!==void 0&&(p.className=Dr(p.className,d)),m!==void 0&&(p.style=zo(p.style,m)),p):me}function hp(e){return Array.isArray(e)?ka(e):ve(void 0,e)}var wp=Symbol.for("react.lazy");function vp(e,t,o,n){if(t){if(typeof t=="function")return t(o,n);let r=ve(o,t.props);r.ref=o.ref;let i=t;return i?.$$typeof===wp&&(i=qt.Children.toArray(t)[0]),qt.cloneElement(i,r)}if(e&&typeof e=="string")return _p(e,o);throw new Error(De(8))}function _p(e,t){return e==="button"?(0,jr.createElement)("button",{type:"button",...t,key:t.key}):e==="img"?(0,jr.createElement)("img",{alt:"",...t,key:t.key}):qt.createElement(e,t)}var yn=b(z(),1);var Na=0;function yp(e,t="mui"){let[o,n]=yn.useState(e),r=e||o;return yn.useEffect(()=>{o==null&&(Na+=1,n(`${t}-${Na}`))},[o,t]),r}var Ia=Ho.useId;function mo(e,t){if(Ia!==void 0){let o=Ia();return e??(t?`${t}-${o}`:o)}return yp(e,t)}function La(e){return mo(e,"base-ui")}var G={};Mt(G,{cancelOpen:()=>qp,chipRemovePress:()=>Op,clearPress:()=>Ap,closePress:()=>Pp,closeWatcher:()=>Vp,decrementPress:()=>Lp,disabled:()=>Qp,drag:()=>Gp,escapeKey:()=>Fp,focusOut:()=>jp,imperativeAction:()=>em,incrementPress:()=>Ip,initial:()=>$p,inputBlur:()=>Hp,inputChange:()=>Mp,inputClear:()=>Bp,inputPaste:()=>zp,inputPress:()=>Dp,itemPress:()=>kp,keyboard:()=>Yp,linkPress:()=>Cp,listNavigation:()=>Wp,missing:()=>Jp,none:()=>xp,outsidePress:()=>Tp,pointer:()=>Up,scrub:()=>Xp,siblingOpen:()=>Zp,swipe:()=>tm,trackPress:()=>Np,triggerFocus:()=>Ep,triggerHover:()=>Rp,triggerPress:()=>Sp,wheel:()=>Kp,windowResize:()=>om});var xp="none",Sp="trigger-press",Rp="trigger-hover",Ep="trigger-focus",Tp="outside-press",kp="item-press",Pp="close-press",Cp="link-press",Ap="clear-press",Op="chip-remove-press",Np="track-press",Ip="increment-press",Lp="decrement-press",Mp="input-change",Bp="input-clear",Hp="input-blur",zp="input-paste",Dp="input-press",jp="focus-out",Fp="escape-key",Vp="close-watcher",Wp="list-navigation",Yp="keyboard",Up="pointer",Gp="drag",Kp="wheel",Xp="scrub",qp="cancel-open",Zp="sibling-open",Qp="disabled",Jp="missing",$p="initial",em="imperative-action",tm="swipe",om="window-resize";function ee(e,t,o,n){let r=!1,i=!1,s=n??me;return{reason:e,event:t??new Event("base-ui"),cancel(){r=!0},allowPropagation(){i=!0},get isCanceled(){return r},get isPropagationAllowed(){return i},trigger:o,...s}}var Vr=b(z(),1);var Ma=b(z(),1);function go(e){Ma.useEffect(e,Sa)}var xn=null,Y0=globalThis.requestAnimationFrame,Fr=class{callbacks=[];callbacksCount=0;nextId=1;startId=1;isScheduled=!1;tick=t=>{this.isScheduled=!1;let o=this.callbacks,n=this.callbacksCount;if(this.callbacks=[],this.callbacksCount=0,this.startId=this.nextId,n>0)for(let r=0;r=this.callbacks.length||(this.callbacks[o]=null,this.callbacksCount-=1)}},Sn=new Fr;var gt=class e{static create(){return new e}static request(t){return Sn.request(t)}static cancel(t){return Sn.cancel(t)}currentId=xn;request(t){this.cancel(),this.currentId=Sn.request(()=>{this.currentId=xn,t()})}cancel=()=>{this.currentId!==xn&&(Sn.cancel(this.currentId),this.currentId=xn)};disposeEffect=()=>this.cancel};function bo(){let e=ke(gt.create).current;return go(e.disposeEffect),e}function Ba(e,t=!1,o=!1){let[n,r]=Vr.useState(e&&t?"idle":void 0),[i,s]=Vr.useState(e);return e&&!i&&(s(!0),r("starting")),!e&&i&&n!=="ending"&&!o&&r("ending"),!e&&!i&&n==="ending"&&r(void 0),F(()=>{if(!e&&i&&n!=="ending"&&o){let a=gt.request(()=>{r("ending")});return()=>{gt.cancel(a)}}},[e,i,n,o]),F(()=>{if(!e||t)return;let a=gt.request(()=>{r(void 0)});return()=>{gt.cancel(a)}},[t,e]),F(()=>{if(!e||!t)return;e&&i&&n!=="idle"&&r("starting");let a=gt.request(()=>{r("idle")});return()=>{gt.cancel(a)}},[t,e,i,n]),{mounted:i,setMounted:s,transitionStatus:n}}var Wr=(function(e){return e.startingStyle="data-starting-style",e.endingStyle="data-ending-style",e})({}),nm={"data-starting-style":""},rm={"data-ending-style":""},Ha={transitionStatus(e){return e==="starting"?nm:e==="ending"?rm:null}};var wo=b(z(),1);function Rn(){return typeof window<"u"}function Qt(e){return En(e)?(e.nodeName||"").toLowerCase():"#document"}function fe(e){var t;return(e==null||(t=e.ownerDocument)==null?void 0:t.defaultView)||window}function ht(e){var t;return(t=(En(e)?e.ownerDocument:e.document)||window.document)==null?void 0:t.documentElement}function En(e){return Rn()?e instanceof Node||e instanceof fe(e).Node:!1}function U(e){return Rn()?e instanceof Element||e instanceof fe(e).Element:!1}function he(e){return Rn()?e instanceof HTMLElement||e instanceof fe(e).HTMLElement:!1}function ho(e){return!Rn()||typeof ShadowRoot>"u"?!1:e instanceof ShadowRoot||e instanceof fe(e).ShadowRoot}function Fo(e){let{overflow:t,overflowX:o,overflowY:n,display:r}=Le(e);return/auto|scroll|overlay|hidden|clip/.test(t+n+o)&&r!=="inline"&&r!=="contents"}function za(e){return/^(table|td|th)$/.test(Qt(e))}function Vo(e){try{if(e.matches(":popover-open"))return!0}catch{}try{return e.matches(":modal")}catch{return!1}}var im=/transform|translate|scale|rotate|perspective|filter/,sm=/paint|layout|strict|content/,Zt=e=>!!e&&e!=="none",Yr;function Tn(e){let t=U(e)?Le(e):e;return Zt(t.transform)||Zt(t.translate)||Zt(t.scale)||Zt(t.rotate)||Zt(t.perspective)||!kn()&&(Zt(t.backdropFilter)||Zt(t.filter))||im.test(t.willChange||"")||sm.test(t.contain||"")}function Da(e){let t=bt(e);for(;he(t)&&!wt(t);){if(Tn(t))return t;if(Vo(t))return null;t=bt(t)}return null}function kn(){return Yr==null&&(Yr=typeof CSS<"u"&&CSS.supports&&CSS.supports("-webkit-backdrop-filter","none")),Yr}function wt(e){return/^(html|body|#document)$/.test(Qt(e))}function Le(e){return fe(e).getComputedStyle(e)}function Wo(e){return U(e)?{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}:{scrollLeft:e.scrollX,scrollTop:e.scrollY}}function bt(e){if(Qt(e)==="html")return e;let t=e.assignedSlot||e.parentNode||ho(e)&&e.host||ht(e);return ho(t)?t.host:t}function ja(e){let t=bt(e);return wt(t)?(e.ownerDocument||e).body:he(t)&&Fo(t)?t:ja(t)}function Bt(e,t,o){var n;t===void 0&&(t=[]),o===void 0&&(o=!0);let r=ja(e),i=r===((n=e.ownerDocument)==null?void 0:n.body),s=fe(r);if(i){let a=Pn(s);return t.concat(s,s.visualViewport||[],Fo(r)?r:[],a&&o?Bt(a):[])}else return t.concat(r,Bt(r,[],o))}function Pn(e){return e.parent&&Object.getPrototypeOf(e.parent)?e.frameElement:null}var Cn=b(z(),1),am=Cn.createContext(void 0);function Fa(e=!1){let t=Cn.useContext(am);if(t===void 0&&!e)throw new Error(De(16));return t}var Va=b(z(),1);function Wa(e){let{focusableWhenDisabled:t,disabled:o,composite:n=!1,tabIndex:r=0,isNativeButton:i}=e,s=n&&t!==!1,a=n&&t===!1;return{props:Va.useMemo(()=>{let c={onKeyDown(d){o&&t&&d.key!=="Tab"&&d.preventDefault()}};return n||(c.tabIndex=r,!i&&o&&(c.tabIndex=t?r:-1)),(i&&(t||s)||!i&&o)&&(c["aria-disabled"]=o),i&&(!t||a)&&(c.disabled=o),c},[n,o,t,s,a,i,r])}}function Pe(e){return e?.ownerDocument||document}function An(e,t,{detail:o=0}={}){e.dispatchEvent(new(fe(e)).PointerEvent("click",{bubbles:!0,cancelable:!0,composed:!0,detail:o,shiftKey:t.shiftKey,ctrlKey:t.ctrlKey,altKey:t.altKey,metaKey:t.metaKey}))}function Ya(e={}){let{disabled:t=!1,focusableWhenDisabled:o,tabIndex:n=0,native:r=!0,composite:i}=e,s=wo.useRef(null),a=Fa(!0),l=i??a!==void 0,{props:c}=Wa({focusableWhenDisabled:o,disabled:t,composite:l,tabIndex:n,isNativeButton:r}),d=wo.useCallback(()=>{let f=s.current;Ur(f)&&l&&t&&c.disabled===void 0&&f.disabled&&(f.disabled=!1)},[t,c.disabled,l]);F(d,[d]);let m=wo.useCallback((f={})=>{let{onClick:p,onMouseDown:g,onKeyUp:h,onKeyDown:y,onPointerDown:_,...v}=f;return ve({onClick(w){if(t){w.preventDefault();return}p?.(w)},onMouseDown(w){t||g?.(w)},onKeyDown(w){if(t||(jo(w),y?.(w),w.baseUIHandlerPrevented))return;let R=w.target===w.currentTarget,x=w.currentTarget,S=Ur(x),E=!r&&cm(x),T=R&&(r?S:!E),P=w.key==="Enter",N=w.key===" ",H=x.getAttribute("role"),j=H?.startsWith("menuitem")||H==="option"||H==="gridcell";if(R&&l&&N){if(w.defaultPrevented&&j)return;w.preventDefault(),(!r||S)&&(w.preventBaseUIHandler(),An(x,w));return}if(!T||r||!N&&!P){R&&E&&N&&w.preventDefault();return}w.defaultPrevented||(w.preventDefault(),P&&(w.preventBaseUIHandler(),An(x,w)))},onKeyUp(w){if(!t){if(jo(w),h?.(w),w.target===w.currentTarget&&r&&l&&Ur(w.currentTarget)&&w.key===" "){w.preventDefault();return}w.baseUIHandlerPrevented||w.target===w.currentTarget&&!r&&!l&&!w.defaultPrevented&&w.key===" "&&(w.preventBaseUIHandler(),An(w.currentTarget,w))}},onPointerDown(w){if(t){w.preventDefault();return}_?.(w)}},r?{type:"button"}:{role:"button"},c,v)},[t,c,l,r]),u=Y(f=>{s.current=f,d()});return{getButtonProps:m,buttonRef:u}}function Ur(e){return he(e)&&e.tagName==="BUTTON"}function cm(e){return he(e)&&e.tagName==="A"&&!!e.href}function oe(e,t,o,n){return e.addEventListener(t,o,n),()=>{e.removeEventListener(t,o,n)}}function je(e){let t=ke(lm,e).current;return t.next=e,F(t.effect),t}function lm(e){let t={current:e,next:e,effect:()=>{t.current=t.next}};return t}var Xa=b(z(),1);var Ka=b(Ht(),1);function Ga(e){return e==null?e:"current"in e?e.current:e}function vo(e,t=!1){let o=bo();return Y((n,r=null)=>{o.cancel();let i=Ga(e);if(i==null)return;let s=i,a=()=>{Ka.flushSync(n)};if(typeof s.getAnimations!="function"||globalThis.BASE_UI_ANIMATIONS_DISABLED){n();return}function l(){Promise.all(s.getAnimations().map(c=>c.finished)).then(()=>{r?.aborted||a()},()=>{if(r?.aborted)return;if(s.getAnimations().some(d=>d.pending||d.playState!=="finished")){l();return}a()})}if(t){let c="data-starting-style";if(!s.hasAttribute(c)){o.request(l);return}let d=new MutationObserver(()=>{s.hasAttribute(c)||(d.disconnect(),l())});d.observe(s,{attributes:!0,attributeFilter:[c]}),r?.addEventListener("abort",()=>d.disconnect(),{once:!0});return}o.request(l)})}function On(e){let{enabled:t=!0,open:o,ref:n,onComplete:r}=e,i=Y(r),s=vo(n,o);Xa.useEffect(()=>{if(!t)return;let a=new AbortController;return s(i,a.signal),()=>{a.abort()}},[t,o,i,s])}var kt={};Mt(kt,{engine:()=>Zr,env:()=>Jr,os:()=>Xr,screenReader:()=>Qr});var Xr={};Mt(Xr,{android:()=>Qa,apple:()=>Kr,ios:()=>Gr,linux:()=>mm,mac:()=>Ja,windows:()=>pm});function dm(){return typeof navigator>"u"?{userAgent:"",platform:"",maxTouchPoints:0}:{userAgent:navigator.userAgent,platform:navigator.platform??"",maxTouchPoints:navigator.maxTouchPoints??0}}var{userAgent:um,platform:fm,maxTouchPoints:qa}=dm(),Jt=um.toLowerCase(),$t=fm.toLowerCase();var Gr=/^i(os$|p)/.test($t)||$t==="macintel"&&qa>1,Za="android",Qa=$t===Za||Jt.includes(Za),Ja=!Gr&&$t.startsWith("mac"),pm=$t.startsWith("win"),mm=!Qa&&/^(linux|chrome os)/.test($t),Kr=Ja||Gr;var Zr={};Mt(Zr,{blink:()=>bm,gecko:()=>gm,webkit:()=>qr});var qr=typeof CSS<"u"&&!!CSS.supports?.("-webkit-backdrop-filter:none"),gm=!qr&&Jt.includes("firefox"),bm=!qr&&Jt.includes("chrom");var Qr={};Mt(Qr,{voiceOver:()=>hm});var hm=Kr;var Jr={};Mt(Jr,{jsdom:()=>wm});var wm=/jsdom|happydom/.test(Jt);var Yo=0,Ke=class e{static create(){return new e}currentId=Yo;start(t,o){this.clear(),this.currentId=setTimeout(()=>{this.currentId=Yo,o()},t)}isStarted(){return this.currentId!==Yo}clear=()=>{this.currentId!==Yo&&(clearTimeout(this.currentId),this.currentId=Yo)};disposeEffect=()=>this.clear};function at(){let e=ke(Ke.create).current;return go(e.disposeEffect),e}var Be=b(z(),1);function $a(e){return"nativeEvent"in e}function Pt(e,t){let o=["mouse","pen"];return t||o.push("",void 0),o.includes(e)}function ec(e){let t=e.type;return t==="click"||t==="mousedown"||t==="keydown"||t==="keyup"}var $r="data-base-ui-focusable";var ei="input:not([type='hidden']):not([disabled]),[contenteditable]:not([contenteditable='false']),textarea:not([disabled])";function Nn(e){let t=e.activeElement;for(;t?.shadowRoot?.activeElement!=null;)t=t.shadowRoot.activeElement;return t}function re(e,t){if(!e||!t)return!1;let o=t.getRootNode?.();if(e.contains(t))return!0;if(o&&ho(o)){let n=t;for(;n;){if(e===n)return!0;n=n.parentNode||n.host}}return!1}function Me(e){return"composedPath"in e?e.composedPath()[0]:e.target}function zt(e,t){if(!U(e))return!1;let o=e;if(t.hasElement(o))return!o.hasAttribute("data-trigger-disabled");for(let[,n]of t.entries())if(re(n,o))return!n.hasAttribute("data-trigger-disabled");return!1}function In(e,t){if(t==null)return!1;if("composedPath"in e)return e.composedPath().includes(t);let o=e;return o.target!=null&&t.contains(o.target)}function tc(e){return e.matches("html,body")}function oc(e){return he(e)&&e.matches(ei)}function ti(e){return e?.closest(`button,a[href],[role="button"],select,[tabindex]:not([tabindex="-1"]),${ei}`)!=null}function nc(e){if(!e||kt.env.jsdom)return!0;try{return e.matches(":focus-visible")}catch{return!0}}function vm(e,t){return t!=null&&!Pt(t)?0:typeof e=="function"?e():e}function $e(e,t,o){let n=vm(e,o);return typeof n=="number"?n:n?.[t]}function oi(e){return typeof e=="function"?e():e}function Ln(e,t){return t||e==="click"||e==="mousedown"}function rc(e){return e?.includes("mouse")&&e!=="mousedown"}var ic=b(W(),1),sc=Be.createContext({hasProvider:!1,timeoutMs:0,delayRef:{current:0},initialDelayRef:{current:0},timeout:new Ke,currentIdRef:{current:null},currentContextRef:{current:null}});function _m(e,t){e.current=t.current}function ni(e){let{children:t,delay:o,timeoutMs:n=0}=e,r=Be.useRef(o),i=Be.useRef(o),s=Be.useRef(null),a=Be.useRef(null),l=at();return F(()=>{if(i.current=o,!s.current){r.current=o;return}r.current={open:$e(r.current,"open"),close:$e(o,"close")}},[o,s,r,i]),(0,ic.jsx)(sc.Provider,{value:Be.useMemo(()=>({hasProvider:!0,delayRef:r,initialDelayRef:i,currentIdRef:s,timeoutMs:n,currentContextRef:a,timeout:l}),[n,l]),children:t})}function ri(e,t={open:!1}){let{open:o}=t,n="rootStore"in e?e.rootStore:e,r=n.useState("floatingId"),i=Be.useContext(sc),{currentIdRef:s,delayRef:a,timeoutMs:l,initialDelayRef:c,currentContextRef:d,hasProvider:m,timeout:u}=i,[f,p]=Be.useState(!1),g=Be.useRef(o);return F(()=>{g.current=o},[o]),F(()=>{function h(){d.current?.setIsInstantPhase(!1),s.current=null,d.current=null,a.current=c.current,u.clear()}if(s.current&&!o&&s.current===r){if(p(!1),l){let y=r;return u.start(l,()=>{n.select("open")||s.current&&s.current!==y||h()}),()=>{(g.current||s.current!==y)&&u.clear()}}h()}},[o,r,s,a,l,c,d,u,n]),F(()=>{if(!o)return;let h=d.current,y=s.current;u.clear(),d.current={onOpenChange:n.setOpen,setIsInstantPhase:p},s.current=r,a.current={open:0,close:$e(c.current,"close")},y!==null&&y!==r?(p(!0),h?.setIsInstantPhase(!0),h?.onOpenChange(!1,ee(G.none))):(p(!1),h?.setIsInstantPhase(!1))},[o,r,n,s,a,c,d,u]),F(()=>()=>{if(s.current===r){if(d.current=null,!g.current)return;s.current=null,_m(a,c),u.clear()}},[d,s,a,r,c,u]),Be.useMemo(()=>({hasProvider:m,delayRef:a,isInstantPhase:f}),[m,a,f])}function ct(...e){return()=>{for(let t=0;t({x:e,y:e}),ym={left:"right",right:"left",bottom:"top",top:"bottom"};function Bn(e,t,o){return lt(e,Dt(t,o))}function _t(e,t){return typeof e=="function"?e(t):e}function Ne(e){return e.split("-")[0]}function dt(e){return e.split("-")[1]}function Hn(e){return e==="x"?"y":"x"}function Ko(e){return e==="y"?"height":"width"}function Fe(e){let t=e[0];return t==="t"||t==="b"?"y":"x"}function Xo(e){return Hn(Fe(e))}function lc(e,t,o){o===void 0&&(o=!1);let n=dt(e),r=Xo(e),i=Ko(r),s=r==="x"?n===(o?"end":"start")?"right":"left":n==="start"?"bottom":"top";return t.reference[i]>t.floating[i]&&(s=Uo(s)),[s,Uo(s)]}function dc(e){let t=Uo(e);return[Mn(e),t,Mn(t)]}function Mn(e){return e.includes("start")?e.replace("start","end"):e.replace("end","start")}var ac=["left","right"],cc=["right","left"],xm=["top","bottom"],Sm=["bottom","top"];function Rm(e,t,o){switch(e){case"top":case"bottom":return o?t?cc:ac:t?ac:cc;case"left":case"right":return t?xm:Sm;default:return[]}}function uc(e,t,o,n){let r=dt(e),i=Rm(Ne(e),o==="start",n);return r&&(i=i.map(s=>s+"-"+r),t&&(i=i.concat(i.map(Mn)))),i}function Uo(e){let t=Ne(e);return ym[t]+e.slice(t.length)}function Em(e){var t,o,n,r;return{top:(t=e.top)!=null?t:0,right:(o=e.right)!=null?o:0,bottom:(n=e.bottom)!=null?n:0,left:(r=e.left)!=null?r:0}}function zn(e){return typeof e!="number"?Em(e):{top:e,right:e,bottom:e,left:e}}function eo(e){let{x:t,y:o,width:n,height:r}=e;return{width:n,height:r,top:o,left:t,right:t+n,bottom:o+r,x:t,y:o}}function Ct(e,t,o=!0){return e.filter(r=>r.parentId===t).flatMap(r=>[...!o||r.context?.open?[r]:[],...Ct(e,r.id,o)])}function _o(e){return`data-base-ui-${e}`}var He=b(z(),1),mc=b(Ht(),1);var fc={style:{transition:"none"}};var Tm="data-base-ui-swipe-ignore",km="data-swipe-ignore",o1=`[${Tm}]`,n1=`[${km}]`;var pc={fallbackAxisSide:"end"};var gc=b(W(),1),Pm=He.createContext(null),Cm=()=>He.useContext(Pm),Am=_o("portal");function bc(e={}){let{ref:t,container:o,componentProps:n=me,elementProps:r}=e,i=mo(),a=Cm()?.portalNode,[l,c]=He.useState(null),[d,m]=He.useState(null),u=Y(h=>{h!==null&&m(h)}),f=He.useRef(null);F(()=>{if(o===null){f.current&&(f.current=null,m(null),c(null));return}let h=(o&&(En(o)?o:o.current))??a??document.body;if(h==null){f.current&&(f.current=null,m(null),c(null));return}f.current!==h&&(f.current=h,m(null),c(h))},[o,a]);let p=Oe("div",n,{ref:[t,u],props:[{id:i,[Am]:""},r]}),g=l&&p?mc.createPortal(p,l):null;return{node:d,nodeId:He.isValidElement(p)?p.props.id:void 0,subtree:g}}var to=b(z(),1);function hc(){let e=new Map;return{emit(t,o){e.get(t)?.forEach(n=>n(o))},on(t,o){e.has(t)||e.set(t,new Set),e.get(t).add(o)},off(t,o){e.get(t)?.delete(o)}}}var Om=b(W(),1),Nm=to.createContext(null),Im=to.createContext(null),Dn=()=>to.useContext(Nm)?.id||null,Ft=e=>{let t=to.useContext(Im);return e??t};var Ve=b(z(),1);function Lm(e,t){let o=null,n=null,r=!1;return{contextElement:e||void 0,getBoundingClientRect(){let i=e?.getBoundingClientRect()||{width:0,height:0,x:0,y:0},s=t.axis==="x"||t.axis==="both",a=t.axis==="y"||t.axis==="both",l=["mouseenter","mousemove"].includes(t.dataRef.current.openEvent?.type||"")&&t.pointerType!=="touch",c=i.width,d=i.height,m=i.x,u=i.y;return o==null&&t.x&&s&&(o=i.x-t.x),n==null&&t.y&&a&&(n=i.y-t.y),m-=o||0,u-=n||0,c=0,d=0,!r||l?(c=t.axis==="y"?i.width:0,d=t.axis==="x"?i.height:0,m=s&&t.x!=null?t.x:m,u=a&&t.y!=null?t.y:u):r&&!l&&(d=t.axis==="x"?i.height:d,c=t.axis==="y"?i.width:c),r=!0,{width:c,height:d,x:m,y:u,top:u,right:m+c,bottom:u+d,left:m}}}}function wc(e){return e!=null&&e.clientX!=null}function ii(e,t={}){let{enabled:o=!0,axis:n="both"}=t,r="rootStore"in e?e.rootStore:e,i=r.useState("open"),s=r.useState("floatingElement"),a=r.useState("domReferenceElement"),l=r.context.dataRef,c=Ve.useRef(!1),d=Ve.useRef(null),[m,u]=Ve.useState(),[f,p]=Ve.useState([]),g=Y(w=>{r.set("positionReference",w)}),h=Y((w,R,x)=>{c.current||l.current.openEvent&&!wc(l.current.openEvent)||r.set("positionReference",Lm(x??a,{x:w,y:R,axis:n,dataRef:l,pointerType:m}))}),y=Y(w=>{i?d.current||(h(w.clientX,w.clientY,w.currentTarget),p([])):h(w.clientX,w.clientY,w.currentTarget)}),_=Pt(m)?s:i;Ve.useEffect(()=>{if(!o){g(a);return}if(!_)return;function w(){d.current?.(),d.current=null}let R=fe(s);function x(S){let E=Me(S);re(s,E)?w():h(S.clientX,S.clientY)}return!l.current.openEvent||wc(l.current.openEvent)?d.current=oe(R,"mousemove",x):g(a),w},[_,o,s,l,a,r,h,g,f]),Ve.useEffect(()=>()=>{r.set("positionReference",null)},[r]),Ve.useEffect(()=>{o&&!s&&(c.current=!1)},[o,s]),Ve.useEffect(()=>{!o&&i&&(c.current=!0)},[o,i]);let v=Ve.useMemo(()=>{function w(R){u(R.pointerType)}return{onPointerDown:w,onPointerEnter:w,onMouseMove:y,onMouseEnter:y}},[y]);return Ve.useMemo(()=>o?{reference:v,trigger:v}:{},[o,v])}var Xe=b(z(),1);function Mm(){return!1}function Bm(e){return{escapeKey:typeof e=="boolean"?e:e?.escapeKey??!1,outsidePress:typeof e=="boolean"?e:e?.outsidePress??!0}}function si(e,t={}){let{enabled:o=!0,escapeKey:n=!0,outsidePress:r=!0,outsidePressEvent:i="sloppy",referencePress:s=Mm,bubbles:a,externalTree:l}=t,c="rootStore"in e?e.rootStore:e,d=c.useState("open"),m=c.useState("floatingElement"),{dataRef:u}=c.context,f=Ft(l),p=Y(typeof r=="function"?r:()=>!1),g=typeof r=="function"?p:r,h=g!==!1,y=Y(()=>i),{escapeKey:_,outsidePress:v}=Bm(a),w=Xe.useRef(!1),R=Xe.useRef(!1),x=Xe.useRef(!1),S=Xe.useRef(!1),E=Xe.useRef(""),T=Xe.useRef(null),P=at(),N=at(),H=Y(()=>{N.clear(),u.current.insideReactTree=!1}),j=Y(O=>{let V=u.current.floatingContext?.nodeId;return(f?Ct(f.nodesRef.current,V):[]).some(ie=>ie.context?.open&&!ie.context.dataRef.current[O])}),L=Y(O=>In(O,c.select("floatingElement"))||In(O,c.select("domReferenceElement"))),k=Y(O=>{s()&&c.setOpen(!1,ee(G.triggerPress,O.nativeEvent))}),I=Y(O=>{if(!d||!o||!n||O.key!=="Escape"||S.current||!_&&j("__escapeKeyBubbles"))return;let V=$a(O)?O.nativeEvent:O,Z=ee(G.escapeKey,V);c.setOpen(!1,Z),Z.isCanceled||O.preventDefault(),!_&&!Z.isPropagationAllowed&&O.stopPropagation()}),C=Y(()=>{u.current.insideReactTree=!0,N.start(0,H)}),A=Y(O=>{if(!d||!o||O.button!==0)return;let V=Me(O.nativeEvent);re(c.select("floatingElement"),V)&&(w.current||(w.current=!0,R.current=!1))}),M=Y(O=>{!d||!o||(O.defaultPrevented||O.nativeEvent.defaultPrevented)&&w.current&&(R.current=!0)});Xe.useEffect(()=>{if(!d||!o)return H;u.current.__escapeKeyBubbles=_,u.current.__outsidePressBubbles=v;let O=new Ke,V=new Ke;function Z(){O.clear(),S.current=!0}function ie(){O.start(kt.engine.webkit?5:0,()=>{S.current=!1})}function K(){x.current=!0,V.start(0,()=>{x.current=!1})}function Q(){w.current=!1,R.current=!1}function q(){let B=E.current,D=B==="pen"||!B?"mouse":B,Se=y(),Ae=typeof Se=="function"?Se():Se;return typeof Ae=="string"?Ae:Ae[D]}function $(B){let D=q();return D==="intentional"&&B.type!=="click"||D==="sloppy"&&B.type==="click"}function ne(B){let D=u.current.floatingContext?.nodeId,Se=f&&Ct(f.nodesRef.current,D).some(Ae=>In(B,Ae.context?.elements.floating));return L(B)||Se}function se(B){if($(B)){B.type!=="click"&&!L(B)&&(V.clear(),x.current=!1),H();return}if(u.current.insideReactTree){H();return}let D=Me(B),Se=`[${_o("inert")}]`,Ae=U(D)?D.getRootNode():null,Nt=Array.from((ho(Ae)?Ae:Pe(c.select("floatingElement"))).querySelectorAll(Se)),it=c.context.triggerElements;if(D&&(it.hasElement(D)||it.hasMatchingElement(Ye=>re(Ye,D))))return;let It=U(D)?D:null;for(;It&&!wt(It);){let Ye=bt(It);if(wt(Ye)||!U(Ye))break;It=Ye}if(!(Nt.length&&U(D)&&!tc(D)&&!re(D,c.select("floatingElement"))&&Nt.every(Ye=>!re(It,Ye)))){if(he(D)&&!("touches"in B)){let Ye=wt(D),uo=Le(D),Xt=/auto|scroll/,pn=Ye||Xt.test(uo.overflowX),fo=Ye||Xt.test(uo.overflowY),Lt=pn&&D.clientWidth>0&&D.scrollWidth>D.clientWidth,mn=fo&&D.clientHeight>0&&D.scrollHeight>D.clientHeight,gn=uo.direction==="rtl",bn=mn&&(gn?B.offsetX<=D.offsetWidth-D.clientWidth:B.offsetX>D.clientWidth),hn=Lt&&B.offsetY>D.clientHeight;if(bn||hn)return}if(!ne(B)){if(q()==="intentional"&&x.current){V.clear(),x.current=!1;return}typeof g=="function"&&!g(B)||j("__outsidePressBubbles")||(c.setOpen(!1,ee(G.outsidePress,B)),H())}}}function ze(B){q()!=="sloppy"||B.pointerType==="touch"||!c.select("open")||!o||L(B)||se(B)}function ae(B){if(q()!=="sloppy"||!c.select("open")||!o||L(B))return;let D=B.touches[0];D&&(T.current={startTime:Date.now(),startX:D.clientX,startY:D.clientY,dismissOnTouchEnd:!1,dismissOnMouseDown:!0},P.start(1e3,()=>{T.current&&(T.current.dismissOnTouchEnd=!1,T.current.dismissOnMouseDown=!1)}))}function ge(B,D){let Se=Me(B);if(!Se)return;let Ae=oe(Se,B.type,()=>{D(B),Ae()})}function be(B){E.current="touch",ge(B,ae)}function Ee(B){P.clear(),B.type==="pointerdown"&&(E.current=B.pointerType),!(B.type==="mousedown"&&T.current&&!T.current.dismissOnMouseDown)&&ge(B,D=>{D.type==="pointerdown"?ze(D):se(D)})}function ye(B){if(!w.current)return;let D=R.current;if(Q(),q()==="intentional"){if(B.type==="pointercancel"){D&&K();return}if(!ne(B)){if(D){K();return}typeof g=="function"&&!g(B)||(V.clear(),x.current=!0,H())}}}function Kt(B){if(q()!=="sloppy"||!T.current||L(B))return;let D=B.touches[0];if(!D)return;let Se=Math.abs(D.clientX-T.current.startX),Ae=Math.abs(D.clientY-T.current.startY),Nt=Math.sqrt(Se*Se+Ae*Ae);Nt>5&&(T.current.dismissOnTouchEnd=!0),Nt>10&&(se(B),P.clear(),T.current=null)}function rt(B){ge(B,Kt)}function ft(B){q()!=="sloppy"||!T.current||L(B)||(T.current.dismissOnTouchEnd&&se(B),P.clear(),T.current=null)}function Ot(B){ge(B,ft)}let xe=Pe(m),fn=ct(n&&ct(oe(xe,"keydown",I),oe(xe,"compositionstart",Z),oe(xe,"compositionend",ie)),h&&ct(oe(xe,"click",Ee,!0),oe(xe,"pointerdown",Ee,!0),oe(xe,"pointerup",ye,!0),oe(xe,"pointercancel",ye,!0),oe(xe,"mousedown",Ee,!0),oe(xe,"mouseup",ye,!0),oe(xe,"touchstart",be,!0),oe(xe,"touchmove",rt,!0),oe(xe,"touchend",Ot,!0)));return()=>{fn(),O.clear(),V.clear(),Q(),x.current=!1,H()}},[u,m,n,h,g,d,o,_,v,I,H,y,j,L,f,c,P]);let X=Xe.useMemo(()=>({onKeyDown:I,onPointerDown:k,onClick:k}),[I,k]),de=Xe.useMemo(()=>({onKeyDown:I,onPointerDown:M,onMouseDown:M,onClickCapture:C,onMouseDownCapture(O){C(),A(O)},onPointerDownCapture(O){C(),A(O)},onMouseUpCapture:C,onTouchEndCapture:C,onTouchMoveCapture:C}),[I,C,A,M]);return Xe.useMemo(()=>o?{reference:X,floating:de,trigger:X}:{},[o,X,de])}var Ie=b(z(),1);function vc(e,t,o){let{reference:n,floating:r}=e,i=Fe(t),s=Xo(t),a=Ko(s),l=Ne(t),c=i==="y",d=n.x+n.width/2-r.width/2,m=n.y+n.height/2-r.height/2,u=n[a]/2-r[a]/2,f;switch(l){case"top":f={x:d,y:n.y-r.height};break;case"bottom":f={x:d,y:n.y+n.height};break;case"right":f={x:n.x+n.width,y:m};break;case"left":f={x:n.x-r.width,y:m};break;default:f={x:n.x,y:n.y}}let p=dt(t);return p&&(f[s]+=u*(p==="end"?1:-1)*(o&&c?-1:1)),f}async function _c(e,t){var o;t===void 0&&(t={});let{x:n,y:r,platform:i,rects:s,elements:a,strategy:l}=e,{boundary:c="clippingAncestors",rootBoundary:d="viewport",elementContext:m="floating",altBoundary:u=!1,padding:f=0}=_t(t,e),p=zn(f),h=a[u?m==="floating"?"reference":"floating":m],y=eo(await i.getClippingRect({element:(o=await(i.isElement==null?void 0:i.isElement(h)))==null||o?h:h.contextElement||await(i.getDocumentElement==null?void 0:i.getDocumentElement(a.floating)),boundary:c,rootBoundary:d,strategy:l})),_=m==="floating"?{x:n,y:r,width:s.floating.width,height:s.floating.height}:s.reference,v=await(i.getOffsetParent==null?void 0:i.getOffsetParent(a.floating)),w=await(i.isElement==null?void 0:i.isElement(v))&&await(i.getScale==null?void 0:i.getScale(v))||{x:1,y:1},R=eo(i.convertOffsetParentRelativeRectToViewportRelativeRect?await i.convertOffsetParentRelativeRectToViewportRelativeRect({elements:a,rect:_,offsetParent:v,strategy:l}):_);return{top:(y.top-R.top+p.top)/w.y,bottom:(R.bottom-y.bottom+p.bottom)/w.y,left:(y.left-R.left+p.left)/w.x,right:(R.right-y.right+p.right)/w.x}}var Hm=50,yc=async(e,t,o)=>{let{placement:n="bottom",strategy:r="absolute",middleware:i=[],platform:s}=o,a=s.detectOverflow?s:{...s,detectOverflow:_c},l=await(s.isRTL==null?void 0:s.isRTL(t)),c=await s.getElementRects({reference:e,floating:t,strategy:r}),{x:d,y:m}=vc(c,n,l),u=n,f=0,p={};for(let g=0;gL<=0)){var N,H;let L=(((N=i.flip)==null?void 0:N.index)||0)+1,k=S[L];if(k&&(!(m==="alignment"?_!==Fe(k):!1)||P.every(A=>Fe(A.placement)===_?A.overflows[0]>0:!0)))return{data:{index:L,overflows:P},reset:{placement:k}};let I=(H=P.filter(C=>C.overflows[0]<=0).sort((C,A)=>C.overflows[1]-A.overflows[1])[0])==null?void 0:H.placement;if(!I)switch(f){case"bestFit":{var j;let C=(j=P.filter(A=>{if(x){let M=Fe(A.placement);return M===_||M==="y"}return!0}).map(A=>[A.placement,A.overflows.filter(M=>M>0).reduce((M,X)=>M+X,0)]).sort((A,M)=>A[1]-M[1])[0])==null?void 0:j[0];C&&(I=C);break}case"initialPlacement":I=a;break}if(r!==I)return{reset:{placement:I}}}return{}}}};var Sc=new Set(["left","top"]);async function zm(e,t){let{placement:o,platform:n,elements:r}=e,i=await(n.isRTL==null?void 0:n.isRTL(r.floating)),s=Ne(o),a=dt(o),l=Fe(o)==="y",c=Sc.has(s)?-1:1,d=i&&l?-1:1,m=_t(t,e),{mainAxis:u,crossAxis:f,alignmentAxis:p}=typeof m=="number"?{mainAxis:m,crossAxis:0,alignmentAxis:null}:{mainAxis:m.mainAxis||0,crossAxis:m.crossAxis||0,alignmentAxis:m.alignmentAxis};return a&&typeof p=="number"&&(f=a==="end"?p*-1:p),l?{x:f*d,y:u*c}:{x:u*c,y:f*d}}var Rc=function(e){return e===void 0&&(e=0),{name:"offset",options:e,async fn(t){var o,n;let{x:r,y:i,placement:s,middlewareData:a}=t,l=await zm(t,e);return s===((o=a.offset)==null?void 0:o.placement)&&(n=a.arrow)!=null&&n.alignmentOffset?{}:{x:r+l.x,y:i+l.y,data:{...l,placement:s}}}}},Ec=function(e){return e===void 0&&(e={}),{name:"shift",options:e,async fn(t){let{x:o,y:n,placement:r,platform:i}=t,{mainAxis:s=!0,crossAxis:a=!1,limiter:l={fn:_=>{let{x:v,y:w}=_;return{x:v,y:w}}},...c}=_t(e,t),d={x:o,y:n},m=await i.detectOverflow(t,c),u=Fe(r),f=Hn(u),p=d[f],g=d[u],h=(_,v)=>Bn(v+m[_==="y"?"top":"left"],v,v-m[_==="y"?"bottom":"right"]);s&&(p=h(f,p)),a&&(g=h(u,g));let y=l.fn({...t,[f]:p,[u]:g});return{...y,data:{x:y.x-o,y:y.y-n,enabled:{[f]:s,[u]:a}}}}}},Tc=function(e){return e===void 0&&(e={}),{options:e,fn(t){var o,n;let{x:r,y:i,placement:s,rects:a,middlewareData:l}=t,{offset:c=0,mainAxis:d=!0,crossAxis:m=!0}=_t(e,t),u={x:r,y:i},f=Fe(s),p=Hn(f),g=u[p],h=u[f],y=_t(c,t),_=typeof y=="number"?{mainAxis:y,crossAxis:0}:{mainAxis:(o=y.mainAxis)!=null?o:0,crossAxis:(n=y.crossAxis)!=null?n:0};if(d){let R=p==="y"?"height":"width",x=a.reference[p]-a.floating[R]+_.mainAxis,S=a.reference[p]+a.reference[R]-_.mainAxis;gS&&(g=S)}if(m){var v,w;let R=p==="y"?"width":"height",x=Sc.has(Ne(s)),S=a.reference[f]-a.floating[R]+(x&&((v=l.offset)==null?void 0:v[f])||0)+(x?0:_.crossAxis),E=a.reference[f]+a.reference[R]+(x?0:((w=l.offset)==null?void 0:w[f])||0)-(x?_.crossAxis:0);hE&&(h=E)}return{[p]:g,[f]:h}}}},kc=function(e){return e===void 0&&(e={}),{name:"size",options:e,async fn(t){let{placement:o,rects:n,platform:r,elements:i}=t,{apply:s=()=>{},...a}=_t(e,t),l=await r.detectOverflow(t,a),c=Ne(o),d=dt(o),m=Fe(o)==="y",{width:u,height:f}=n.floating,p,g;c==="top"||c==="bottom"?(p=c,g=d===(await(r.isRTL==null?void 0:r.isRTL(i.floating))?"start":"end")?"left":"right"):(g=c,p=d==="end"?"top":"bottom");let h=f-l.top-l.bottom,y=u-l.left-l.right,_=Dt(f-l[p],h),v=Dt(u-l[g],y),w=t.middlewareData.shift,R=!w,x=_,S=v;w!=null&&w.enabled.x&&(S=y),w!=null&&w.enabled.y&&(x=h),R&&!d&&(m?S=u-2*lt(l.left,l.right):x=f-2*lt(l.top,l.bottom)),await s({...t,availableWidth:S,availableHeight:x});let E=await r.getDimensions(i.floating);return u!==E.width||f!==E.height?{reset:{rects:!0}}:{}}}};function Ac(e){let t=Le(e),o=parseFloat(t.width)||0,n=parseFloat(t.height)||0,r=he(e),i=r?e.offsetWidth:o,s=r?e.offsetHeight:n,a=jt(o)!==i||jt(n)!==s;return a&&(o=i,n=s),{width:o,height:n,$:a}}function ci(e){return U(e)?e:e.contextElement}function yo(e){let t=ci(e);if(!he(t))return vt(1);let o=t.getBoundingClientRect(),{width:n,height:r,$:i}=Ac(t),s=(i?jt(o.width):o.width)/n,a=(i?jt(o.height):o.height)/r;return(!s||!Number.isFinite(s))&&(s=1),(!a||!Number.isFinite(a))&&(a=1),{x:s,y:a}}var Dm=vt(0);function Oc(e){let t=fe(e);return!kn()||!t.visualViewport?Dm:{x:t.visualViewport.offsetLeft,y:t.visualViewport.offsetTop}}function jm(e,t,o){return t===void 0&&(t=!1),!!o&&t&&o===fe(e)}function oo(e,t,o,n){t===void 0&&(t=!1),o===void 0&&(o=!1);let r=e.getBoundingClientRect(),i=ci(e),s=vt(1);t&&(n?U(n)&&(s=yo(n)):s=yo(e));let a=jm(i,o,n)?Oc(i):vt(0),l=(r.left+a.x)/s.x,c=(r.top+a.y)/s.y,d=r.width/s.x,m=r.height/s.y;if(i&&n){let u=fe(i),f=U(n)?fe(n):n,p=u,g=Pn(p);for(;g&&f!==p;){let h=yo(g),y=g.getBoundingClientRect(),_=Le(g),v=y.left+(g.clientLeft+parseFloat(_.paddingLeft))*h.x,w=y.top+(g.clientTop+parseFloat(_.paddingTop))*h.y;l*=h.x,c*=h.y,d*=h.x,m*=h.y,l+=v,c+=w,p=fe(g),g=Pn(p)}}return eo({width:d,height:m,x:l,y:c})}function jn(e,t){let o=Wo(e).scrollLeft;return t?t.left+o:oo(ht(e)).left+o}function Nc(e,t){let o=e.getBoundingClientRect(),n=o.left+t.scrollLeft-jn(e,o),r=o.top+t.scrollTop;return{x:n,y:r}}function Fm(e){let{elements:t,rect:o,offsetParent:n,strategy:r}=e,i=r==="fixed",s=ht(n),a=t?Vo(t.floating):!1;if(n===s||a&&i)return o;let l={scrollLeft:0,scrollTop:0},c=vt(1),d=vt(0),m=he(n);if((m||!i)&&((Qt(n)!=="body"||Fo(s))&&(l=Wo(n)),m)){let f=oo(n);c=yo(n),d.x=f.x+n.clientLeft,d.y=f.y+n.clientTop}let u=s&&!m&&!i?Nc(s,l):vt(0);return{width:o.width*c.x,height:o.height*c.y,x:o.x*c.x-l.scrollLeft*c.x+d.x+u.x,y:o.y*c.y-l.scrollTop*c.y+d.y+u.y}}function Vm(e){return e.getClientRects?Array.from(e.getClientRects()):[]}function Wm(e){let t=Wo(e),o=e.ownerDocument.body,n=lt(e.scrollWidth,e.clientWidth,o.scrollWidth,o.clientWidth),r=lt(e.scrollHeight,e.clientHeight,o.scrollHeight,o.clientHeight),i=-t.scrollLeft+jn(e),s=-t.scrollTop;return Le(o).direction==="rtl"&&(i+=lt(e.clientWidth,o.clientWidth)-n),{width:n,height:r,x:i,y:s}}var Ym=25;function Um(e,t,o){o===void 0&&(o="viewport");let n=o==="layoutViewport",r=fe(e),i=ht(e),s=r.visualViewport,a=i.clientWidth,l=i.clientHeight,c=0,d=0;if(s){let u=!kn()||t==="fixed";n?u||(c=-s.offsetLeft,d=-s.offsetTop):(a=s.width,l=s.height,u&&(c=s.offsetLeft,d=s.offsetTop))}if(jn(i)<=0){let u=i.ownerDocument,f=u.body,p=getComputedStyle(f),g=u.compatMode==="CSS1Compat"&&parseFloat(p.marginLeft)+parseFloat(p.marginRight)||0,h=Math.abs(i.clientWidth-f.clientWidth-g),y=getComputedStyle(i).scrollbarGutter==="stable both-edges"?h/2:h;y<=Ym&&(a-=y)}return{width:a,height:l,x:c,y:d}}function Gm(e,t){let o=oo(e,!0,t==="fixed"),n=o.top+e.clientTop,r=o.left+e.clientLeft,i=yo(e),s=e.clientWidth*i.x,a=e.clientHeight*i.y,l=r*i.x,c=n*i.y;return{width:s,height:a,x:l,y:c}}function Pc(e,t,o){let n;if(t==="viewport"||t==="layoutViewport")n=Um(e,o,t);else if(t==="document")n=Wm(ht(e));else if(U(t))n=Gm(t,o);else{let r=Oc(e);n={x:t.x-r.x,y:t.y-r.y,width:t.width,height:t.height}}return eo(n)}function Km(e,t){let o=t.get(e);if(o)return o;let n=Bt(e,[],!1).filter(a=>U(a)&&Qt(a)!=="body"),r=null,i=Le(e).position==="fixed",s=i?bt(e):e;for(;U(s)&&!wt(s);){let a=Le(s),l=Tn(s),c=r?r.position:i?"fixed":"";!l&&(c==="fixed"||c==="absolute"&&a.position==="static")?n=n.filter(m=>m!==s):r=a,s=bt(s)}return t.set(e,n),n}function Xm(e){let{element:t,boundary:o,rootBoundary:n,strategy:r}=e,s=[...o==="clippingAncestors"?Vo(t)?[]:Km(t,this._c):[].concat(o),n],a=Pc(t,s[0],r),l=a.top,c=a.right,d=a.bottom,m=a.left;for(let u=1;u{a(!1,1e-7)},1e3)}S=!1}try{n=new IntersectionObserver(E,{...x,root:i.ownerDocument})}catch{n=new IntersectionObserver(E,x)}n.observe(e)}let l=fe(e),c=()=>a(o);return l.addEventListener("resize",c),a(!0),()=>{l.removeEventListener("resize",c),s()}}function qo(e,t,o,n){n===void 0&&(n={});let{ancestorScroll:r=!0,ancestorResize:i=!0,elementResize:s=typeof ResizeObserver=="function",layoutShift:a=typeof IntersectionObserver=="function",animationFrame:l=!1}=n,c=ci(e),d=r||i?[...c?Bt(c):[],...t?Bt(t):[]]:[];d.forEach(y=>{r&&y.addEventListener("scroll",o),i&&y.addEventListener("resize",o)});let m=c&&a?$m(c,o,i):null,u=-1,f=null;s&&(f=new ResizeObserver(y=>{let[_]=y;_&&_.target===c&&f&&t&&(f.unobserve(t),cancelAnimationFrame(u),u=requestAnimationFrame(()=>{var v;(v=f)==null||v.observe(t)})),o()}),c&&!l&&f.observe(c),t&&f.observe(t));let p,g=l?oo(e):null;l&&h();function h(){let y=oo(e);g&&!Lc(g,y)&&o(),g=y,p=requestAnimationFrame(h)}return o(),()=>{var y;d.forEach(_=>{r&&_.removeEventListener("scroll",o),i&&_.removeEventListener("resize",o)}),m?.(),(y=f)==null||y.disconnect(),f=null,l&&cancelAnimationFrame(p)}}var Mc=Rc;var Bc=Ec,Hc=xc,zc=kc;var Dc=Tc,Fn=(e,t,o)=>{let n=new Map,r=o??{},i={...li,...r.platform,_c:n};return yc(e,t,{...r,platform:i})};var we=b(z(),1),Fc=b(z(),1),Vc=b(Ht(),1),tg=typeof document<"u",og=function(){},Vn=tg?Fc.useLayoutEffect:og;function Wn(e,t){if(e===t)return!0;if(typeof e!=typeof t)return!1;if(typeof e=="function"&&e.toString()===t.toString())return!0;let o,n,r;if(e&&t&&typeof e=="object"){if(Array.isArray(e)){if(o=e.length,o!==t.length)return!1;for(n=o;n--!==0;)if(!Wn(e[n],t[n]))return!1;return!0}if(r=Object.keys(e),o=r.length,o!==Object.keys(t).length)return!1;for(n=o;n--!==0;)if(!{}.hasOwnProperty.call(t,r[n]))return!1;for(n=o;n--!==0;){let i=r[n];if(!(i==="_owner"&&e.$$typeof)&&!Wn(e[i],t[i]))return!1}return!0}return e!==e&&t!==t}function Wc(e){return typeof window>"u"?1:(e.ownerDocument.defaultView||window).devicePixelRatio||1}function jc(e,t){let o=Wc(e);return Math.round(t*o)/o}function di(e){let t=we.useRef(e);return Vn(()=>{t.current=e}),t}function Yc(e){e===void 0&&(e={});let{placement:t="bottom",strategy:o="absolute",middleware:n=[],platform:r,elements:{reference:i,floating:s}={},transform:a=!0,whileElementsMounted:l,open:c}=e,[d,m]=we.useState({x:0,y:0,strategy:o,placement:t,middlewareData:{},isPositioned:!1}),[u,f]=we.useState(n);Wn(u,n)||f(n);let[p,g]=we.useState(null),[h,y]=we.useState(null),_=we.useCallback(A=>{A!==x.current&&(x.current=A,g(A))},[]),v=we.useCallback(A=>{A!==S.current&&(S.current=A,y(A))},[]),w=i||p,R=s||h,x=we.useRef(null),S=we.useRef(null),E=we.useRef(d),T=l!=null,P=di(l),N=di(r),H=di(c),j=we.useCallback(()=>{if(!x.current||!S.current)return;let A={placement:t,strategy:o,middleware:u};N.current&&(A.platform=N.current),Fn(x.current,S.current,A).then(M=>{let X={...M,isPositioned:H.current!==!1};L.current&&!Wn(E.current,X)&&(E.current=X,Vc.flushSync(()=>{m(X)}))})},[u,t,o,N,H]);Vn(()=>{c===!1&&E.current.isPositioned&&(E.current.isPositioned=!1,m(A=>({...A,isPositioned:!1})))},[c]);let L=we.useRef(!1);Vn(()=>(L.current=!0,()=>{L.current=!1}),[]),Vn(()=>{if(w&&(x.current=w),R&&(S.current=R),w&&R){if(P.current)return P.current(w,R,j);j()}},[w,R,j,P,T]);let k=we.useMemo(()=>({reference:x,floating:S,setReference:_,setFloating:v}),[_,v]),I=we.useMemo(()=>({reference:w,floating:R}),[w,R]),C=we.useMemo(()=>{let A={position:o,left:0,top:0};if(!I.floating)return A;let M=jc(I.floating,d.x),X=jc(I.floating,d.y);return a?{...A,transform:"translate("+M+"px, "+X+"px)",...Wc(I.floating)>=1.5&&{willChange:"transform"}}:{position:o,left:M,top:X}},[o,a,I.floating,d.x,d.y]);return we.useMemo(()=>({...d,update:j,refs:k,elements:I,floatingStyles:C}),[d,j,k,I,C])}var ui=(e,t)=>{let o=Mc(e);return{name:o.name,fn:o.fn,options:[e,t]}},fi=(e,t)=>{let o=Bc(e);return{name:o.name,fn:o.fn,options:[e,t]}},pi=(e,t)=>({fn:Dc(e).fn,options:[e,t]}),mi=(e,t)=>{let o=Hc(e);return{name:o.name,fn:o.fn,options:[e,t]}},gi=(e,t)=>{let o=zc(e);return{name:o.name,fn:o.fn,options:[e,t]}};var Yn=class{attachedStores=[];attachedStoreValue=null;storeListeners=new Set;constructor(t,o,n=!0){this.fallbackStore=t,this.componentName=o,this.throwOnMissingTrigger=n}get attachedStore(){return this.attachedStoreValue}get store(){return this.attachedStoreValue??this.fallbackStore}get serverStore(){return this.fallbackStore}subscribeStore(t){return this.storeListeners.add(t),()=>{this.storeListeners.delete(t)}}attachStore(t){return this.attachedStores.push(t),this.setActiveStore(t),()=>{let o=this.attachedStores.lastIndexOf(t);o!==-1&&this.attachedStores.splice(o,1),this.setActiveStore(this.attachedStores[this.attachedStores.length-1]??null)}}setActiveStore(t){this.attachedStoreValue!==t&&(this.attachedStoreValue=t,this.storeListeners.forEach(o=>{o()}))}openByTrigger(t){let o=this.attachedStore;if(o===null)return;let n;if(t){for(let r=this.attachedStores.length-1;r>=0&&!n;r-=1)n=this.attachedStores[r].context.triggerElements.getById(t);n??=this.fallbackStore.context.triggerElements.getById(t)}if(t&&!n&&this.throwOnMissingTrigger)throw new Error(De(99,this.componentName,t,this.componentName));o.setOpen(!0,ee(G.imperativeAction,void 0,n))}closePopup(){let t=this.attachedStore;t!==null&&t.setOpen(!1,ee(G.imperativeAction))}};var ro=b(z(),1),sl=b(Ht(),1);var rl=b(z(),1);var ol=b(z(),1),_i=b(Un(),1),nl=b(Qc(),1);var Jc=b(z(),1);var hi=[],wi;function $c(){return wi}function el(e){hi.push(e)}function vi(e){let t=(o,n)=>{let r=ke(_g).current,i;try{wi=r;for(let s of hi)s.before(r);i=e(o,n);for(let s of hi)s.after(r);r.didInitialize=!0}finally{wi=void 0}return i};return t.displayName=e.displayName||e.name,t}function tl(e){return Jc.forwardRef(vi(e))}function _g(){return{didInitialize:!1}}var yg=po(19),xg=yg?Rg:Eg;function Kn(e,t,o,n,r){return xg(e,t,o,n,r)}function Sg(e,t,o,n,r){let i=ol.useCallback(()=>t(e.getSnapshot(),o,n,r),[e,t,o,n,r]);return(0,_i.useSyncExternalStore)(e.subscribe,i,i)}el({before(e){e.syncIndex=0,e.didInitialize||(e.syncTick=1,e.syncHooks=[],e.didChangeStore=!0,e.getSnapshot=()=>{let t=!1;for(let o=0;o0&&(e.didChangeStore&&(e.didChangeStore=!1,e.subscribe=t=>{let o=new Set;for(let r of e.syncHooks)o.add(r.store);let n=[];for(let r of o)n.push(r.subscribe(t));return()=>{for(let r of n)r()}}),(0,_i.useSyncExternalStore)(e.subscribe,e.getSnapshot,e.getSnapshot))}});function Rg(e,t,o,n,r){let i=$c();if(!i)return Sg(e,t,o,n,r);let s=i.syncIndex;i.syncIndex+=1;let a;return i.didInitialize?(a=i.syncHooks[s],(a.store!==e||a.selector!==t||!Object.is(a.a1,o)||!Object.is(a.a2,n)||!Object.is(a.a3,r))&&(a.store!==e&&(i.didChangeStore=!0),a.store=e,a.selector=t,a.a1=o,a.a2=n,a.a3=r,a.value=t(e.getSnapshot(),o,n,r))):(a={store:e,selector:t,a1:o,a2:n,a3:r,value:t(e.getSnapshot(),o,n,r)},i.syncHooks.push(a)),a.value}function Eg(e,t,o,n,r){return(0,nl.useSyncExternalStoreWithSelector)(e.subscribe,e.getSnapshot,e.getSnapshot,i=>t(i,o,n,r))}var Xn=class{constructor(t){this.state=t,this.listeners=new Set,this.updateTick=0}subscribe=t=>(this.listeners.add(t),()=>{this.listeners.delete(t)});getSnapshot=()=>this.state;setState(t){if(this.state===t)return;this.state=t,this.updateTick+=1;let o=this.updateTick;for(let n of this.listeners){if(o!==this.updateTick)return;n(t)}}update(t){for(let o in t)if(!Object.is(this.state[o],t[o])){this.setState({...this.state,...t});return}}set(t,o){Object.is(this.state[t],o)||this.setState({...this.state,[t]:o})}notifyAll(){let t={...this.state};this.setState(t)}use(t,o,n,r){return Kn(this,t,o,n,r)}};var no=b(z(),1);var Vt=class extends Xn{constructor(t,o={},n){super(t),this.context=o,this.selectors=n}useSyncedValue(t,o){no.useDebugValue(t);let n=this;F(()=>{n.state[t]!==o&&n.set(t,o)},[n,t,o])}useSyncedValueWithCleanup(t,o){let n=this;F(()=>(n.state[t]!==o&&n.set(t,o),()=>{n.set(t,void 0)}),[n,t,o])}useSyncedValues(t){let o=this,n=Object.values(t);F(()=>{o.update(t)},[o,...n])}useControlledProp(t,o){no.useDebugValue(t);let n=this,r=o!==void 0;F(()=>{r&&!Object.is(n.state[t],o)&&n.setState({...n.state,[t]:o})},[n,t,o,r])}select(t,o,n,r){let i=this.selectors[t];return i(this.state,o,n,r)}useState(t,o,n,r){return no.useDebugValue(t),Kn(this,this.selectors[t],o,n,r)}useContextCallback(t,o){no.useDebugValue(t);let n=Y(o??Ge);this.context[t]=n}useStateSetter(t){let o=no.useRef(void 0);return o.current===void 0&&(o.current=n=>{this.set(t,n)}),o.current}observe(t,o){let n;typeof t=="function"?n=t:n=this.selectors[t];let r=n(this.state);return o(r,r,this),this.subscribe(i=>{let s=n(i);if(!Object.is(r,s)){let a=r;r=s,o(s,a,this)}})}};var Tg={open:e=>e.open,transitionStatus:e=>e.transitionStatus,domReferenceElement:e=>e.domReferenceElement,referenceElement:e=>e.positionReference??e.referenceElement,floatingElement:e=>e.floatingElement,floatingId:e=>e.floatingId},Wt=class extends Vt{constructor(t){let{syncOnly:o,nested:n,onOpenChange:r,triggerElements:i,...s}=t;super({...s,positionReference:s.referenceElement,domReferenceElement:s.referenceElement},{onOpenChange:r,dataRef:{current:{}},events:hc(),nested:n,triggerElements:i},Tg),this.syncOnly=o}syncOpenEvent=(t,o)=>{(!t||!this.state.open||o!=null&&ec(o))&&(this.context.dataRef.current.openEvent=t?o:void 0)};dispatchOpenChange=(t,o)=>{this.syncOpenEvent(t,o.event);let n={open:t,reason:o.reason,nativeEvent:o.event,nested:this.context.nested,triggerElement:o.trigger};this.context.events.emit("openchange",n)};setOpen=(t,o)=>{if(this.syncOnly){this.context.onOpenChange?.(t,o);return}this.dispatchOpenChange(t,o),this.context.onOpenChange?.(t,o)}};function il(e){let{popupStore:t,treatPopupAsFloatingElement:o=!1,floatingRootContext:n,floatingId:r,nested:i,onOpenChange:s}=e,a=t.useState("open"),l=t.useState("activeTriggerElement"),c=t.useState(o?"popupElement":"positionerElement"),d=t.context.triggerElements,m=s,u=rl.useRef(null);n===void 0&&u.current===null&&(u.current=new Wt({open:a,transitionStatus:void 0,referenceElement:l,floatingElement:c,triggerElements:d,onOpenChange:m,floatingId:r,syncOnly:!0,nested:i}));let f=n??u.current;return t.useSyncedValue("floatingId",r),F(()=>{let p={open:a,floatingId:r,referenceElement:l,floatingElement:c};U(l)&&(p.domReferenceElement=l),f.state.positionReference===f.state.referenceElement&&(p.positionReference=l),f.update(p)},[a,r,l,c,f]),f.context.onOpenChange=m,f.context.nested=i,f}var al={tabIndex:-1,[$r]:""};function cl(e,t=!1){let o=mo(),n=Dn()!=null,r=ke(()=>e(o,n)).current;return il({popupStore:r,treatPopupAsFloatingElement:t,floatingRootContext:r.state.floatingRootContext,floatingId:o,nested:n,onOpenChange:r.setOpen}),r}function ll({handle:e,store:t}){return F(()=>e.attachStore(t),[e,t]),null}function kg(e,t){let o=ro.useRef(null),n=ro.useRef(null);return ro.useCallback(r=>{if(e===void 0)return;let i=!1;if(o.current!==null){let s=o.current,a=n.current,l=t.context.triggerElements.getById(s);a&&l===a&&(t.context.triggerElements.delete(s),i=!0),o.current=null,n.current=null}if(r!==null&&(o.current=e,n.current=r,t.context.triggerElements.add(e,r),i=!0),i){let s=t.context.triggerElements.size;t.select("open")&&t.state.triggerCount!==s&&t.set("triggerCount",s)}},[t,e])}function Pg(e,t,o,n=!1){t?e.preventUnmountingOnClose=!1:n&&(e.preventUnmountingOnClose=!0);let r=o?.id??null;(r||t)&&(e.activeTriggerId=r,e.activeTriggerElement=o??null)}function Cg(e){let t=!1;return e.preventUnmountOnClose=()=>{t=!0},()=>t}function dl(e,t,o,n={}){let r=o.reason,i=r===G.triggerHover,s=t&&r===G.triggerFocus,a=!t&&(r===G.triggerPress||r===G.escapeKey),l=Cg(o);if(e.context.onOpenChange?.(t,o),o.isCanceled)return;n.onBeforeDispatch?.(),e.state.floatingRootContext.dispatchOpenChange(t,o);let c=()=>{let d={...n.extraState,open:t};s?d.instantType="focus":a?d.instantType="dismiss":i&&(d.instantType=void 0),Pg(d,t,o.trigger,l()),e.update(d)};i?sl.flushSync(c):c()}function ul(e,t,o,n){let r=o.useState("isMountedByTrigger",e),i=kg(e,o),s=Y(l=>{let c=o.select("open"),d=o.select("activeTriggerId");if(d===e){o.update({activeTriggerElement:l,...c?n:null});return}d==null&&c&&o.update({activeTriggerId:e,activeTriggerElement:l,...n})}),a=ro.useCallback(l=>{i(l),l&&s(l)},[i,s]);return F(()=>{r&&o.update({activeTriggerElement:t.current,...n})},[r,o,t,...Object.values(n)]),{registerTrigger:a,isMountedByThisTrigger:r}}function fl(e,t={}){let{closeOnActiveTriggerUnmount:o=!1}=t,n=ro.useRef(null),r=e.useState("open"),i=e.useState("triggerCount"),s=e.useState("activeTriggerId"),a=e.useState("activeTriggerElement");F(()=>{if(!r){n.current=null,e.state.triggerCount!==0&&e.set("triggerCount",0);return}let l=e.context.triggerElements.size,c={};e.state.triggerCount!==l&&(c.triggerCount=l);let d=e.select("activeTriggerId"),m=null;if(d){let u=e.context.triggerElements.getById(d);if(u)n.current=d,u!==e.state.activeTriggerElement&&(c.activeTriggerElement=u);else{for(let[f,p]of e.context.triggerElements.entries())if(p===e.state.activeTriggerElement){c.activeTriggerId=f,c.activeTriggerElement=p,n.current=f;break}c.activeTriggerId===void 0&&(n.current===d?m=d:n.current=null)}}else n.current=null;if(!m&&!d&&l===1){let u=e.context.triggerElements.entries().next();if(!u.done){let[f,p]=u.value;c.activeTriggerId=f,c.activeTriggerElement=p,n.current=f}}(c.triggerCount!==void 0||c.activeTriggerId!==void 0||c.activeTriggerElement!==void 0)&&e.update(c),m&&o&&queueMicrotask(()=>{if(e.select("open")&&e.select("activeTriggerId")===m&&!e.context.triggerElements.getById(m)){let u=ee(G.none);e.setOpen(!1,u),u.isCanceled||e.update({activeTriggerId:null,activeTriggerElement:null})}})},[r,e,i,s,a,o])}function pl(e,t,o){let{mounted:n,setMounted:r,transitionStatus:i}=Ba(e),s=t.useState("preventUnmountingOnClose"),a=e?!1:s;t.useSyncedValues({mounted:n,transitionStatus:i,preventUnmountingOnClose:a});let l=Y(()=>{r(!1),t.update({activeTriggerId:null,activeTriggerElement:null,mounted:!1,preventUnmountingOnClose:!1}),o?.(),t.context.onOpenChangeComplete?.(!1)});return On({enabled:n&&!e&&!a,open:e,ref:t.context.popupRef,onComplete(){e||l()}}),{forceUnmount:l,transitionStatus:i}}function ml(e,t){e.useSyncedValues(t),F(()=>()=>{e.update({activeTriggerProps:me,inactiveTriggerProps:me,popupProps:me})},[e])}var io=class{constructor(){this.idMap=new Map}add(t,o){this.idMap.set(t,o)}delete(t){this.idMap.delete(t)}hasElement(t){for(let o of this.idMap.values())if(o===t)return!0;return!1}hasMatchingElement(t){for(let o of this.idMap.values())if(t(o))return!0;return!1}getById(t){return this.idMap.get(t)}entries(){return this.idMap.entries()}elements(){return this.idMap.values()}get size(){return this.idMap.size}};function gl(){return new Wt({open:!1,transitionStatus:void 0,floatingElement:null,referenceElement:null,triggerElements:new io,floatingId:void 0,syncOnly:!1,nested:!1,onOpenChange:void 0})}function hl(){return{open:!1,openProp:void 0,mounted:!1,transitionStatus:void 0,floatingRootContext:gl(),floatingId:void 0,triggerCount:0,preventUnmountingOnClose:!1,payload:void 0,activeTriggerId:null,activeTriggerElement:null,triggerIdProp:void 0,popupElement:null,positionerElement:null,activeTriggerProps:me,inactiveTriggerProps:me,popupProps:me}}function wl(e,t,o=!1){return new Wt({open:!1,transitionStatus:void 0,floatingElement:null,referenceElement:null,triggerElements:e,floatingId:t,syncOnly:!0,nested:o,onOpenChange:void 0})}var Zo=e=>e.triggerIdProp??e.activeTriggerId,yi=e=>e.openProp??e.open,bl=e=>(e.popupElement?.id??e.floatingId)||void 0;function vl(e,t){return t!==void 0&&yi(e)&&Zo(e)===t}function Ag(e,t){return vl(e,t)?!0:t!==void 0&&yi(e)&&Zo(e)==null&&e.triggerCount===1}var _l={open:yi,mounted:e=>e.mounted,transitionStatus:e=>e.transitionStatus,floatingRootContext:e=>e.floatingRootContext,triggerCount:e=>e.triggerCount,preventUnmountingOnClose:e=>e.preventUnmountingOnClose,payload:e=>e.payload,activeTriggerId:Zo,activeTriggerElement:e=>e.mounted?e.activeTriggerElement:null,popupId:bl,isTriggerActive:(e,t)=>t!==void 0&&Zo(e)===t,isOpenedByTrigger:(e,t)=>vl(e,t),isMountedByTrigger:(e,t)=>t!==void 0&&Zo(e)===t&&e.mounted,triggerProps:(e,t)=>t?e.activeTriggerProps:e.inactiveTriggerProps,triggerPopupId:(e,t)=>Ag(e,t)?bl(e):void 0,popupProps:e=>e.popupProps,popupElement:e=>e.popupElement,positionerElement:e=>e.positionerElement};var xi=b(z(),1),yl=b(Un(),1);function xl(e){let t=xi.useCallback(n=>e===void 0?Ge:e.subscribeStore(n),[e]),o=xi.useCallback(()=>e===void 0?void 0:e.store,[e]);return(0,yl.useSyncExternalStore)(t,o,()=>e?.serverStore)}function Sl(e){return Og(e,e.rootContext)}function Og(e,t){let{nodeId:o,externalTree:n}=e,r=t.useState("referenceElement"),i=t.useState("floatingElement"),s=t.useState("domReferenceElement"),a=t.useState("open"),l=t.useState("floatingId"),[c,d]=Ie.useState(null),[m,u]=Ie.useState(void 0),[f,p]=Ie.useState(void 0),g=Ie.useRef(null),h=Ft(n),y=Ie.useMemo(()=>({reference:r,floating:i,domReference:s}),[r,i,s]),_=Yc({...e,elements:{...y,...c&&{reference:c}}}),v=U(m)?m:null,w=f===void 0?t.state.floatingElement:f;t.useSyncedValue("referenceElement",m??null),t.useSyncedValue("domReferenceElement",m===void 0?s:v),t.useSyncedValue("floatingElement",w);let R=Ie.useCallback(N=>{let H=U(N)?{getBoundingClientRect:()=>N.getBoundingClientRect(),getClientRects:()=>N.getClientRects(),contextElement:N}:N;d(H),_.refs.setReference(H)},[_.refs]),x=Ie.useCallback(N=>{(U(N)||N===null)&&(g.current=N,u(N)),(U(_.refs.reference.current)||_.refs.reference.current===null||N!==null&&!U(N))&&_.refs.setReference(N)},[_.refs,u]),S=Ie.useCallback(N=>{p(N),_.refs.setFloating(N)},[_.refs]),E=Ie.useMemo(()=>({..._.refs,setReference:x,setFloating:S,setPositionReference:R,domReference:g}),[_.refs,x,S,R]),T=Ie.useMemo(()=>({..._.elements,domReference:s}),[_.elements,s]),P=Ie.useMemo(()=>({..._,dataRef:t.context.dataRef,open:a,onOpenChange:t.setOpen,events:t.context.events,floatingId:l,refs:E,elements:T,nodeId:o,rootStore:t}),[_,E,T,o,t,a,l]);return F(()=>{s&&(g.current=s)},[s]),F(()=>{t.context.dataRef.current.floatingContext=P;let N=h?.nodesRef.current.find(H=>H.id===o);N&&(N.context=P)}),Ie.useMemo(()=>({..._,context:P,refs:E,elements:T,rootStore:t}),[_,E,T,P,t])}var yt=b(z(),1);var Si=kt.os.mac&&kt.engine.webkit;function Ri(e,t={}){let{enabled:o=!0,delay:n}=t,r="rootStore"in e?e.rootStore:e,{events:i,dataRef:s}=r.context,a=yt.useRef(!1),l=yt.useRef(null),c=yt.useRef(!0),d=at();yt.useEffect(()=>{let u=r.select("domReferenceElement");if(!o)return;let f=fe(u);function p(){let y=r.select("domReferenceElement");!r.select("open")&&he(y)&&y===Nn(Pe(y))&&(a.current=!0)}function g(){c.current=!0}function h(){c.current=!1}return ct(oe(f,"blur",p),Si&&oe(f,"keydown",g,!0),Si&&oe(f,"pointerdown",h,!0))},[r,o]),yt.useEffect(()=>{if(!o)return;function u(f){if(f.reason===G.triggerPress||f.reason===G.escapeKey){let p=r.select("domReferenceElement");U(p)&&(l.current=p,a.current=!0)}}return i.on("openchange",u),()=>{i.off("openchange",u)}},[i,o,r]);let m=yt.useMemo(()=>{function u(){a.current=!1,l.current=null}return{onMouseLeave(){u()},onFocus(f){let p=f.currentTarget;if(a.current){if(l.current===p)return;u()}let g=Me(f.nativeEvent);if(U(g)){if(Si&&!f.relatedTarget){if(!c.current&&!oc(g))return}else if(!nc(g))return}let h=zt(f.relatedTarget,r.context.triggerElements),{nativeEvent:y,currentTarget:_}=f,v=typeof n=="function"?n():n;if(r.select("open")&&h||v===0||v===void 0){r.setOpen(!0,ee(G.triggerFocus,y,_));return}d.start(v,()=>{a.current||r.setOpen(!0,ee(G.triggerFocus,y,_))})},onBlur(f){u();let p=f.relatedTarget,g=f.nativeEvent,h=U(p)&&p.hasAttribute(_o("focus-guard"))&&p.getAttribute("data-type")==="outside";d.start(0,()=>{let y=r.select("domReferenceElement"),_=Nn(Pe(y));!p&&_===y||re(s.current.floatingContext?.refs.floating.current,_)||re(y,_)||h||zt(p??_,r.context.triggerElements)||r.setOpen(!1,ee(G.triggerFocus,g))})}}},[s,n,r,d]);return yt.useMemo(()=>o?{reference:m,trigger:m}:{},[o,m])}var Ti=b(z(),1);var Ei=class e{constructor(){this.pointerType=void 0,this.interactedInside=!1,this.handler=void 0,this.blockMouseMove=!0,this.performedPointerEventsMutation=!1,this.pointerEventsScopeElement=null,this.pointerEventsReferenceElement=null,this.pointerEventsFloatingElement=null,this.restTimeoutPending=!1,this.openChangeTimeout=new Ke,this.restTimeout=new Ke,this.handleCloseOptions=void 0}static create(){return new e}dispose=()=>{this.openChangeTimeout.clear(),this.restTimeout.clear()};disposeEffect=()=>this.dispose},qn=new WeakMap;function So(e){if(!e.performedPointerEventsMutation)return;let t=e.pointerEventsScopeElement;t&&qn.get(t)===e&&(e.pointerEventsScopeElement?.style.removeProperty("pointer-events"),e.pointerEventsReferenceElement?.style.removeProperty("pointer-events"),e.pointerEventsFloatingElement?.style.removeProperty("pointer-events"),qn.delete(t)),e.performedPointerEventsMutation=!1,e.pointerEventsScopeElement=null,e.pointerEventsReferenceElement=null,e.pointerEventsFloatingElement=null}function Zn(e,t){let{scopeElement:o,referenceElement:n,floatingElement:r}=t,i=qn.get(o);i&&i!==e&&So(i),So(e),e.performedPointerEventsMutation=!0,e.pointerEventsScopeElement=o,e.pointerEventsReferenceElement=n,e.pointerEventsFloatingElement=r,qn.set(o,e),o.style.pointerEvents="none",n.style.pointerEvents="auto",r.style.pointerEvents="auto"}function Ro(e){let t=e.context.dataRef.current,o=ke(()=>t.hoverInteractionState??Ei.create()).current;return t.hoverInteractionState||(t.hoverInteractionState=o),go(t.hoverInteractionState.disposeEffect),t.hoverInteractionState}function ki(e,t={}){let{enabled:o=!0,closeDelay:n=0,nodeId:r}=t,i="rootStore"in e?e.rootStore:e,s=i.useState("open"),a=i.useState("floatingElement"),l=i.useState("domReferenceElement"),{dataRef:c}=i.context,d=Ft(),m=Dn(),u=Ro(i),f=at(),p=Y(()=>Ln(c.current.openEvent?.type,u.interactedInside)),g=Y(()=>rc(c.current.openEvent?.type)),h=Y(()=>{So(u)});F(()=>{s||(u.pointerType=void 0,u.restTimeoutPending=!1,u.interactedInside=!1,h())},[s,u,h]),Ti.useEffect(()=>h,[h]),F(()=>{if(o&&s&&u.handleCloseOptions?.blockPointerEvents&&g()&&U(l)&&a){let y=l,_=a,v=Pe(a),w=d?.nodesRef.current.find(E=>E.id===m)?.context?.elements.floating;w&&(w.style.pointerEvents="");let R=u.pointerEventsScopeElement!==_?u.pointerEventsScopeElement:null,x=w!==_?w:null,S=u.handleCloseOptions?.getScope?.()??R??x??y.closest("[data-rootownerid]")??v.body;return Zn(u,{scopeElement:S,referenceElement:y,floatingElement:_}),()=>{h()}}},[o,s,l,a,u,g,d,m,h]),Ti.useEffect(()=>{if(!o)return;function y(){return!!(d&&m&&Ct(d.nodesRef.current,m).length>0)}function _(E){let T=$e(n,"close",u.pointerType),P=()=>{i.setOpen(!1,ee(G.triggerHover,E)),d?.events.emit("floating.closed",E)};T?u.openChangeTimeout.start(T,P):(u.openChangeTimeout.clear(),P())}function v(E){let T=Me(E);if(!ti(T)){u.interactedInside=!1;return}u.interactedInside=T?.closest("[aria-haspopup]")!=null}function w(){u.openChangeTimeout.clear(),f.clear(),d?.events.off("floating.closed",x),h()}function R(E){if(y()&&d){d.events.on("floating.closed",x);return}if(zt(E.relatedTarget,i.context.triggerElements))return;let T=c.current.floatingContext?.nodeId??r,P=E.relatedTarget;if(!(d&&T&&U(P)&&Ct(d.nodesRef.current,T,!1).some(H=>re(H.context?.elements.floating,P)))){if(u.handler){u.handler(E);return}h(),g()&&!p()&&_(E)}}function x(E){!d||!m||y()||f.start(0,()=>{d.events.off("floating.closed",x),i.setOpen(!1,ee(G.triggerHover,E)),d.events.emit("floating.closed",E)})}let S=a;return ct(S&&oe(S,"mouseenter",w),S&&oe(S,"mouseleave",R),S&&oe(S,"pointerdown",v,!0),()=>{d?.events.off("floating.closed",x)})},[o,a,i,c,n,r,g,p,h,u,d,m,f])}var Yt=b(z(),1),Rl=b(Ht(),1);var Ng={current:null};function Pi(e,t={}){let{enabled:o=!0,delay:n=0,handleClose:r=null,mouseOnly:i=!1,restMs:s=0,move:a=!0,triggerElementRef:l=Ng,externalTree:c,isActiveTrigger:d=!0,getHandleCloseContext:m,isClosing:u,shouldOpen:f,guardStaleOpen:p=!1}=t,g="rootStore"in e?e.rootStore:e,{dataRef:h,events:y}=g.context,_=Ft(c),v=Ro(g),w=Yt.useRef(!1),R=je(r),x=je(n),S=je(s),E=je(o),T=je(f),P=je(u),N=Y(()=>Ln(h.current.openEvent?.type,v.interactedInside)),H=Y(()=>T.current?.()!==!1),j=Y((I,C,A)=>{let M=g.context.triggerElements;if(M.hasElement(C))return!I||!re(I,C);if(!U(A))return!1;let X=A;return M.hasMatchingElement(de=>re(de,X))&&(!I||!re(I,X))}),L=Y(()=>{if(!v.handler)return;Pe(g.select("domReferenceElement")).removeEventListener("mousemove",v.handler),v.handler=void 0}),k=Y(()=>{So(v)});return d&&(v.handleCloseOptions=R.current?.__options),Yt.useEffect(()=>L,[L]),Yt.useEffect(()=>{if(!o)return;function I(C){C.open?w.current=!1:(w.current=C.reason===G.triggerHover,L(),v.openChangeTimeout.clear(),v.restTimeout.clear(),v.blockMouseMove=!0,v.restTimeoutPending=!1)}return y.on("openchange",I),()=>{y.off("openchange",I)}},[o,y,v,L]),Yt.useEffect(()=>{if(!o)return;function I(O,V=!0){let Z=$e(x.current,"close",v.pointerType);Z?v.openChangeTimeout.start(Z,()=>{g.setOpen(!1,ee(G.triggerHover,O)),_?.events.emit("floating.closed",O)}):V&&(v.openChangeTimeout.clear(),g.setOpen(!1,ee(G.triggerHover,O)),_?.events.emit("floating.closed",O))}let C=l.current??(d?g.select("domReferenceElement"):null);if(!U(C))return;function A(O){if(v.openChangeTimeout.clear(),v.blockMouseMove=!1,i&&!Pt(v.pointerType))return;let V=oi(S.current),Z=$e(x.current,"open",v.pointerType),ie=Me(O),K=O.currentTarget??null,Q=g.select("domReferenceElement"),q=K;if(U(ie)&&!g.context.triggerElements.hasElement(ie)){for(let ye of g.context.triggerElements.elements())if(re(ye,ie)){q=ye;break}}U(K)&&U(Q)&&!g.context.triggerElements.hasElement(K)&&re(K,Q)&&(q=Q);let $=q==null?!1:j(Q,q,ie),ne=g.select("open"),se=P.current?.()??g.select("transitionStatus")==="ending",ze=!ne&&se&&w.current,ae=!$&&U(q)&&U(Q)&&re(Q,q)&&ze,ge=V>0&&!Z,be=$&&(ne||ze)||ae,Ee=!ne||$;if(be){H()&&g.setOpen(!0,ee(G.triggerHover,O,q));return}ge||(Z?v.openChangeTimeout.start(Z,()=>{Ee&&H()&&g.setOpen(!0,ee(G.triggerHover,O,q))}):Ee&&H()&&g.setOpen(!0,ee(G.triggerHover,O,q)))}function M(O){if(N()){k();return}L();let V=g.select("domReferenceElement"),Z=Pe(V);v.restTimeout.clear(),v.restTimeoutPending=!1;let ie=h.current.floatingContext??m?.();if(zt(O.relatedTarget,g.context.triggerElements))return;if(R.current&&ie){g.select("open")||v.openChangeTimeout.clear();let Q=l.current;v.handler=R.current({...ie,tree:_,x:O.clientX,y:O.clientY,onClose(){k(),L(),E.current&&!N()&&Q===g.select("domReferenceElement")&&I(O,!0)}}),Z.addEventListener("mousemove",v.handler),v.handler(O);return}(v.pointerType!=="touch"||!re(g.select("floatingElement"),O.relatedTarget))&&I(O)}function X(O){re(C,O.relatedTarget)||(v.openChangeTimeout.clear(),v.restTimeout.clear(),v.restTimeoutPending=!1)}let de=p?oe(C,"mouseout",X):void 0;return a?ct(oe(C,"mousemove",A,{once:!0}),oe(C,"mouseenter",A),oe(C,"mouseleave",M),de):ct(oe(C,"mouseenter",A),oe(C,"mouseleave",M),de)},[L,k,h,x,g,o,R,v,d,j,N,i,a,S,l,_,E,m,P,H,p]),Yt.useMemo(()=>{if(!o)return;function I(C){v.pointerType=C.pointerType}return{onPointerDown:I,onPointerEnter:I,onMouseMove(C){let{nativeEvent:A}=C,M=C.currentTarget,X=g.select("domReferenceElement"),de=g.select("open"),O=j(X,M,C.target);if(i&&!Pt(v.pointerType))return;if(de&&O&&v.handleCloseOptions?.blockPointerEvents){let ie=g.select("floatingElement");if(ie){let K=v.handleCloseOptions?.getScope?.()??M.ownerDocument.body;Zn(v,{scopeElement:K,referenceElement:M,floatingElement:ie})}}let V=oi(S.current);if(de&&!O||V===0||!O&&v.restTimeoutPending&&C.movementX**2+C.movementY**2<2)return;v.restTimeout.clear();function Z(){if(v.restTimeoutPending=!1,N())return;let ie=g.select("open");!v.blockMouseMove&&(!ie||O)&&H()&&g.setOpen(!0,ee(G.triggerHover,A,M))}v.pointerType==="touch"?Rl.flushSync(()=>{Z()}):O&&de?Z():(v.restTimeoutPending=!0,v.restTimeout.start(V,Z))}}},[o,v,N,j,i,g,S,H])}var El=.1,Ig=El*El,le=.5;function Qn(e,t,o,n,r,i){return n>=t!=i>=t&&e<=(r-o)*(t-n)/(i-n)+o}function Jn(e,t,o,n,r,i,s,a,l,c){let d=!1;return Qn(e,t,o,n,r,i)&&(d=!d),Qn(e,t,r,i,s,a)&&(d=!d),Qn(e,t,s,a,l,c)&&(d=!d),Qn(e,t,l,c,o,n)&&(d=!d),d}function Lg(e,t,o){return e>=o.x&&e<=o.x+o.width&&t>=o.y&&t<=o.y+o.height}function $n(e,t,o,n,r,i){let s=Math.min(o,r),a=Math.max(o,r),l=Math.min(n,i),c=Math.max(n,i);return e>=s&&e<=a&&t>=l&&t<=c}function Ci(e={}){let{blockPointerEvents:t=!1}=e,o=new Ke,n=({x:r,y:i,placement:s,elements:a,onClose:l,nodeId:c,tree:d})=>{let m=s?.split("-")[0],u=!1,f=null,p=null,g=typeof performance<"u"?performance.now():0;function h(_,v){let w=performance.now(),R=w-g;if(f===null||p===null||R===0)return f=_,p=v,g=w,!1;let x=_-f,S=v-p,E=x*x+S*S,T=R*R*Ig;return f=_,p=v,g=w,E0)}function j(){H()||y()}if(H())return;let L=w.getBoundingClientRect(),k=R.getBoundingClientRect(),I=r>k.right-k.width/2,C=i>k.bottom-k.height/2,A=k.width>L.width,M=k.height>L.height,X=(A?L:k).left,de=(A?L:k).right,O=(M?L:k).top,V=(M?L:k).bottom;if(m==="top"&&i>=L.bottom-1||m==="bottom"&&i<=L.top+1||m==="left"&&r>=L.right-1||m==="right"&&r<=L.left+1){j();return}let Z=!1;switch(m){case"top":Z=$n(x,S,X,L.top+1,de,k.bottom-1);break;case"bottom":Z=$n(x,S,X,k.top+1,de,L.bottom-1);break;case"left":Z=$n(x,S,k.right-1,V,L.left+1,O);break;case"right":Z=$n(x,S,L.right-1,V,k.left+1,O);break;default:}if(Z)return;if(u&&!Lg(x,S,L)){j();return}if(!T&&h(x,S)){j();return}let ie=!1;switch(m){case"top":{let K=A?le/2:le*4,Q=A||I?r+K:r-K,q=A?r-K:I?r+K:r-K,$=i+le+1,ne=I||A?k.bottom-le:k.top,se=I?A?k.bottom-le:k.top:k.bottom-le;ie=Jn(x,S,Q,$,q,$,k.left,ne,k.right,se);break}case"bottom":{let K=A?le/2:le*4,Q=A||I?r+K:r-K,q=A?r-K:I?r+K:r-K,$=i-le,ne=I||A?k.top+le:k.bottom,se=I?A?k.top+le:k.bottom:k.top+le;ie=Jn(x,S,Q,$,q,$,k.left,ne,k.right,se);break}case"left":{let K=M?le/2:le*4,Q=M||C?i+K:i-K,q=M?i-K:C?i+K:i-K,$=r+le+1,ne=C||M?k.right-le:k.left,se=C?M?k.right-le:k.left:k.right-le;ie=Jn(x,S,ne,k.top,se,k.bottom,$,Q,$,q);break}case"right":{let K=M?le/2:le*4,Q=M||C?i+K:i-K,q=M?i-K:C?i+K:i-K,$=r-le,ne=C||M?k.left+le:k.right,se=C?M?k.left+le:k.right:k.left+le;ie=Jn(x,S,$,Q,$,q,ne,k.top,se,k.bottom);break}default:}ie?u||o.start(40,j):j()}};return n.__options={...e,blockPointerEvents:t},n}var er=class extends Vt{setState(t){}update(t){}set(t,o){}notifyAll(){}};var hy=(function(e){return e.open="data-open",e.closed="data-closed",e[e.startingStyle=Wr.startingStyle]="startingStyle",e[e.endingStyle=Wr.endingStyle]="endingStyle",e.anchorHidden="data-anchor-hidden",e.side="data-side",e.align="data-align",e})({});var Mg={"data-popup-open":""};var Bg={"data-open":""},Hg={"data-closed":""},zg={"data-anchor-hidden":""},Tl={open(e){return e?Mg:null}};var Qo={open(e){return e?Bg:Hg},anchorHidden(e){return e?zg:null}},kl={...Qo,...Ha};function Pl(e){return po(19)?e:e?"true":void 0}var tr=b(z(),1),Ai=tr.createContext(void 0);function Eo(){return tr.useContext(Ai)?.direction??"ltr"}var qe=b(z(),1);var Dg=e=>({name:"arrow",options:e,async fn(t){let{x:o,y:n,placement:r,rects:i,platform:s,elements:a,middlewareData:l}=t,{element:c,padding:d=0,offsetParent:m="real"}=_t(e,t)||{};if(c==null)return{};let u=zn(d),f={x:o,y:n},p=Xo(r),g=Ko(p),h=await s.getDimensions(c),y=p==="y",_=y?"top":"left",v=y?"bottom":"right",w=y?"clientHeight":"clientWidth",R=i.reference[g]+i.reference[p]-f[p]-i.floating[g],x=f[p]-i.reference[p],S=m==="real"?await s.getOffsetParent?.(c):a.floating,E=a.floating[w]||i.floating[g];(!E||!await s.isElement?.(S))&&(E=a.floating[w]||i.floating[g]);let T=R/2-x/2,P=E/2-h[g]/2-1,N=Math.min(u[_],P),H=Math.min(u[v],P),j=N,L=E-h[g]-H,k=E/2-h[g]/2+T,I=Bn(j,k,L),C=!l.arrow&&dt(r)!=null&&k!==I&&i.reference[g]/2-(k({...Dg(e),options:[e,t]});var Al={name:"hide",async fn(e){let{width:t,height:o,x:n,y:r}=e.rects.reference,i=t===0&&o===0&&n===0&&r===0,s=await e.platform.detectOverflow(e,{elementContext:"reference"});return{data:{referenceHidden:s.top-o>=0||s.right-t>=0||s.bottom-o>=0||s.left-t>=0||i}}}};var To={sideX:"left",sideY:"top"};var Ol="--available-width",Nl="--available-height";function Ml(e,t,o){let n=e==="inline-start"||e==="inline-end";return{top:"top",right:n?o?"inline-start":"inline-end":"right",bottom:"bottom",left:n?o?"inline-end":"inline-start":"left"}[t]}function Il(e,t,o){let{rects:n,placement:r}=e;return{side:Ml(t,Ne(r),o),align:dt(r)||"center",anchor:{width:n.reference.width,height:n.reference.height},positioner:{width:n.floating.width,height:n.floating.height}}}function Bl(e){return jg(e,Sl)}function jg(e,t){let{anchor:o,positionMethod:n="absolute",side:r="bottom",sideOffset:i=0,align:s="center",alignOffset:a=0,collisionBoundary:l,collisionPadding:c=5,sticky:d=!1,arrowPadding:m=5,disableAnchorTracking:u=!1,inline:f,keepMounted:p=!1,floatingRootContext:g,mounted:h,collisionAvoidance:y,shift:_,nodeId:v,adaptiveOrigin:w,lazyFlip:R=!1,externalTree:x}=e,[S,E]=qe.useState(null);!h&&S!==null&&E(null);let T=y.side||"flip",P=y.align||"flip",N=y.fallbackAxisSide||"end",H=_?.crossAxis??!1,j=_?.rootBoundary,L=typeof o=="function"?o:void 0,k=Y(L),I=L?k:o,C=je(o),A=je(h),X=Eo()==="rtl",de=S||{top:"top",right:"right",bottom:"bottom",left:"left","inline-end":X?"left":"right","inline-start":X?"right":"left"}[r],O=s==="center"?de:`${de}-${s}`,V=c;typeof V=="number"?V={top:V,right:V,bottom:V,left:V}:V&&(V={top:V.top||0,right:V.right||0,bottom:V.bottom||0,left:V.left||0});let Z=1,ie=r==="bottom"?Z:0,K=r==="top"?Z:0,Q=r==="right"?Z:0,q=r==="left"?Z:0,$={boundary:l==="clipping-ancestors"?"clippingAncestors":l,padding:V},ne=qe.useRef(null),se=je(i),ze=je(a),ae=typeof i!="function"?i:0,ge=typeof a!="function"?a:0,be=[];f&&be.push(f),be.push(ui(te=>{let Je=Il(te,r,X),pt=typeof se.current=="function"?se.current(Je):se.current,Ue=typeof ze.current=="function"?ze.current(Je):ze.current;return{mainAxis:pt,crossAxis:Ue,alignmentAxis:Ue}},[ae,ge,X,r]));let Ee=P==="none"&&T!=="shift",ye=!Ee&&(d||H||T==="shift"),Kt=T==="none"?null:mi({...$,padding:{top:V.top+Z+ie,right:V.right+Z+q,bottom:V.bottom+Z+K,left:V.left+Z+Q},mainAxis:!H&&T==="flip",crossAxis:P==="flip"?"alignment":!1,fallbackAxisSideDirection:N}),rt=Ee?null:fi({...$,rootBoundary:j,mainAxis:P!=="none",crossAxis:ye,limiter:d||H?void 0:pi(te=>{if(!ne.current)return{};let{width:Je,height:pt}=ne.current.getBoundingClientRect(),Ue=Fe(Ne(te.placement)),Tt=Ue==="y"?Je:pt,mt=Ue==="y"?V.left+V.right:V.top+V.bottom;return{offset:Tt/2+mt/2}})},[$,d,H,j,V,P]);T==="shift"||P==="shift"||s==="center"?be.push(rt,Kt):be.push(Kt,rt),be.push(gi({...$,apply({elements:{floating:te},availableWidth:Je,availableHeight:pt,rects:Ue}){if(!A.current)return;let Tt=te.style;Tt.setProperty(Ol,`${Je}px`),Tt.setProperty(Nl,`${pt}px`);let mt=fe(te).devicePixelRatio||1,{x:Mo,y:wn,width:vn,height:Cr}=Ue.reference,Ar=(Math.round((Mo+vn)*mt)-Math.round(Mo*mt))/mt,Or=(Math.round((wn+Cr)*mt)-Math.round(wn*mt))/mt;Tt.setProperty("--anchor-width",`${Ar}px`),Tt.setProperty("--anchor-height",`${Or}px`)}}),Cl(te=>({element:ne.current||Pe(te.elements.floating).createElement("div"),padding:m,offsetParent:"floating"}),[m]),{name:"transformOrigin",fn(te){let{elements:Je,middlewareData:pt,placement:Ue,rects:Tt,y:mt}=te,Mo=Ne(Ue),wn=Fe(Mo),vn=ne.current,Cr=pt.arrow?.x||0,Ar=pt.arrow?.y||0,Or=vn?.clientWidth||0,Yf=vn?.clientHeight||0,Nr=Cr+Or/2,la=Ar+Yf/2,Uf=Math.abs(pt.shift?.y||0),Gf=Tt.reference.height/2,Bo=typeof i=="function"?i(Il(te,r,X)):i,Kf=Uf>Bo,Xf={top:`${Nr}px calc(100% + ${Bo}px)`,bottom:`${Nr}px ${-Bo}px`,left:`calc(100% + ${Bo}px) ${la}px`,right:`${-Bo}px ${la}px`}[Mo],qf=`${Nr}px ${Tt.reference.y+Gf-mt}px`;return Je.floating.style.setProperty("--transform-origin",ye&&wn==="y"&&Kf?qf:Xf),{}}},Al,w),F(()=>{!h&&g&&g.update({referenceElement:null,floatingElement:null,domReferenceElement:null,positionReference:null})},[h,g]);let ft=qe.useMemo(()=>({elementResize:!u&&typeof ResizeObserver<"u",layoutShift:!u&&typeof IntersectionObserver<"u"}),[u]),{refs:Ot,elements:xe,x:fn,y:B,middlewareData:D,update:Se,placement:Ae,context:Nt,isPositioned:it,floatingStyles:It}=t({rootContext:g,open:p?h:void 0,placement:O,middleware:be,strategy:n,whileElementsMounted:p?void 0:(...te)=>qo(...te,ft),nodeId:v,externalTree:x}),{sideX:Ye,sideY:uo}=D.adaptiveOrigin||To,Xt=it?n:"fixed",pn=qe.useMemo(()=>{let te;return it?w?te={position:Xt,[Ye]:fn,[uo]:B}:te={...It,position:Xt}:te={position:Xt,top:0,left:0},te[Ol]="100vw",te[Nl]="100vh",it||(te.opacity=0),te},[w,Xt,Ye,fn,uo,B,It,it]),fo=qe.useRef(null);F(()=>{if(!h)return;let te=C.current,Je=typeof te=="function"?te():te,Ue=(Ll(Je)?Je.current:Je)||null||null;Ue!==fo.current&&(Ot.setPositionReference(Ue),fo.current=Ue)},[h,Ot,I,C]),qe.useEffect(()=>{if(!h)return;let te=C.current;typeof te!="function"&&Ll(te)&&te.current!==fo.current&&(Ot.setPositionReference(te.current),fo.current=te.current)},[h,Ot,I,C]),qe.useEffect(()=>{if(p&&h&&xe.reference&&xe.floating)return qo(xe.reference,xe.floating,Se,ft)},[p,h,xe,Se,ft]);let Lt=Ne(Ae),mn=Ml(r,Lt,X),gn=dt(Ae)||"center",bn=!!D.hide?.referenceHidden;F(()=>{R&&h&&it&&Lt!==de&&E(Lt)},[R,h,it,Lt,de]);let hn=qe.useMemo(()=>({position:"absolute",top:D.arrow?.y,left:D.arrow?.x}),[D.arrow]),ca=D.arrow?.centerOffset!==0;return qe.useMemo(()=>({positionerStyles:pn,arrowStyles:hn,arrowRef:ne,arrowUncentered:ca,side:mn,align:gn,physicalSide:Lt,anchorHidden:bn,refs:Ot,context:Nt,isPositioned:it,update:Se}),[pn,hn,ne,ca,mn,gn,Lt,bn,Ot,Nt,it,Se])}function Ll(e){return e!=null&&"current"in e}function or(e){return e==="starting"?fc:me}function Hl(e,t,{styles:o,transitionStatus:n,props:r,refs:i,hidden:s,inert:a=!1}){let l={...o};return a&&(l.pointerEvents="none"),Oe("div",e,{state:t,ref:i,props:[{role:"presentation",hidden:s,style:l},or(n),r],stateAttributesMapping:Qo})}var zl=b(z(),1);var Oi=zl.forwardRef(function(t,o){let{render:n,className:r,disabled:i=!1,focusableWhenDisabled:s=!1,nativeButton:a=!0,style:l,...c}=t,{getButtonProps:d,buttonRef:m}=Ya({disabled:i,focusableWhenDisabled:s,native:a});return Oe("button",t,{state:{disabled:i},ref:[o,m],props:[c,d]})});var Ce=b(z(),1),Kl=b(Ht(),1);var Dl=b(z(),1);function jl(e){let[t,o]=Dl.useState({current:e,previous:null});return Object.is(e,t.current)||o({current:e,previous:t.current}),t.previous}var ko=b(z(),1);function Ni(e){let t=Le(e),o=parseFloat(t.width)||0,n=parseFloat(t.height)||0,r=he(e),i=r?e.offsetWidth:o,s=r?e.offsetHeight:n;return(jt(o)!==i||jt(n)!==s)&&(o=i,n=s),{width:o,height:n}}function Vl(e){let{popupElement:t,positionerElement:o,content:n,mounted:r,onMeasureLayout:i,onMeasureLayoutComplete:s,side:a,direction:l}=e,c=vo(t,!0),d=bo(),m=ko.useRef(null),u=ko.useRef(!0),f=ko.useRef(Ge),p=Y(i),g=Y(s),h=ko.useMemo(()=>Fg(a,l),[a,l]);F(()=>{if(!r){f.current=Ge,u.current=!0,m.current=null;return}if(!t||!o)return;f.current=Fl(t,h),Ii(t,"auto");let y=rr(t,"position","static"),_=rr(t,"transform","none"),v=rr(t,"scale","1"),w=Fl(o,{"--available-width":"max-content","--available-height":"max-content"});function R(){y(),_(),w()}function x(){R(),v()}if(p?.(),u.current||m.current===null){nr(o,"max-content");let P=Ni(t);return m.current=P,nr(o,P),x(),g?.(null,P),u.current=!1,()=>{f.current(),f.current=Ge}}nr(o,"max-content");let S=m.current,E=Ni(t);m.current=E,Ii(t,S),x(),g?.(S,E),nr(o,E);let T=new AbortController;return d.request(()=>{Ii(t,E),c(()=>{t.style.setProperty("--popup-width","auto"),t.style.setProperty("--popup-height","auto")},T.signal)}),()=>{T.abort(),d.cancel(),f.current(),f.current=Ge}},[n,t,o,c,d,r,p,g,h])}function Fg(e,t){let o=e==="top",n=e==="left"||e===(t==="rtl"?"inline-end":"inline-start");return!o&&!n?me:{position:"absolute",[o?"bottom":"top"]:"0",[n?"right":"left"]:"0"}}function rr(e,t,o){let n=e.style.getPropertyValue(t);return e.style.setProperty(t,o),()=>{e.style.setProperty(t,n)}}function Fl(e,t){let o=[];for(let[n,r]of Object.entries(t))o.push(rr(e,n,r));return o.length?()=>{o.forEach(n=>n())}:Ge}function Ii(e,t){let o=t==="auto"?"auto":`${t.width}px`,n=t==="auto"?"auto":`${t.height}px`;e.style.setProperty("--popup-width",o),e.style.setProperty("--popup-height",n)}function nr(e,t){let o=t==="max-content"?"max-content":`${t.width}px`,n=t==="max-content"?"max-content":`${t.height}px`;e.style.setProperty("--positioner-width",o),e.style.setProperty("--positioner-height",n)}var Wl=b(z(),1);var Yl=b(W(),1),ir=function(t){let{direction:o="ltr"}=t,n=Wl.useMemo(()=>({direction:o}),[o]);return(0,Yl.jsx)(Ai.Provider,{value:n,children:t.children})};var Ul={name:"adaptiveOrigin",async fn(e){let{x:t,y:o,rects:{floating:n},elements:{floating:r},platform:i,strategy:s,placement:a}=e,l=fe(r),c=l.getComputedStyle(r);if(!(c.transitionDuration!=="0s"&&c.transitionDuration!==""))return{x:t,y:o,data:To};let m=await i.getOffsetParent?.(r),u={width:0,height:0};if(s==="fixed"&&l?.visualViewport)u={width:l.visualViewport.width,height:l.visualViewport.height};else if(m===l){let _=Pe(r);u={width:_.documentElement.clientWidth,height:_.documentElement.clientHeight}}else await i.isElement?.(m)&&(u=await i.getDimensions(m));let f=Ne(a),p=t,g=o;f==="left"&&(p=u.width-(t+n.width)),f==="top"&&(g=u.height-(o+n.height));let h=f==="left"?"right":To.sideX,y=f==="top"?"bottom":To.sideY;return{x:p,y:g,data:{sideX:h,sideY:y}}}};var Po=b(W(),1),Xl={activationDirection:e=>e?{"data-activation-direction":e}:null};function ql(e){let{store:t,side:o,children:n}=e,r=Eo(),i=t.useState("activeTriggerElement"),s=t.useState("activeTriggerId"),a=t.useState("open"),l=t.useState("payload"),c=t.useState("mounted"),d=t.useState("popupElement"),m=t.useState("positionerElement"),u=jl(a?i:null),f=Yg(s,l),p=Ce.useRef(null),[g,h]=Ce.useState(null),[y,_]=Ce.useState(null),v=Ce.useRef(null),w=Ce.useRef(null),R=vo(v,!0),x=bo(),S=Ce.useRef(null),[E,T]=Ce.useState(null),[P,N]=Ce.useState(!1);F(()=>(t.set("adaptiveOrigin",Ul),()=>{t.set("adaptiveOrigin",void 0)}),[t]);let H=Y(()=>{v.current?.style.setProperty("animation","none"),v.current?.style.setProperty("transition","none"),w.current?.style.setProperty("display","none")}),j=Y(M=>{v.current?.style.removeProperty("animation"),v.current?.style.removeProperty("transition"),w.current?.style.removeProperty("display"),M&&T(M)}),L=Y(()=>{S.current?.abort();let M=new AbortController;S.current=M,R(()=>{h(null),T(null),p.current=null},M.signal)}),k=Ce.useRef(null);F(()=>{(!a||!c)&&(k.current=null)},[a,c]),F(()=>{if(i&&u&&i!==u&&k.current!==i&&p.current){h(p.current),N(!0);let M=Wg(u,i);_(M),k.current=i}},[i,u]),F(()=>{g!=null&&(S.current?.abort(),N(!0),x.request(()=>{Kl.flushSync(()=>{N(!1)}),L()}))},[f,g,L,x]),F(()=>{let M=v.current;if(!M)return;let X=Pe(M).createElement("div");for(let de of Array.from(M.childNodes))X.appendChild(de.cloneNode(!0));p.current=X});let I=g!=null,C;I?C=(0,Po.jsxs)(Ce.Fragment,{children:[(0,Po.jsx)("div",{"data-previous":!0,inert:Pl(!0),ref:w,style:{...E?{"--popup-width":`${E.width}px`,"--popup-height":`${E.height}px`}:null,position:"absolute"},"data-ending-style":P?void 0:""},"previous"),(0,Po.jsx)("div",{"data-current":!0,ref:v,"data-starting-style":P?"":void 0,children:n},f)]}):C=(0,Po.jsx)("div",{"data-current":!0,ref:v,children:n},f),F(()=>{let M=w.current;!M||!g||M.replaceChildren(...Array.from(g.childNodes))},[g]),Vl({popupElement:d,positionerElement:m,mounted:c,content:l,onMeasureLayout:H,onMeasureLayoutComplete:j,side:o,direction:r});let A={activationDirection:Vg(y),transitioning:I};return{children:C,state:A}}function Vg(e){if(e)return`${Gl(e.horizontal,5,"right","left")} ${Gl(e.vertical,5,"down","up")}`}function Gl(e,t,o,n){return e>t?o:e<-t?n:""}function Wg(e,t){let o=e.getBoundingClientRect(),n=t.getBoundingClientRect(),r={x:o.left+o.width/2,y:o.top+o.height/2},i={x:n.left+n.width/2,y:n.top+n.height/2};return{horizontal:i.x-r.x,vertical:i.y-r.y}}function Yg(e,t){let[o,n]=Ce.useState(0),r=Ce.useRef(e),i=Ce.useRef(t),s=Ce.useRef(!1);return F(()=>{let a=r.current,l=i.current,c=e!==a,d=t!==l;c?(n(m=>m+1),s.current=!d):s.current&&d&&(n(m=>m+1),s.current=!1),r.current=e,i.current=t},[e,t]),`${e??"current"}-${o}`}var sr=b(z(),1),Zl=b(Ht(),1);var Ql=b(W(),1),Jl=sr.forwardRef(function(t,o){let{children:n,container:r,className:i,render:s,style:a,...l}=t,{node:c,subtree:d}=bc({container:r,ref:o,componentProps:t,elementProps:l});return!d&&!c?null:(0,Ql.jsxs)(sr.Fragment,{children:[d,c&&Zl.createPortal(n,c)]})});var tt={};Mt(tt,{Arrow:()=>hd,Handle:()=>$o,Popup:()=>gd,Portal:()=>ud,Positioner:()=>pd,Provider:()=>vd,Root:()=>rd,Trigger:()=>cd,Viewport:()=>yd,createHandle:()=>xd});var Co=b(z(),1);var ar=b(z(),1),Li=ar.createContext(void 0);function et(e){let t=ar.useContext(Li);if(t===void 0&&!e)throw new Error(De(72));return t}var $l=b(z(),1);var ed={..._l,disabled:e=>e.disabled,instantType:e=>e.instantType,isInstantPhase:e=>e.isInstantPhase,trackCursorAxis:e=>e.trackCursorAxis,disableHoverablePopup:e=>e.disableHoverablePopup,lastOpenChangeReason:e=>e.openChangeReason,closeOnClick:e=>e.closeOnClick,closeDelay:e=>e.closeDelay,adaptiveOrigin:e=>e.adaptiveOrigin},cr=class extends Vt{constructor(t,o,n){let r=new io;super(od(t,r,o,n),nd(r),ed)}setOpen=(t,o)=>{dl(this,t,o,{extraState:{openChangeReason:o.reason}})};cancelPendingOpen(t){this.state.floatingRootContext.dispatchOpenChange(!1,ee(G.triggerPress,t))}};function td(){let e=new io,t=new er(Object.freeze(od(void 0,e)),Object.freeze(nd(e)),ed);return Object.assign(t,{setOpen:Ge,cancelPendingOpen:Ge})}function od(e,t,o,n=!1){let r={...hl(),disabled:!1,instantType:void 0,isInstantPhase:!1,trackCursorAxis:"none",disableHoverablePopup:!1,openChangeReason:null,closeOnClick:!0,closeDelay:0,adaptiveOrigin:void 0,...e};return r.floatingRootContext=wl(t,o,n),r}function nd(e){return{popupRef:$l.createRef(),onOpenChange:void 0,onOpenChangeComplete:void 0,triggerElements:e}}var Jo=b(W(),1),rd=vi(function(t){let{disabled:o=!1,defaultOpen:n=!1,open:r,disableHoverablePopup:i=!1,trackCursorAxis:s="none",actionsRef:a,onOpenChange:l,onOpenChangeComplete:c,handle:d,triggerId:m,defaultTriggerId:u=null,children:f}=t,p=cl((N,H)=>new cr({open:n,openProp:r,activeTriggerId:u,triggerIdProp:m},N,H));p.useControlledProp("openProp",r),p.useControlledProp("triggerIdProp",m),p.useContextCallback("onOpenChange",l),p.useContextCallback("onOpenChangeComplete",c);let g=p.useState("open"),h=!o&&g,y=p.useState("activeTriggerId"),_=p.useState("mounted"),v=p.useState("payload");p.useSyncedValues({trackCursorAxis:s,disableHoverablePopup:i,disabled:o}),fl(p,{closeOnActiveTriggerUnmount:!0});let{forceUnmount:w,transitionStatus:R}=pl(h,p),x=p.useState("isInstantPhase"),S=p.useState("instantType"),E=p.useState("lastOpenChangeReason"),T=Co.useRef(null);F(()=>{g&&o&&p.setOpen(!1,ee(G.disabled))},[g,o,p]),F(()=>{R==="ending"&&E===G.none||R!=="ending"&&x?(S!=="delay"&&(T.current=S),p.set("instantType","delay")):T.current!==null&&(p.set("instantType",T.current),T.current=null)},[R,x,E,S,p]),F(()=>{h&&y==null&&p.set("payload",void 0)},[p,y,h]),Co.useImperativeHandle(a,()=>({unmount:w,close:()=>p.setOpen(!1,ee(G.imperativeAction))}),[w,p]);let P=h||_||!o&&s!=="none";return(0,Jo.jsxs)(Li.Provider,{value:p,children:[d&&(0,Jo.jsx)(ll,{handle:d,store:p}),P&&(0,Jo.jsx)(Ug,{store:p,disabled:o,trackCursorAxis:s}),typeof f=="function"?f({payload:v}):f]})});function Ug({store:e,disabled:t,trackCursorAxis:o}){let n=e.useState("floatingRootContext"),r=si(n,{enabled:!t,referencePress:()=>e.select("closeOnClick")}),i=ii(n,{enabled:!t&&o!=="none",axis:o==="none"?void 0:o}),s=Co.useMemo(()=>ve(i.reference,r.reference),[i.reference,r.reference]);return ml(e,{activeTriggerProps:s,inactiveTriggerProps:s,popupProps:r.floating??me}),null}var dr=b(z(),1);var lr=b(z(),1),Mi=lr.createContext(void 0);function id(){return lr.useContext(Mi)}var ad="data-base-ui-tooltip-trigger";function sd(e){if("composedPath"in e){let o=e.composedPath();for(let n=0;nh.select("transitionStatus")==="ending",shouldOpen(){return!X.current}}),Q=Ri(w,{enabled:!I}).reference,q=ae=>{let ge=X.current,be=sd(ae),Ee=ie(be),ye=R.current,Kt=ye&&be&&re(ye,be);if(Ee&&h.select("open")&&h.select("lastOpenChangeReason")===G.triggerHover){h.setOpen(!1,ee(G.triggerHover,ae));return}if(ge&&!Ee&&Kt&&!C.current&&!h.select("open")&&ye&&Pt(O.current)){let rt=()=>{!X.current&&!C.current&&!h.select("open")&&h.setOpen(!0,ee(G.triggerHover,ae,ye))},ft=V();ft===0?(de.clear(),rt()):de.start(ft,rt)}},$=h.useState("triggerProps",T);return Oe("button",t,{state:{open:v},ref:[o,E,R],props:[K,Q,T||A!=="none"?$:void 0,{onMouseOver(ae){q(ae.nativeEvent)},onFocus(ae){Z(sd(ae.nativeEvent))&&ae.preventBaseUIHandler()},onMouseLeave(){X.current=!1,de.clear(),O.current=void 0},onPointerEnter(ae){O.current=ae.pointerType},onPointerDown(ae){O.current=ae.pointerType,h.set("closeOnClick",d),d&&!h.select("open")&&h.cancelPendingOpen(ae.nativeEvent)},onClick(ae){d&&!h.select("open")&&h.cancelPendingOpen(ae.nativeEvent)},id:y,"data-trigger-disabled":I?"":void 0,[ad]:I?void 0:""},f],stateAttributesMapping:Tl})});var dd=b(z(),1);var ur=b(z(),1),Bi=ur.createContext(void 0);function ld(){let e=ur.useContext(Bi);if(e===void 0)throw new Error(De(70));return e}var Hi=b(W(),1),ud=dd.forwardRef(function(t,o){let{keepMounted:n=!1,...r}=t;return et().useState("mounted")||n?(0,Hi.jsx)(Bi.Provider,{value:n,children:(0,Hi.jsx)(Jl,{ref:o,...r})}):null});var pr=b(z(),1);var fr=b(z(),1),zi=fr.createContext(void 0);function Ao(){let e=fr.useContext(zi);if(e===void 0)throw new Error(De(71));return e}var fd=b(W(),1),pd=pr.forwardRef(function(t,o){let{render:n,className:r,anchor:i,positionMethod:s="absolute",side:a="top",align:l="center",sideOffset:c=0,alignOffset:d=0,collisionBoundary:m="clipping-ancestors",collisionPadding:u=5,arrowPadding:f=5,sticky:p=!1,disableAnchorTracking:g=!1,collisionAvoidance:h=pc,style:y,..._}=t,v=et(),w=ld(),R=v.useState("open"),x=v.useState("mounted"),S=v.useState("trackCursorAxis"),E=v.useState("disableHoverablePopup"),T=v.useState("floatingRootContext"),P=v.useState("instantType"),N=v.useState("transitionStatus"),H=v.useState("adaptiveOrigin"),j=Bl({anchor:i,positionMethod:s,floatingRootContext:T,mounted:x,side:a,sideOffset:c,align:l,alignOffset:d,collisionBoundary:m,collisionPadding:u,sticky:p,arrowPadding:f,disableAnchorTracking:g,keepMounted:w,collisionAvoidance:h,adaptiveOrigin:H}),L=pr.useMemo(()=>({open:R,side:j.side,align:j.align,anchorHidden:j.anchorHidden,instant:S!=="none"?"tracking-cursor":P}),[R,j.side,j.align,j.anchorHidden,S,P]),k=Hl(t,L,{styles:j.positionerStyles,transitionStatus:N,props:_,refs:[o,v.useStateSetter("positionerElement")],hidden:!x,inert:!R||S==="both"||E});return(0,fd.jsx)(zi.Provider,{value:j,children:k})});var md=b(z(),1);var gd=md.forwardRef(function(t,o){let{render:n,className:r,style:i,...s}=t,a=et(),{side:l,align:c}=Ao(),d=a.useState("open"),m=a.useState("instantType"),u=a.useState("transitionStatus"),f=a.useState("popupProps"),p=a.useState("floatingRootContext"),g=a.useState("disabled"),h=a.useState("closeDelay");On({open:d,ref:a.context.popupRef,onComplete(){d&&a.context.onOpenChangeComplete?.(!0)}}),ki(p,{enabled:!g,closeDelay:h});let y=a.useStateSetter("popupElement");return Oe("div",t,{state:{open:d,side:l,align:c,instant:m,transitionStatus:u},ref:[o,a.context.popupRef,y],props:[al,f,or(u),s],stateAttributesMapping:kl})});var bd=b(z(),1);var hd=bd.forwardRef(function(t,o){let{render:n,className:r,style:i,...s}=t,a=et(),{arrowRef:l,side:c,align:d,arrowUncentered:m,arrowStyles:u}=Ao(),f=a.useState("open"),p=a.useState("instantType");return Oe("div",t,{state:{open:f,side:c,align:d,uncentered:m,instant:p},ref:[o,l],props:[{style:u,"aria-hidden":!0},s],stateAttributesMapping:Qo})});var wd=b(z(),1);var Di=b(W(),1),vd=function(t){let{delay:o,closeDelay:n,timeout:r=400}=t,i=wd.useMemo(()=>({open:o,close:n}),[o,n]);return(0,Di.jsx)(Mi.Provider,{value:o,children:(0,Di.jsx)(ni,{delay:i,timeoutMs:r,children:t.children})})};var _d=b(z(),1);var yd=_d.forwardRef(function(t,o){let{render:n,className:r,style:i,children:s,...a}=t,l=et(),c=Ao(),d=l.useState("instantType"),{children:m,state:u}=ql({store:l,side:c.side,children:s}),f={activationDirection:u.activationDirection,transitioning:u.transitioning,instant:d};return Oe("div",t,{state:f,ref:o,props:[a,{children:m}],stateAttributesMapping:Xl})});var $o=class extends Yn{constructor(){super(td(),"Tooltip")}open(t){this.openByTrigger(t)}close(){this.closePopup()}get isOpen(){return this.attachedStore?.select("open")??!1}};function xd(){return new $o}function ot(e){return Oe(e.defaultTagName??"div",e,e)}var Ed=b(ce(),1),ji="data-wp-hash";function Fi(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&qg(document)),e.__wpStyleRuntime}function Xg(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${ji}]`))if(o.getAttribute(ji)===t)return!0;return!1}function Td(e,t,o){if(!e.head)return;let n=Fi(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Xg(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(ji,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function qg(e){let t=Fi();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Td(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function kd(e,t){let o=Fi();o.styles.set(e,t);for(let n of o.documents.keys())Td(n,e,t)}typeof process>"u",kd("a495f9d138",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._83ed8a8da5dd50ea__text{margin:0}._14437cfb77831647__heading-2xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-2xl,32px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-2xl,32px);--_gcd-p-line-height:var(--wpds-typography-line-height-2xl,40px);font-size:var(--wpds-typography-font-size-2xl,32px);line-height:var(--wpds-typography-line-height-2xl,40px)}._14437cfb77831647__heading-2xl,._3c78b7fa9b4072dd__heading-xl{font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-emphasis,600)}._3c78b7fa9b4072dd__heading-xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-p-line-height:var(--wpds-typography-line-height-md,24px);font-size:var(--wpds-typography-font-size-xl,20px);line-height:var(--wpds-typography-line-height-md,24px)}.aa58f227716bcde2__heading-lg{--_gcd-heading-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-lg,15px)}.aa58f227716bcde2__heading-lg,.fc4da56d8dfe52c4__heading-md{font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:var(--wpds-typography-line-height-sm,20px)}.fc4da56d8dfe52c4__heading-md{--_gcd-heading-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-md,13px)}.a9b78c7c82e8dff7__heading-sm{--_gcd-heading-font-size:var(--wpds-typography-font-size-xs,11px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-xs,11px);--_gcd-p-line-height:var(--wpds-typography-line-height-xs,16px);font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-xs,11px);font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:var(--wpds-typography-line-height-xs,16px);text-transform:uppercase}._305ff559e52180d5__body-xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-p-line-height:var(--wpds-typography-line-height-xl,32px);font-size:var(--wpds-typography-font-size-xl,20px);line-height:var(--wpds-typography-line-height-xl,32px)}._305ff559e52180d5__body-xl,.ca1aa3fc2029e958__body-lg{font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-default,400)}.ca1aa3fc2029e958__body-lg{--_gcd-heading-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-p-line-height:var(--wpds-typography-line-height-md,24px);font-size:var(--wpds-typography-font-size-lg,15px);line-height:var(--wpds-typography-line-height-md,24px)}._131101940be12424__body-md{--_gcd-heading-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-md,13px);line-height:var(--wpds-typography-line-height-sm,20px)}._0e8d87a42c1f75fa__body-sm,._131101940be12424__body-md{font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-default,400)}._0e8d87a42c1f75fa__body-sm{--_gcd-heading-font-size:var(--wpds-typography-font-size-sm,12px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-sm,12px);--_gcd-p-line-height:var(--wpds-typography-line-height-xs,16px);font-size:var(--wpds-typography-font-size-sm,12px);line-height:var(--wpds-typography-line-height-xs,16px)}}}');var Sd={text:"_83ed8a8da5dd50ea__text","heading-2xl":"_14437cfb77831647__heading-2xl","heading-xl":"_3c78b7fa9b4072dd__heading-xl","heading-lg":"aa58f227716bcde2__heading-lg","heading-md":"fc4da56d8dfe52c4__heading-md","heading-sm":"a9b78c7c82e8dff7__heading-sm","body-xl":"_305ff559e52180d5__body-xl","body-lg":"ca1aa3fc2029e958__body-lg","body-md":"_131101940be12424__body-md","body-sm":"_0e8d87a42c1f75fa__body-sm"};typeof process>"u",kd("af6d9984a6","._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}");var Rd={button:"_6defc79820e382c6__button",input:"d2cff2e5dea83bd1__input",textarea:"_547d86373d02e108__textarea",div:"_8c15fd0ed9f28ba4__div",p:"_43cec3e1eec1066d__p",heading:"e97669c6d9a38497__heading",a:"_2c0831b0499dbd6e__a"},We=(0,Ed.forwardRef)(function({variant:t="body-md",render:o,className:n,...r},i){return ot({render:o,defaultTagName:"span",ref:i,props:ve(r,{className:J(Sd.text,Rd.heading,Rd.p,Sd[t],n)})})});var Od=b(W(),1),Vi="data-wp-hash";function Wi(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Qg(document)),e.__wpStyleRuntime}function Zg(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Vi}]`))if(o.getAttribute(Vi)===t)return!0;return!1}function Ad(e,t,o){if(!e.head)return;let n=Wi(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Zg(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Vi,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Qg(e){let t=Wi();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Ad(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Jg(e,t){let o=Wi();o.styles.set(e,t);for(let n of o.documents.keys())Ad(n,e,t)}typeof process>"u",Jg("9db2873e7f","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._96e6251aad1a6136__badge{border-radius:var(--wpds-border-radius-lg,8px);padding-block:var(--wpds-dimension-padding-xs,4px);padding-inline:var(--wpds-dimension-padding-sm,8px)}._99f7158cb520f750__is-high-intent{background-color:var(--wpds-color-background-surface-error,#f6e6e3);color:var(--wpds-color-foreground-content-error,#470000)}.c20ebef2365bc8b7__is-medium-intent{background-color:var(--wpds-color-background-surface-warning,#fde6be);color:var(--wpds-color-foreground-content-warning,#2e1900)}._365e1626c6202e52__is-low-intent{background-color:var(--wpds-color-background-surface-caution,#fee995);color:var(--wpds-color-foreground-content-caution,#281d00)}._33f8198127ddf4ef__is-stable-intent{background-color:var(--wpds-color-background-surface-success,#c6f7cd);color:var(--wpds-color-foreground-content-success,#002900)}._04c1aca8fc449412__is-informational-intent{background-color:var(--wpds-color-background-surface-info,#deebfa);color:var(--wpds-color-foreground-content-info,#001b4f)}._90726e69d495ec19__is-draft-intent{background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);color:var(--wpds-color-foreground-content-neutral,#1e1e1e)}._898f4a544993bd39__is-none-intent{background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);padding-block:calc(var(--wpds-dimension-padding-xs, 4px) - var(--wpds-border-width-xs, 1px));padding-inline:calc(var(--wpds-dimension-padding-sm, 8px) - var(--wpds-border-width-xs, 1px))}}}");var Pd={badge:"_96e6251aad1a6136__badge","is-high-intent":"_99f7158cb520f750__is-high-intent","is-medium-intent":"c20ebef2365bc8b7__is-medium-intent","is-low-intent":"_365e1626c6202e52__is-low-intent","is-stable-intent":"_33f8198127ddf4ef__is-stable-intent","is-informational-intent":"_04c1aca8fc449412__is-informational-intent","is-draft-intent":"_90726e69d495ec19__is-draft-intent","is-none-intent":"_898f4a544993bd39__is-none-intent"},Yi=(0,Cd.forwardRef)(function({intent:t="none",className:o,...n},r){return(0,Od.jsx)(We,{ref:r,className:J(Pd.badge,Pd[`is-${t}-intent`],o),...n,variant:"body-sm"})});var mr=b(ce(),1),Nd=b(st(),1),Ld=b(W(),1);import{speak as $g}from"@wordpress/a11y";var Ui="data-wp-hash";function Gi(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&tb(document)),e.__wpStyleRuntime}function eb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Ui}]`))if(o.getAttribute(Ui)===t)return!0;return!1}function Id(e,t,o){if(!e.head)return;let n=Gi(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(eb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Ui,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function tb(e){let t=Gi();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Id(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function gr(e,t){let o=Gi();o.styles.set(e,t);for(let n of o.documents.keys())Id(n,e,t)}typeof process>"u",gr("effc4e3032",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._97b0fc33c028be1a__button,.abbb272e2ce49bd6__is-unstyled{appearance:none;padding:0}._97b0fc33c028be1a__button{--wp-ui-button-font-weight:var(--wpds-typography-font-weight-emphasis,600);--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-strong,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-strong-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 93%,#000));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand-strong,#fff);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-strong-active,#fff);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-strong-disabled,#8d8d8d);--wp-ui-button-padding-block:var(--wpds-dimension-padding-xs,4px);--wp-ui-button-padding-inline:var(--wpds-dimension-padding-md,12px);--wp-ui-button-height:var(--wpds-dimension-size-lg,40px);--wp-ui-button-aspect-ratio:auto;--wp-ui-button-font-size:var(--wpds-typography-font-size-md,13px);--wp-ui-button-min-width:calc(4ch + var(--wp-ui-button-padding-inline)*2);--wp-ui-button-icon-margin:calc((var(--wpds-dimension-size-2xs, 16px) - var(--wpds-dimension-size-sm, 24px))/2);--wp-ui-button-border-color:var(--wp-ui-button-background-color);--wp-ui-button-border-color-active:var(--wp-ui-button-background-color-active);--wp-ui-button-border-color-disabled:var(--wp-ui-button-background-color-disabled);--_gcd-button-font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);--_gcd-button-font-size:var(--wp-ui-button-font-size);--_gcd-button-font-weight:var(--wp-ui-button-font-weight);align-items:center;aspect-ratio:var(--wp-ui-button-aspect-ratio);background-clip:border-box;background-color:var(--wp-ui-button-background-color);border-color:var(--wp-ui-button-border-color);border-radius:var(--wpds-border-radius-sm,2px);border-style:solid;border-width:1px;color:var(--wp-ui-button-foreground-color);display:inline-flex;font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wp-ui-button-font-size);font-weight:var(--wp-ui-button-font-weight);gap:var(--wpds-dimension-gap-sm,8px);justify-content:center;line-height:var(--wpds-typography-line-height-sm,20px);max-width:100%;min-height:var(--wp-ui-button-height);min-width:var(--wp-ui-button-min-width);overflow-wrap:anywhere;padding-block:var(--wp-ui-button-padding-block);padding-inline:var(--wp-ui-button-padding-inline);position:relative;text-align:center;text-decoration:none;&:not([data-disabled]){cursor:var(--wpds-cursor-control,pointer)}@media not (prefers-reduced-motion){transition:color .1s ease-out;*{transition:opacity .1s ease-out}}&[href]{cursor:pointer}[href]{color:inherit;text-decoration:inherit}&:not([data-disabled]):is(:hover,:active,:focus){background-color:var(--wp-ui-button-background-color-active);border-color:var(--wp-ui-button-border-color-active);color:var(--wp-ui-button-foreground-color-active)}&[data-disabled]:not(._914b42f315c0e580__is-loading){background-color:var(--wp-ui-button-background-color-disabled);border-color:var(--wp-ui-button-border-color-disabled);color:var(--wp-ui-button-foreground-color-disabled);@media (forced-colors:active){border-bottom-color:GrayText;border-left-color:GrayText;border-right-color:GrayText;border-top-color:GrayText;color:GrayText}}&:before{aspect-ratio:1;border:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid;border-block-end-color:transparent;border-block-start-color:var(--wp-ui-button-foreground-color);border-inline-end-color:var(--wp-ui-button-foreground-color);border-inline-start-color:transparent;border-radius:50%;box-sizing:border-box;content:"";display:block;height:var(--wp-ui-button-font-size);left:50%;opacity:0;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);@media not (prefers-reduced-motion){transition:opacity .1s ease-out}@media (forced-colors:active){border-block-end-style:none;border-bottom-color:ButtonText;border-inline-start-style:none;border-left-color:ButtonText;border-right-color:ButtonText;border-top-color:ButtonText}}}._908205475f9f2a92__is-small{--wp-ui-button-padding-block:0px;--wp-ui-button-padding-inline:var(--wpds-dimension-padding-sm,8px);--wp-ui-button-height:var(--wpds-dimension-size-sm,24px)}._9f6fc6553aeb36fe__icon{margin:var(--wp-ui-button-icon-margin)}.dd460c965226cc77__is-brand{&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 85%,#000));--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-brand-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000)}}.e722a8f96726aa99__is-neutral{&.ad0619a3217c6a5b__is-minimal[aria-pressed=true],&.b50b3358c5fb4d0b__is-solid{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-strong,#2d2d2d);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-strong-active,#1e1e1e);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral-strong,#f0f0f0);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-strong-active,#f0f0f0);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-strong-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d);--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-neutral-active,#6e6e6e);--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-neutral-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000)}}.abbb272e2ce49bd6__is-unstyled{background:none;border:none;min-width:unset}.cf59cf1b69629838__is-compact{--wp-ui-button-height:var(--wpds-dimension-size-md,32px)}._914b42f315c0e580__is-loading:not(.abbb272e2ce49bd6__is-unstyled){color:transparent;&:not([data-disabled]):is(:hover,:active,:focus){color:transparent}@media (forced-colors:active){color:ButtonFace}*{opacity:0}&:before{opacity:1;transition-delay:.05s;@media not (prefers-reduced-motion){animation:_5a1d53da6f830c8d__loading-animation 1s linear infinite}}}}@keyframes _5a1d53da6f830c8d__loading-animation{0%{transform:translate(-50%,-50%) rotate(0deg)}to{transform:translate(-50%,-50%) rotate(1turn)}}}');var en={button:"_97b0fc33c028be1a__button","is-unstyled":"abbb272e2ce49bd6__is-unstyled","is-loading":"_914b42f315c0e580__is-loading","is-small":"_908205475f9f2a92__is-small",icon:"_9f6fc6553aeb36fe__icon","is-brand":"dd460c965226cc77__is-brand","is-outline":"_62d5a778b7b258ee__is-outline","is-minimal":"ad0619a3217c6a5b__is-minimal","is-neutral":"e722a8f96726aa99__is-neutral","is-solid":"b50b3358c5fb4d0b__is-solid","is-compact":"cf59cf1b69629838__is-compact","loading-animation":"_5a1d53da6f830c8d__loading-animation"};typeof process>"u",gr("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var ob={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",gr("96553466c8","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._64de9947bf305b7a__outset-ring--focus-within-visible:focus-within:has(:focus-visible),.af79fb116edb0dd7__outset-ring--focus:focus,.dfcfdc28396e5d98__outset-ring--focus-visible:focus-visible,.e5cd9ee879f6403a__outset-ring--focus-within:focus-within,:focus-visible ._81935a08e952f267__outset-ring--focus-parent-visible{--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within,.abc777e9713fa711__outset-ring--focus-except-active:focus{outline:none}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within:not(:has(:active)),.abc777e9713fa711__outset-ring--focus-except-active:focus:not(:active){--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}}}");var nb={"outset-ring--focus":"af79fb116edb0dd7__outset-ring--focus","outset-ring--focus-visible":"dfcfdc28396e5d98__outset-ring--focus-visible","outset-ring--focus-within":"e5cd9ee879f6403a__outset-ring--focus-within","outset-ring--focus-within-visible":"_64de9947bf305b7a__outset-ring--focus-within-visible","outset-ring--focus-parent-visible":"_81935a08e952f267__outset-ring--focus-parent-visible","outset-ring--focus-except-active":"abc777e9713fa711__outset-ring--focus-except-active","outset-ring--focus-within-except-active":"_3c9f5ee9fc9c136d__outset-ring--focus-within-except-active"};typeof process>"u",gr("af6d9984a6","._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}");var rb={button:"_6defc79820e382c6__button",input:"d2cff2e5dea83bd1__input",textarea:"_547d86373d02e108__textarea",div:"_8c15fd0ed9f28ba4__div",p:"_43cec3e1eec1066d__p",heading:"e97669c6d9a38497__heading",a:"_2c0831b0499dbd6e__a"},Md=(0,mr.forwardRef)(function({tone:t="brand",variant:o="solid",size:n="default",className:r,focusableWhenDisabled:i=!0,disabled:s,loading:a,loadingAnnouncement:l=(0,Nd.__)("Loading"),children:c,...d},m){let u=J(rb.button,ob["box-sizing"],nb["outset-ring--focus-except-active"],o!=="unstyled"&&en.button,en[`is-${t}`],en[`is-${o}`],en[`is-${n}`],a&&en["is-loading"],r);return(0,mr.useEffect)(()=>{a&&l&&$g(l)},[a,l]),(0,Ld.jsx)(Oi,{ref:m,className:u,focusableWhenDisabled:i,disabled:s??a,...d,children:c})});var jd=b(ce(),1);var Hd=b(ce(),1),zd=b(so(),1),Dd=b(W(),1),ao=(0,Hd.forwardRef)(function({icon:t,size:o=24,...n},r){return(0,Dd.jsx)(zd.SVG,{ref:r,...t.props,...n,width:o,height:o})});var Vd=b(W(),1),Ki="data-wp-hash";function Xi(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&sb(document)),e.__wpStyleRuntime}function ib(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Ki}]`))if(o.getAttribute(Ki)===t)return!0;return!1}function Fd(e,t,o){if(!e.head)return;let n=Xi(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(ib(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Ki,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function sb(e){let t=Xi();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Fd(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function ab(e,t){let o=Xi();o.styles.set(e,t);for(let n of o.documents.keys())Fd(n,e,t)}typeof process>"u",ab("effc4e3032",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._97b0fc33c028be1a__button,.abbb272e2ce49bd6__is-unstyled{appearance:none;padding:0}._97b0fc33c028be1a__button{--wp-ui-button-font-weight:var(--wpds-typography-font-weight-emphasis,600);--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-strong,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-strong-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 93%,#000));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand-strong,#fff);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-strong-active,#fff);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-strong-disabled,#8d8d8d);--wp-ui-button-padding-block:var(--wpds-dimension-padding-xs,4px);--wp-ui-button-padding-inline:var(--wpds-dimension-padding-md,12px);--wp-ui-button-height:var(--wpds-dimension-size-lg,40px);--wp-ui-button-aspect-ratio:auto;--wp-ui-button-font-size:var(--wpds-typography-font-size-md,13px);--wp-ui-button-min-width:calc(4ch + var(--wp-ui-button-padding-inline)*2);--wp-ui-button-icon-margin:calc((var(--wpds-dimension-size-2xs, 16px) - var(--wpds-dimension-size-sm, 24px))/2);--wp-ui-button-border-color:var(--wp-ui-button-background-color);--wp-ui-button-border-color-active:var(--wp-ui-button-background-color-active);--wp-ui-button-border-color-disabled:var(--wp-ui-button-background-color-disabled);--_gcd-button-font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);--_gcd-button-font-size:var(--wp-ui-button-font-size);--_gcd-button-font-weight:var(--wp-ui-button-font-weight);align-items:center;aspect-ratio:var(--wp-ui-button-aspect-ratio);background-clip:border-box;background-color:var(--wp-ui-button-background-color);border-color:var(--wp-ui-button-border-color);border-radius:var(--wpds-border-radius-sm,2px);border-style:solid;border-width:1px;color:var(--wp-ui-button-foreground-color);display:inline-flex;font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wp-ui-button-font-size);font-weight:var(--wp-ui-button-font-weight);gap:var(--wpds-dimension-gap-sm,8px);justify-content:center;line-height:var(--wpds-typography-line-height-sm,20px);max-width:100%;min-height:var(--wp-ui-button-height);min-width:var(--wp-ui-button-min-width);overflow-wrap:anywhere;padding-block:var(--wp-ui-button-padding-block);padding-inline:var(--wp-ui-button-padding-inline);position:relative;text-align:center;text-decoration:none;&:not([data-disabled]){cursor:var(--wpds-cursor-control,pointer)}@media not (prefers-reduced-motion){transition:color .1s ease-out;*{transition:opacity .1s ease-out}}&[href]{cursor:pointer}[href]{color:inherit;text-decoration:inherit}&:not([data-disabled]):is(:hover,:active,:focus){background-color:var(--wp-ui-button-background-color-active);border-color:var(--wp-ui-button-border-color-active);color:var(--wp-ui-button-foreground-color-active)}&[data-disabled]:not(._914b42f315c0e580__is-loading){background-color:var(--wp-ui-button-background-color-disabled);border-color:var(--wp-ui-button-border-color-disabled);color:var(--wp-ui-button-foreground-color-disabled);@media (forced-colors:active){border-bottom-color:GrayText;border-left-color:GrayText;border-right-color:GrayText;border-top-color:GrayText;color:GrayText}}&:before{aspect-ratio:1;border:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid;border-block-end-color:transparent;border-block-start-color:var(--wp-ui-button-foreground-color);border-inline-end-color:var(--wp-ui-button-foreground-color);border-inline-start-color:transparent;border-radius:50%;box-sizing:border-box;content:"";display:block;height:var(--wp-ui-button-font-size);left:50%;opacity:0;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);@media not (prefers-reduced-motion){transition:opacity .1s ease-out}@media (forced-colors:active){border-block-end-style:none;border-bottom-color:ButtonText;border-inline-start-style:none;border-left-color:ButtonText;border-right-color:ButtonText;border-top-color:ButtonText}}}._908205475f9f2a92__is-small{--wp-ui-button-padding-block:0px;--wp-ui-button-padding-inline:var(--wpds-dimension-padding-sm,8px);--wp-ui-button-height:var(--wpds-dimension-size-sm,24px)}._9f6fc6553aeb36fe__icon{margin:var(--wp-ui-button-icon-margin)}.dd460c965226cc77__is-brand{&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 85%,#000));--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-brand-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000)}}.e722a8f96726aa99__is-neutral{&.ad0619a3217c6a5b__is-minimal[aria-pressed=true],&.b50b3358c5fb4d0b__is-solid{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-strong,#2d2d2d);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-strong-active,#1e1e1e);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral-strong,#f0f0f0);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-strong-active,#f0f0f0);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-strong-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d);--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-neutral-active,#6e6e6e);--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-neutral-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000)}}.abbb272e2ce49bd6__is-unstyled{background:none;border:none;min-width:unset}.cf59cf1b69629838__is-compact{--wp-ui-button-height:var(--wpds-dimension-size-md,32px)}._914b42f315c0e580__is-loading:not(.abbb272e2ce49bd6__is-unstyled){color:transparent;&:not([data-disabled]):is(:hover,:active,:focus){color:transparent}@media (forced-colors:active){color:ButtonFace}*{opacity:0}&:before{opacity:1;transition-delay:.05s;@media not (prefers-reduced-motion){animation:_5a1d53da6f830c8d__loading-animation 1s linear infinite}}}}@keyframes _5a1d53da6f830c8d__loading-animation{0%{transform:translate(-50%,-50%) rotate(0deg)}to{transform:translate(-50%,-50%) rotate(1turn)}}}');var cb={button:"_97b0fc33c028be1a__button","is-unstyled":"abbb272e2ce49bd6__is-unstyled","is-loading":"_914b42f315c0e580__is-loading","is-small":"_908205475f9f2a92__is-small",icon:"_9f6fc6553aeb36fe__icon","is-brand":"dd460c965226cc77__is-brand","is-outline":"_62d5a778b7b258ee__is-outline","is-minimal":"ad0619a3217c6a5b__is-minimal","is-neutral":"e722a8f96726aa99__is-neutral","is-solid":"b50b3358c5fb4d0b__is-solid","is-compact":"cf59cf1b69629838__is-compact","loading-animation":"_5a1d53da6f830c8d__loading-animation"},qi=(0,jd.forwardRef)(function({className:t,icon:o,...n},r){return(0,Vd.jsx)(ao,{ref:r,icon:o,className:J(cb.icon,t),size:24,...n})});qi.displayName="Button.Icon";var br=Object.assign(Md,{Icon:qi});var hr=b(so(),1),Zi=b(W(),1),Qi=(0,Zi.jsx)(hr.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,Zi.jsx)(hr.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M5.5 12a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0ZM12 4a8 8 0 1 0 0 16 8 8 0 0 0 0-16Zm-.75 12v-1.5h1.5V16h-1.5Zm0-8v5h1.5V8h-1.5Z"})});var wr=b(so(),1),Ji=b(W(),1),$i=(0,Ji.jsx)(wr.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,Ji.jsx)(wr.Path,{d:"M12 13.06l3.712 3.713 1.061-1.06L13.061 12l3.712-3.712-1.06-1.06L12 10.938 8.288 7.227l-1.061 1.06L10.939 12l-3.712 3.712 1.06 1.061L12 13.061z"})});var vr=b(so(),1),es=b(W(),1),ts=(0,es.jsx)(vr.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,es.jsx)(vr.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M12.218 5.377a.25.25 0 0 0-.436 0l-7.29 12.96a.25.25 0 0 0 .218.373h14.58a.25.25 0 0 0 .218-.372l-7.29-12.96Zm-1.743-.735c.669-1.19 2.381-1.19 3.05 0l7.29 12.96a1.75 1.75 0 0 1-1.525 2.608H4.71a1.75 1.75 0 0 1-1.525-2.608l7.29-12.96ZM12.75 17.46h-1.5v-1.5h1.5v1.5Zm-1.5-3h1.5v-5h-1.5v5Z"})});var _r=b(so(),1),os=b(W(),1),ns=(0,os.jsx)(_r.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,os.jsx)(_r.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M5.5 12a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0ZM12 4a8 8 0 1 0 0 16 8 8 0 0 0 0-16Zm.75 4v1.5h-1.5V8h1.5Zm0 8v-5h-1.5v5h1.5Z"})});var yr=b(so(),1),rs=b(W(),1),is=(0,rs.jsx)(yr.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,rs.jsx)(yr.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M12 18.5a6.5 6.5 0 1 1 0-13 6.5 6.5 0 0 1 0 13ZM4 12a8 8 0 1 1 16 0 8 8 0 0 1-16 0Zm11.53-1.47-1.06-1.06L11 12.94l-1.47-1.47-1.06 1.06L11 15.06l4.53-4.53Z"})});var yu=b(ce(),1);var cu=b(ce(),1);var Kd=b(ce(),1);var as="data-wp-hash";function cs(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&db(document)),e.__wpStyleRuntime}function lb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${as}]`))if(o.getAttribute(as)===t)return!0;return!1}function Yd(e,t,o){if(!e.head)return;let n=cs(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(lb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(as,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function db(e){let t=cs();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Yd(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function ub(e,t){let o=cs();o.styles.set(e,t);for(let n of o.documents.keys())Yd(n,e,t)}typeof process>"u",ub("be37f31c1e","._11fc52b637ff8a7e__slot{inset:0;isolation:isolate;pointer-events:none;position:fixed;z-index:1000000003}@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._11fc52b637ff8a7e__slot>*{pointer-events:auto}}}");var Wd={slot:"_11fc52b637ff8a7e__slot"},Ud="data-wp-compat-overlay-slot";function fb(){return typeof document>"u"?null:document}function pb(){let e;try{e=window.top?.wp}catch{}let t=e??window.wp;return typeof t?.components=="object"&&t.components!==null}var xt=null;function ss(e){return e.setAttribute("aria-hidden","false"),e}function mb(e){let t=e.createElement("div");return t.setAttribute(Ud,""),Wd.slot&&t.classList.add(Wd.slot),e.body.appendChild(t),t}function Gd(){if(typeof window>"u"||!pb()&&window.__wpUiCompatOverlaySlotEnabled!==!0)return;let e=fb();if(!e||!e.body)return;if(xt&&xt.ownerDocument===e&&xt.isConnected)return ss(xt);let t=e.querySelector(`[${Ud}]`);return t instanceof HTMLDivElement?(xt=ss(t),xt):(xt?.isConnected&&xt.remove(),xt=ss(mb(e)),xt)}var Xd=b(W(),1),qd=(0,Kd.forwardRef)(function({container:t,...o},n){return(0,Xd.jsx)(tt.Portal,{container:t??Gd(),...o,ref:n})});var Zd=b(ce(),1),$d=b(W(),1),ls="data-wp-hash";function ds(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&bb(document)),e.__wpStyleRuntime}function gb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${ls}]`))if(o.getAttribute(ls)===t)return!0;return!1}function Qd(e,t,o){if(!e.head)return;let n=ds(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(gb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(ls,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function bb(e){let t=ds();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Qd(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Jd(e,t){let o=ds();o.styles.set(e,t);for(let n of o.documents.keys())Qd(n,e,t)}typeof process>"u",Jd("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var hb={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",Jd("19fcc06039",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}');var wb={positioner:"_480b748dd3510e64__positioner",popup:"_50096b232db7709d__popup"},eu=(0,Zd.forwardRef)(function({align:t="center",className:o,side:n="top",sideOffset:r=4,...i},s){return(0,$d.jsx)(tt.Positioner,{ref:s,align:t,side:n,sideOffset:r,...i,className:J(hb["box-sizing"],wb.positioner,o)})});var tu=b(ce(),1);function us(e,t,o){return(0,tu.cloneElement)(e??t,{children:o})}var vb=b(nu(),1);var iu=b(fs(),1),{lock:s3,unlock:su}=(0,iu.__dangerousOptInToUnstableAPIsOnlyForCoreModules)("I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.","@wordpress/ui");function _b(){let e=vb;if(e.ThemeProvider)return e.ThemeProvider;if(!e.privateApis)throw new Error("@wordpress/ui: @wordpress/theme must expose `ThemeProvider` or `privateApis.ThemeProvider`.");return su(e.privateApis).ThemeProvider}var au=_b();var tn=b(W(),1),ps="data-wp-hash";function ms(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&xb(document)),e.__wpStyleRuntime}function yb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${ps}]`))if(o.getAttribute(ps)===t)return!0;return!1}function lu(e,t,o){if(!e.head)return;let n=ms(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(yb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(ps,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function xb(e){let t=ms();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)lu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Sb(e,t){let o=ms();o.styles.set(e,t);for(let n of o.documents.keys())lu(n,e,t)}typeof process>"u",Sb("19fcc06039",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}');var Rb={positioner:"_480b748dd3510e64__positioner",popup:"_50096b232db7709d__popup"},Eb={background:"#1e1e1e"},gs=(0,cu.forwardRef)(function({portal:t,positioner:o,children:n,className:r,...i},s){let a=(0,tn.jsx)(au,{color:Eb,children:(0,tn.jsx)(tt.Popup,{ref:s,className:J(Rb.popup,r),...i,children:n})}),l=us(o,(0,tn.jsx)(eu,{}),a);return us(t,(0,tn.jsx)(qd,{}),l)});var du=b(ce(),1),uu=b(W(),1),bs=(0,du.forwardRef)(function(t,o){return(0,uu.jsx)(tt.Trigger,{ref:o,...t})});var fu=b(st(),1),pu=b(W(),1);function mu({children:e}){return(0,pu.jsx)(ir,{direction:(0,fu.isRTL)()?"rtl":"ltr",children:e})}var hs=b(W(),1);function ws(e){return(0,hs.jsx)(mu,{children:(0,hs.jsx)(tt.Root,{...e})})}var on=b(ce(),1),Sr=b(st(),1);var gu=b(ce(),1),vs="data-wp-hash";function _s(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Pb(document)),e.__wpStyleRuntime}function kb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${vs}]`))if(o.getAttribute(vs)===t)return!0;return!1}function bu(e,t,o){if(!e.head)return;let n=_s(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(kb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(vs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Pb(e){let t=_s();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)bu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Cb(e,t){let o=_s();o.styles.set(e,t);for(let n of o.documents.keys())bu(n,e,t)}typeof process>"u",Cb("fa606a57ae","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.f37b9e2e191ebd66__visually-hidden{word-wrap:normal;border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-break:normal}}}");var Ab={"visually-hidden":"f37b9e2e191ebd66__visually-hidden"},ys=(0,gu.forwardRef)(function({render:t,...o},n){return ot({render:t,ref:n,props:ve({className:Ab["visually-hidden"]},o,{"data-visually-hidden":""})})});var xr=b(W(),1);function hu({"aria-describedby":e,"aria-keyshortcuts":t,shortcut:o}){let n=(0,on.useId)(),r=o?n:void 0,i=[e,r].filter(Boolean).join(" ");return{descriptionId:r,targetProps:{"aria-describedby":i||void 0,"aria-keyshortcuts":o?.ariaKeyShortcut??t}}}var wu=(0,on.forwardRef)(function({descriptionId:t,shortcut:o},n){return(0,xr.jsx)(ys,{id:t,"aria-hidden":"true",render:(0,xr.jsx)("span",{ref:n}),children:(0,Sr.sprintf)((0,Sr.__)("Keyboard shortcut: %s"),o.label??o.ariaKeyShortcut)})}),vu=(0,on.forwardRef)(function({className:t,shortcut:o},n){return(0,xr.jsx)("span",{ref:n,"aria-hidden":"true",className:t,dir:"ltr",children:o.displayShortcut})});var nt=b(W(),1),xs="data-wp-hash";function Ss(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Nb(document)),e.__wpStyleRuntime}function Ob(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${xs}]`))if(o.getAttribute(xs)===t)return!0;return!1}function xu(e,t,o){if(!e.head)return;let n=Ss(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Ob(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(xs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Nb(e){let t=Ss();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)xu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Ib(e,t){let o=Ss();o.styles.set(e,t);for(let n of o.documents.keys())xu(n,e,t)}typeof process>"u",Ib("c5cdafb1bc","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer compositions{._28cfdc260e755391__icon-button{--wp-ui-button-aspect-ratio:1;--wp-ui-button-padding-inline:0px;--wp-ui-button-min-width:unset}.f1c70d719989a85a__icon{margin:-1px}}}");var _u={"icon-button":"_28cfdc260e755391__icon-button",icon:"f1c70d719989a85a__icon"},Rs=(0,yu.forwardRef)(function({label:t,className:o,children:n,disabled:r,focusableWhenDisabled:i=!0,icon:s,size:a,shortcut:l,positioner:c,"aria-describedby":d,"aria-keyshortcuts":m,...u},f){let p=J(_u["icon-button"],o),{descriptionId:g,targetProps:h}=hu({"aria-describedby":d,"aria-keyshortcuts":m,shortcut:l});return(0,nt.jsxs)(ws,{children:[(0,nt.jsxs)(bs,{ref:f,...h,disabled:r&&!i,render:(0,nt.jsx)(br,{...u,size:a,"aria-label":t,disabled:r,focusableWhenDisabled:i}),className:p,children:[(0,nt.jsx)(ao,{icon:s,size:24,className:_u.icon}),l&&g&&(0,nt.jsx)(wu,{descriptionId:g,shortcut:l})]}),(0,nt.jsxs)(gs,{positioner:c,children:[t,l&&(0,nt.jsxs)(nt.Fragment,{children:[" ",(0,nt.jsx)(vu,{shortcut:l})]})]})]})});var Su=b(ce(),1),Es="data-wp-hash";function Ts(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Mb(document)),e.__wpStyleRuntime}function Lb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Es}]`))if(o.getAttribute(Es)===t)return!0;return!1}function Ru(e,t,o){if(!e.head)return;let n=Ts(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Lb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Es,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Mb(e){let t=Ts();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Ru(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Bb(e,t){let o=Ts();o.styles.set(e,t);for(let n of o.documents.keys())Ru(n,e,t)}typeof process>"u",Bb("32aba35fe1","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._19ce0419607e1896__stack{display:flex}}}");var Hb={stack:"_19ce0419607e1896__stack"},zb={xs:"var(--wpds-dimension-gap-xs, 4px)",sm:"var(--wpds-dimension-gap-sm, 8px)",md:"var(--wpds-dimension-gap-md, 12px)",lg:"var(--wpds-dimension-gap-lg, 16px)",xl:"var(--wpds-dimension-gap-xl, 24px)","2xl":"var(--wpds-dimension-gap-2xl, 32px)","3xl":"var(--wpds-dimension-gap-3xl, 40px)"},Ut=(0,Su.forwardRef)(function({direction:t,gap:o,align:n,justify:r,wrap:i,render:s,...a},l){let c={gap:o&&zb[o],alignItems:n,justifyContent:r,flexDirection:t,flexWrap:i};return ot({render:s,ref:l,props:ve(a,{style:c,className:Hb.stack})})});var Eu=b(ce(),1),Tu=b(st(),1),Oo=b(W(),1),ks="data-wp-hash";function Ps(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&jb(document)),e.__wpStyleRuntime}function Db(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${ks}]`))if(o.getAttribute(ks)===t)return!0;return!1}function ku(e,t,o){if(!e.head)return;let n=Ps(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Db(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(ks,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function jb(e){let t=Ps();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)ku(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Er(e,t){let o=Ps();o.styles.set(e,t);for(let n of o.documents.keys())ku(n,e,t)}typeof process>"u",Er("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var Fb={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",Er("96553466c8","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._64de9947bf305b7a__outset-ring--focus-within-visible:focus-within:has(:focus-visible),.af79fb116edb0dd7__outset-ring--focus:focus,.dfcfdc28396e5d98__outset-ring--focus-visible:focus-visible,.e5cd9ee879f6403a__outset-ring--focus-within:focus-within,:focus-visible ._81935a08e952f267__outset-ring--focus-parent-visible{--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within,.abc777e9713fa711__outset-ring--focus-except-active:focus{outline:none}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within:not(:has(:active)),.abc777e9713fa711__outset-ring--focus-except-active:focus:not(:active){--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}}}");var Vb={"outset-ring--focus":"af79fb116edb0dd7__outset-ring--focus","outset-ring--focus-visible":"dfcfdc28396e5d98__outset-ring--focus-visible","outset-ring--focus-within":"e5cd9ee879f6403a__outset-ring--focus-within","outset-ring--focus-within-visible":"_64de9947bf305b7a__outset-ring--focus-within-visible","outset-ring--focus-parent-visible":"_81935a08e952f267__outset-ring--focus-parent-visible","outset-ring--focus-except-active":"abc777e9713fa711__outset-ring--focus-except-active","outset-ring--focus-within-except-active":"_3c9f5ee9fc9c136d__outset-ring--focus-within-except-active"};typeof process>"u",Er("e8e6a9be37",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.d4250949359b05ce__link{text-decoration-thickness:from-font;text-underline-offset:.2em}.c6055659b8e2cd2c__is-brand,.c6055659b8e2cd2c__is-brand:visited{--_gcd-a-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9))}.c6055659b8e2cd2c__is-brand:active,.c6055659b8e2cd2c__is-brand:hover{--_gcd-a-color:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));color:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000))}._92e0dfcaeee15b88__is-neutral,._92e0dfcaeee15b88__is-neutral:visited{--_gcd-a-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);text-decoration-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d)}._92e0dfcaeee15b88__is-neutral:active,._92e0dfcaeee15b88__is-neutral:hover{--_gcd-a-color:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);color:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e)}.cf122a9bf1035d42__is-unstyled{--_gcd-a-color:inherit;color:inherit;text-decoration:none}._0cb411afac4c86c7__link-icon{display:inline-block;font-weight:var(--wpds-typography-font-weight-default,400);line-height:1;margin-inline-start:var(--wpds-dimension-padding-xs,4px);text-decoration:none}._0cb411afac4c86c7__link-icon:after{content:"\\2197"}._0cb411afac4c86c7__link-icon:dir(rtl):after{content:"\\2196"}}}');var Rr={link:"d4250949359b05ce__link","is-brand":"c6055659b8e2cd2c__is-brand","is-neutral":"_92e0dfcaeee15b88__is-neutral","is-unstyled":"cf122a9bf1035d42__is-unstyled","link-icon":"_0cb411afac4c86c7__link-icon"};typeof process>"u",Er("af6d9984a6","._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}");var Wb={button:"_6defc79820e382c6__button",input:"d2cff2e5dea83bd1__input",textarea:"_547d86373d02e108__textarea",div:"_8c15fd0ed9f28ba4__div",p:"_43cec3e1eec1066d__p",heading:"e97669c6d9a38497__heading",a:"_2c0831b0499dbd6e__a"},co=(0,Eu.forwardRef)(function({children:t,variant:o="default",tone:n="brand",openInNewTab:r=!1,render:i,className:s,...a},l){return ot({render:i,defaultTagName:"a",ref:l,props:ve(a,{className:J(Wb.a,Fb["box-sizing"],Vb["outset-ring--focus-except-active"],o!=="unstyled"&&Rr.link,o!=="unstyled"&&Rr[`is-${n}`],o==="unstyled"&&Rr["is-unstyled"],s),target:r?"_blank":void 0,children:(0,Oo.jsxs)(Oo.Fragment,{children:[t,r&&(0,Oo.jsx)("span",{className:Rr["link-icon"],role:"img","aria-label":(0,Tu.__)("(opens in a new tab)")})]})})})});var nn={};Mt(nn,{ActionButton:()=>Qu,ActionLink:()=>ef,Actions:()=>Fu,CloseIcon:()=>Gu,Description:()=>zu,Root:()=>Au,Title:()=>Lu});var No=b(ce(),1);import{speak as Yb}from"@wordpress/a11y";var Io=b(W(),1),As="data-wp-hash";function Os(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Gb(document)),e.__wpStyleRuntime}function Ub(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${As}]`))if(o.getAttribute(As)===t)return!0;return!1}function Pu(e,t,o){if(!e.head)return;let n=Os(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Ub(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(As,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Gb(e){let t=Os();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Pu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Cu(e,t){let o=Os();o.styles.set(e,t);for(let n of o.documents.keys())Pu(n,e,t)}typeof process>"u",Cu("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var Kb={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",Cu("726c480820","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var Cs={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},Xb={neutral:null,info:ns,warning:Qi,success:is,error:ts};function qb(e){return e==="error"?"assertive":"polite"}function Zb(e){if(e){if(typeof e=="string")return e;try{return(0,No.renderToString)(e)}catch{return}}}function Qb(e,t){let o=Zb(e);(0,No.useEffect)(()=>{o&&Yb(o,t)},[o,t])}var Au=(0,No.forwardRef)(function({intent:t="neutral",children:o,icon:n,spokenMessage:r=o,politeness:i=qb(t),render:s,...a},l){Qb(r,i);let c=n===null?null:n??Xb[t],d=J(Cs.notice,Cs[`is-${t}`],Kb["box-sizing"]);return ot({defaultTagName:"div",render:s,ref:l,props:ve({className:d,children:(0,Io.jsxs)(Io.Fragment,{children:[o,c&&(0,Io.jsx)(ao,{className:Cs.icon,icon:c})]})},a)})});var Ou=b(ce(),1);var Iu=b(W(),1),Ns="data-wp-hash";function Is(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&$b(document)),e.__wpStyleRuntime}function Jb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Ns}]`))if(o.getAttribute(Ns)===t)return!0;return!1}function Nu(e,t,o){if(!e.head)return;let n=Is(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Jb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Ns,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function $b(e){let t=Is();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Nu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function eh(e,t){let o=Is();o.styles.set(e,t);for(let n of o.documents.keys())Nu(n,e,t)}typeof process>"u",eh("726c480820","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var th={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},Lu=(0,Ou.forwardRef)(function({className:t,...o},n){return(0,Iu.jsx)(We,{ref:n,variant:"heading-md",className:J(th.title,t),...o})});var Mu=b(ce(),1);var Hu=b(W(),1),Ls="data-wp-hash";function Ms(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&nh(document)),e.__wpStyleRuntime}function oh(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Ls}]`))if(o.getAttribute(Ls)===t)return!0;return!1}function Bu(e,t,o){if(!e.head)return;let n=Ms(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(oh(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Ls,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function nh(e){let t=Ms();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Bu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function rh(e,t){let o=Ms();o.styles.set(e,t);for(let n of o.documents.keys())Bu(n,e,t)}typeof process>"u",rh("726c480820","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var ih={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},zu=(0,Mu.forwardRef)(function({className:t,...o},n){return(0,Hu.jsx)(We,{ref:n,variant:"body-md",className:J(ih.description,t),...o})});var Du=b(ce(),1);var Bs="data-wp-hash";function Hs(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&ah(document)),e.__wpStyleRuntime}function sh(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Bs}]`))if(o.getAttribute(Bs)===t)return!0;return!1}function ju(e,t,o){if(!e.head)return;let n=Hs(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(sh(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Bs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function ah(e){let t=Hs();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)ju(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function ch(e,t){let o=Hs();o.styles.set(e,t);for(let n of o.documents.keys())ju(n,e,t)}typeof process>"u",ch("726c480820","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var lh={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},Fu=(0,Du.forwardRef)(function({render:t,...o},n){return ot({defaultTagName:"div",render:t,ref:n,props:ve({className:lh.actions},o)})});var Vu=b(ce(),1),Wu=b(st(),1);var Uu=b(W(),1),zs="data-wp-hash";function Ds(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&uh(document)),e.__wpStyleRuntime}function dh(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${zs}]`))if(o.getAttribute(zs)===t)return!0;return!1}function Yu(e,t,o){if(!e.head)return;let n=Ds(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(dh(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(zs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function uh(e){let t=Ds();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Yu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function fh(e,t){let o=Ds();o.styles.set(e,t);for(let n of o.documents.keys())Yu(n,e,t)}typeof process>"u",fh("726c480820","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var ph={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},Gu=(0,Vu.forwardRef)(function({className:t,icon:o=$i,label:n=(0,Wu.__)("Dismiss"),...r},i){return(0,Uu.jsx)(Rs,{...r,ref:i,className:J(ph["close-icon"],t),variant:"minimal",size:"small",tone:"neutral",icon:o,label:n})});var Xu=b(ce(),1);var Zu=b(W(),1),js="data-wp-hash";function Fs(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&gh(document)),e.__wpStyleRuntime}function mh(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${js}]`))if(o.getAttribute(js)===t)return!0;return!1}function qu(e,t,o){if(!e.head)return;let n=Fs(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(mh(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(js,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function gh(e){let t=Fs();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)qu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function bh(e,t){let o=Fs();o.styles.set(e,t);for(let n of o.documents.keys())qu(n,e,t)}typeof process>"u",bh("726c480820","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var Ku={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},Qu=(0,Xu.forwardRef)(function({className:t,loading:o,loadingAnnouncement:n,variant:r,...i},s){return(0,Zu.jsx)(br,{...i,...o!==void 0?{loading:o,loadingAnnouncement:n??""}:{},ref:s,size:"compact",tone:"neutral",variant:r,className:J(Ku["action-button"],Ku[`is-action-button-${r}`],t)})});var Ju=b(ce(),1);var Ws=b(W(),1),Vs="data-wp-hash";function Ys(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&wh(document)),e.__wpStyleRuntime}function hh(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Vs}]`))if(o.getAttribute(Vs)===t)return!0;return!1}function $u(e,t,o){if(!e.head)return;let n=Ys(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(hh(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Vs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function wh(e){let t=Ys();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)$u(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function vh(e,t){let o=Ys();o.styles.set(e,t);for(let n of o.documents.keys())$u(n,e,t)}typeof process>"u",vh("726c480820","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._1904b570a89bb815__description{text-wrap:pretty}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f3f9ff);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#a9c6e7);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#fff7e1);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1bc7c);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#926300)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#ebffed);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#94d29e);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#008030)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#fff6f5);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dab1aa);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var _h={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},ef=(0,Ju.forwardRef)(function({className:t,render:o,...n},r){return(0,Ws.jsx)(We,{ref:r,className:J(_h["action-link"],t),...n,variant:"body-md",render:(0,Ws.jsx)(co,{tone:"neutral",variant:"default",render:o})})});var tf=b(ce(),1),of=b(W(),1),nf=(0,tf.forwardRef)(({children:e,className:t,ariaLabel:o,as:n="div",...r},i)=>(0,of.jsx)(n,{ref:i,className:J("admin-ui-navigable-region",t),"aria-label":o,role:"region",tabIndex:"-1",...r,children:e}));nf.displayName="NavigableRegion";var rf=nf;var sf=b(st(),1);var Gt=b(W(),1),Gs="data-wp-hash";function Ks(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&xh(document)),e.__wpStyleRuntime}function yh(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Gs}]`))if(o.getAttribute(Gs)===t)return!0;return!1}function af(e,t,o){if(!e.head)return;let n=Ks(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(yh(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Gs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function xh(e){let t=Ks();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)af(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Sh(e,t){let o=Ks();o.styles.set(e,t);for(let n of o.documents.keys())af(n,e,t)}typeof process>"u",Sh("72ef022400",".bfb5a2dd8cceebd3__list{--focus-ring-size:calc(var(--wpds-border-width-focus, var(--wp-admin-border-width-focus, 2px))*2);list-style:none;margin:calc(var(--focus-ring-size)*-1);overflow-x:auto;padding:var(--focus-ring-size);scroll-padding:var(--focus-ring-size)}.a4759b4cb2c8bd92__li{flex-shrink:0}._07da506d3f2d9afe__item{align-items:center;color:var(--wpds-color-foreground-interactive-neutral-weak,#707070);display:flex;font-weight:var(--wpds-typography-font-weight-default,400);min-block-size:44px;min-inline-size:44px;text-decoration:none}._07da506d3f2d9afe__item:hover,._07da506d3f2d9afe__item[aria-current=page]{color:var(--wpds-color-foreground-interactive-neutral-weak-active,#1e1e1e)}._07da506d3f2d9afe__item[aria-current=page]{font-weight:var(--wpds-typography-font-weight-emphasis,600)}");var Us={list:"bfb5a2dd8cceebd3__list",li:"a4759b4cb2c8bd92__li",item:"_07da506d3f2d9afe__item"},Rh=({items:e,currentHref:t,ariaLabel:o=(0,sf.__)("Sections"),linkComponent:n,className:r})=>{if(!e.length)return null;let i=n??"a";return(0,Gt.jsx)("nav",{"aria-label":o,className:r,children:(0,Gt.jsx)(Ut,{render:(0,Gt.jsx)("ul",{role:"list"}),direction:"row",align:"center",gap:"md",className:Us.list,children:e.map(s=>(0,Gt.jsx)("li",{className:Us.li,children:(0,Gt.jsx)(We,{variant:"body-md",className:Us.item,render:(0,Gt.jsx)(co,{variant:"unstyled","aria-current":s.href===t?"page":void 0,render:(0,Gt.jsx)(i,{href:s.href})}),children:s.label})},s.href))})})},cf=Rh;var df=b(rn(),1),{Fill:uf,Slot:ff}=(0,df.createSlotFill)("SidebarToggle");var Ze=b(W(),1),Xs="data-wp-hash";function qs(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Th(document)),e.__wpStyleRuntime}function Eh(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Xs}]`))if(o.getAttribute(Xs)===t)return!0;return!1}function pf(e,t,o){if(!e.head)return;let n=qs(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Eh(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Xs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Th(e){let t=qs();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)pf(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function kh(e,t){let o=qs();o.styles.set(e,t);for(let n of o.documents.keys())pf(n,e,t)}typeof process>"u",kh("1f3750277d","._956b6df0898efed0__page{text-wrap:pretty;background-color:var(--wpds-color-background-surface-neutral,#fcfcfc);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);display:flex;flex-flow:column;height:100%;position:relative;z-index:1}._0625b55e82a0d93d__header{background:var(--wpds-color-background-surface-neutral-strong,#fff);border-block-end:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral-weak,#f0f0f0);inset-block-start:0;padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px);position:sticky;z-index:1}.a43c44d5ae28b2e8__header-content{min-height:var(--wpds-dimension-size-md,32px)}.b7cb5b9daf3a3b25__header-actions{flex-shrink:0}._8bcd33103b451f30__header-lockup{min-width:0}._8113be94e7caf73c__header-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._9a776c7f70996f61__header-visual{display:grid;flex-shrink:0;grid-template-columns:1fr;grid-template-rows:1fr;height:var(--wpds-dimension-size-sm,24px);width:var(--wpds-dimension-size-sm,24px);>*{grid-column:1/-1;grid-row:1/-1;max-height:100%;max-width:100%}}.d5e0920cd15d35bc__sidebar-toggle-slot:empty{display:none}._60fea2f6bf5319cd__header-subtitle{color:var(--wpds-color-foreground-content-neutral-weak,#707070);padding-block-end:var(--wpds-dimension-padding-xs,4px)}._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation,._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation ._60fea2f6bf5319cd__header-subtitle{padding-block-end:0}._673c99dcbfb58211__header-navigation{margin-block-start:var(--wpds-dimension-gap-md,12px)}.be5e57d029ec4036__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;&._128806d0b26e3a50__has-padding{padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px)}}");var St={page:"_956b6df0898efed0__page",header:"_0625b55e82a0d93d__header","header-content":"a43c44d5ae28b2e8__header-content","header-actions":"b7cb5b9daf3a3b25__header-actions","header-lockup":"_8bcd33103b451f30__header-lockup","header-title":"_8113be94e7caf73c__header-title","header-visual":"_9a776c7f70996f61__header-visual","sidebar-toggle-slot":"d5e0920cd15d35bc__sidebar-toggle-slot","header-subtitle":"_60fea2f6bf5319cd__header-subtitle","has-navigation":"_4b0f17e503d11619__has-navigation","header-navigation":"_673c99dcbfb58211__header-navigation",content:"be5e57d029ec4036__content","has-padding":"_128806d0b26e3a50__has-padding"};function mf({headingLevel:e=1,breadcrumbs:t,badges:o,visual:n,title:r,subTitle:i,actions:s,navigation:a,components:l,showSidebarToggle:c=!0}){let d=`h${e}`,m=!!a?.items?.length;return(0,Ze.jsxs)(Ut,{direction:"column",className:J(St.header,m&&St["has-navigation"]),children:[(0,Ze.jsxs)(Ut,{className:St["header-content"],direction:"row",gap:"sm",justify:"space-between",children:[(0,Ze.jsxs)(Ut,{direction:"row",gap:"sm",align:"center",justify:"start",className:St["header-lockup"],children:[c&&(0,Ze.jsx)(ff,{bubblesVirtually:!0,className:St["sidebar-toggle-slot"]}),n&&(0,Ze.jsx)("div",{className:St["header-visual"],"aria-hidden":"true",children:n}),r&&(0,Ze.jsx)(We,{className:St["header-title"],render:(0,Ze.jsx)(d,{}),variant:"heading-lg",children:r}),t,o]}),s&&(0,Ze.jsx)(Ut,{align:"center",className:St["header-actions"],direction:"row",gap:"sm",children:s})]}),i&&(0,Ze.jsx)(We,{render:(0,Ze.jsx)("p",{}),variant:"body-md",className:St["header-subtitle"],children:i}),m&&(0,Ze.jsx)(cf,{...a,linkComponent:l?.link,className:St["header-navigation"]})]})}var sn=b(W(),1),Qs="data-wp-hash";function Js(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Ch(document)),e.__wpStyleRuntime}function Ph(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Qs}]`))if(o.getAttribute(Qs)===t)return!0;return!1}function gf(e,t,o){if(!e.head)return;let n=Js(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Ph(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Qs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Ch(e){let t=Js();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)gf(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Ah(e,t){let o=Js();o.styles.set(e,t);for(let n of o.documents.keys())gf(n,e,t)}typeof process>"u",Ah("1f3750277d","._956b6df0898efed0__page{text-wrap:pretty;background-color:var(--wpds-color-background-surface-neutral,#fcfcfc);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);display:flex;flex-flow:column;height:100%;position:relative;z-index:1}._0625b55e82a0d93d__header{background:var(--wpds-color-background-surface-neutral-strong,#fff);border-block-end:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral-weak,#f0f0f0);inset-block-start:0;padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px);position:sticky;z-index:1}.a43c44d5ae28b2e8__header-content{min-height:var(--wpds-dimension-size-md,32px)}.b7cb5b9daf3a3b25__header-actions{flex-shrink:0}._8bcd33103b451f30__header-lockup{min-width:0}._8113be94e7caf73c__header-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._9a776c7f70996f61__header-visual{display:grid;flex-shrink:0;grid-template-columns:1fr;grid-template-rows:1fr;height:var(--wpds-dimension-size-sm,24px);width:var(--wpds-dimension-size-sm,24px);>*{grid-column:1/-1;grid-row:1/-1;max-height:100%;max-width:100%}}.d5e0920cd15d35bc__sidebar-toggle-slot:empty{display:none}._60fea2f6bf5319cd__header-subtitle{color:var(--wpds-color-foreground-content-neutral-weak,#707070);padding-block-end:var(--wpds-dimension-padding-xs,4px)}._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation,._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation ._60fea2f6bf5319cd__header-subtitle{padding-block-end:0}._673c99dcbfb58211__header-navigation{margin-block-start:var(--wpds-dimension-gap-md,12px)}.be5e57d029ec4036__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;&._128806d0b26e3a50__has-padding{padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px)}}");var Zs={page:"_956b6df0898efed0__page",header:"_0625b55e82a0d93d__header","header-content":"a43c44d5ae28b2e8__header-content","header-actions":"b7cb5b9daf3a3b25__header-actions","header-lockup":"_8bcd33103b451f30__header-lockup","header-title":"_8113be94e7caf73c__header-title","header-visual":"_9a776c7f70996f61__header-visual","sidebar-toggle-slot":"d5e0920cd15d35bc__sidebar-toggle-slot","header-subtitle":"_60fea2f6bf5319cd__header-subtitle","has-navigation":"_4b0f17e503d11619__has-navigation","header-navigation":"_673c99dcbfb58211__header-navigation",content:"be5e57d029ec4036__content","has-padding":"_128806d0b26e3a50__has-padding"};function bf({headingLevel:e,breadcrumbs:t,badges:o,visual:n,title:r,subTitle:i,children:s,className:a,actions:l,navigation:c,components:d,ariaLabel:m,hasPadding:u=!1,showSidebarToggle:f=!0}){let p=J(Zs.page,a);return(0,sn.jsxs)(rf,{className:p,ariaLabel:m??(typeof r=="string"?r:""),children:[(r||t||o||l||n||!!c?.items?.length)&&(0,sn.jsx)(mf,{headingLevel:e,breadcrumbs:t,badges:o,visual:n,title:r,subTitle:i,actions:l,navigation:c,components:d,showSidebarToggle:f}),u?(0,sn.jsx)("div",{className:J(Zs.content,Zs["has-padding"]),children:s}):s]})}bf.SidebarToggleFill=uf;var $s=bf;var ut=b(rn()),Ff=b(an()),Vf=b(ce()),At=b(st()),Wf=b(Tr());import{privateApis as Kh}from"@wordpress/connectors";var vf=b(fs()),{lock:a8,unlock:Lo}=(0,vf.__dangerousOptInToUnstableAPIsOnlyForCoreModules)("I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.","@wordpress/routes");if(typeof document<"u"&&!document.head.querySelector("style[data-wp-hash='09e9b056ea']")){let e=document.createElement("style");e.setAttribute("data-wp-hash","09e9b056ea"),e.appendChild(document.createTextNode(".connectors-page{box-sizing:border-box;margin:0 auto;max-width:680px;padding:24px;width:100%}.connectors-page .components-item{background:#fff;border:1px solid #ddd;border-radius:8px;overflow:hidden;padding:20px;scroll-margin-top:120px}.connectors-page .connector-settings__error{color:#cc1818}.connectors-page .connector-settings .components-text-control__input{font-family:monospace;scroll-margin-top:120px}.connectors-page__file-mods-notice{margin-bottom:16px}.connectors-page--empty{align-items:center;display:flex;flex-direction:column;flex-grow:1;gap:32px;justify-content:center;text-align:center}.connectors-page .ai-plugin-callout{background-color:#e7d4e4;background-image:radial-gradient(ellipse 70% 120% at 18% 115%,rgba(202,158,198,.75) 0,rgba(202,158,198,0) 60%),radial-gradient(ellipse 55% 110% at 92% -15%,rgba(208,175,217,.7) 0,rgba(208,175,217,0) 65%),radial-gradient(ellipse 40% 85% at 58% -10%,rgba(170,130,184,.45) 0,rgba(170,130,184,0) 70%);border-radius:8px;overflow:hidden;padding:24px;padding-inline-end:150px;position:relative}[dir=rtl] .connectors-page .ai-plugin-callout{background-image:radial-gradient(ellipse 70% 120% at 82% 115%,rgba(202,158,198,.75) 0,rgba(202,158,198,0) 60%),radial-gradient(ellipse 55% 110% at 8% -15%,rgba(208,175,217,.7) 0,rgba(208,175,217,0) 65%),radial-gradient(ellipse 40% 85% at 42% -10%,rgba(170,130,184,.45) 0,rgba(170,130,184,0) 70%)}.connectors-page .ai-plugin-callout__content{align-items:flex-start;display:flex;flex-direction:column;gap:12px;padding-top:2px}.connectors-page .ai-plugin-callout__content p{font-size:13px;line-height:20px;margin:0}.connectors-page .ai-plugin-callout__decoration{height:110px;inset-inline-end:16px;position:absolute;top:12px;width:110px}.connectors-page>p{color:#949494}@media (max-width:680px){.connectors-page .ai-plugin-callout{padding:12px;padding-inline-end:100px}.connectors-page .ai-plugin-callout__decoration{height:75px;inset-inline-end:8px;top:8px;width:75px}}@media (max-width:480px){.connectors-page{padding:8px}.connectors-page .ai-plugin-callout{padding-inline-end:130px}.connectors-page .components-item{padding:12px}.connectors-page .components-item>.components-v-stack>.components-h-stack:first-child svg{height:32px;width:32px}.connectors-page .components-item>.components-v-stack>.components-h-stack:first-child>.components-h-stack:last-child{align-items:flex-end;flex-direction:column}}")),document.head.appendChild(e)}var dn=b(rn()),sa=b(Tr()),un=b(an()),Et=b(ce()),Qe=b(st()),Hf=b(ea()),zf=b(xf());var kr=b(rn()),na=b(ce()),Af=b(an()),lo=b(st());import{__experimentalRegisterConnector as Oh,__experimentalConnectorItem as Cf,__experimentalDefaultConnectorSettings as Nh,__experimentalApplicationPasswordConnectorSettings as Ih,privateApis as Lh}from"@wordpress/connectors";var ta=b(Tr()),ln=b(an()),cn=b(ce()),pe=b(st()),Sf=b(ea());function oa({file:e,settingName:t,connectorName:o,isInstalled:n,isActivated:r,keySource:i="none",initialIsConnected:s=!1}){let[a,l]=(0,cn.useState)(!1),[c,d]=(0,cn.useState)(!1),[m,u]=(0,cn.useState)(s),[f,p]=(0,cn.useState)(null),g=e?.replace(/\.php$/,""),h=g?.includes("/")?g.split("/")[0]:g,{derivedPluginStatus:y,canManagePlugins:_,currentApiKey:v,currentUsername:w,hasStoredCredentials:R,hasResolvedSettings:x,canInstallPlugins:S}=(0,ln.useSelect)(Q=>{let q=Q(ta.store),ne=q.getEntityRecord("root","site")?.[t],se=typeof ne=="string"?ne:"",ze=typeof ne=="object"&&ne!==null?ne:void 0,ae=ze!==void 0?!!ze.username&&!!ze.password:!!se,ge=q.hasFinishedResolution("getEntityRecord",["root","site"]),be=!!q.canUser("create",{kind:"root",name:"plugin"}),Ee={currentApiKey:se,currentUsername:ze?.username??"",hasStoredCredentials:ae,hasResolvedSettings:ge,canInstallPlugins:be};if(!e)return{...Ee,derivedPluginStatus:ge?"active":"checking",canManagePlugins:void 0};let ye=q.getEntityRecord("root","plugin",g);if(!q.hasFinishedResolution("getEntityRecord",["root","plugin",g]))return{...Ee,derivedPluginStatus:"checking",canManagePlugins:void 0};if(ye){let ft=ye.status==="active"||ye.status==="network-active";return{...Ee,derivedPluginStatus:ft?"active":"inactive",canManagePlugins:!0}}let rt="not-installed";return r?rt="active":n&&(rt="inactive"),{...Ee,derivedPluginStatus:rt,canManagePlugins:!1}},[e,g,t,n,r]),E=f??y,T=_,P=E==="active"&&m||f==="active"&&R,{saveEntityRecord:N,invalidateResolution:H}=(0,ln.useDispatch)(ta.store),{createSuccessNotice:j,createErrorNotice:L}=(0,ln.useDispatch)(Sf.store),k=Q=>N("root","site",{[t]:Q},{throwOnError:!0}),I=()=>{j((0,pe.sprintf)((0,pe.__)("%s connected successfully."),o),{id:"connector-connect-success",type:"snackbar"})},C=()=>{j((0,pe.sprintf)((0,pe.__)("%s disconnected."),o),{id:"connector-disconnect-success",type:"snackbar"})},A=()=>{L((0,pe.sprintf)((0,pe.__)("Failed to disconnect %s."),o),{id:"connector-disconnect-error",type:"snackbar"})},M=async()=>{if(h){d(!0);try{await N("root","plugin",{slug:h,status:"active"},{throwOnError:!0}),p("active"),H("getEntityRecord",["root","site"]),l(!0),j((0,pe.sprintf)((0,pe.__)("Plugin for %s installed and activated successfully."),o),{id:"connector-plugin-install-success",type:"snackbar"})}catch{L((0,pe.sprintf)((0,pe.__)("Failed to install plugin for %s."),o),{id:"connector-plugin-install-error",type:"snackbar"})}finally{d(!1)}}},X=async()=>{if(e){d(!0);try{await N("root","plugin",{plugin:g,status:"active"},{throwOnError:!0}),p("active"),H("getEntityRecord",["root","site"]),l(!0),j((0,pe.sprintf)((0,pe.__)("Plugin for %s activated successfully."),o),{id:"connector-plugin-activate-success",type:"snackbar"})}catch{L((0,pe.sprintf)((0,pe.__)("Failed to activate plugin for %s."),o),{id:"connector-plugin-activate-error",type:"snackbar"})}finally{d(!1)}}};return{pluginStatus:E,canInstallPlugins:S,canActivatePlugins:T,isExpanded:a,setIsExpanded:l,isBusy:c,isConnected:P,currentApiKey:v,currentUsername:w,hasResolvedSettings:x,keySource:i,handleButtonClick:()=>{if(E==="not-installed"){if(S===!1)return;M()}else if(E==="inactive"){if(T===!1)return;X()}else l(!a)},getButtonLabel:()=>{if(c)return E==="not-installed"?(0,pe.__)("Installing\u2026"):(0,pe.__)("Activating\u2026");if(a)return(0,pe.__)("Cancel");if(P)return(0,pe.__)("Edit");switch(E){case"checking":return(0,pe.__)("Checking\u2026");case"not-installed":return(0,pe.__)("Install");case"inactive":return(0,pe.__)("Activate");case"active":return(0,pe.__)("Set up")}},saveApiKey:async Q=>{let q=v;try{let se=(await k(Q))?.[t];if(Q&&(se===q||!se))throw new Error("It was not possible to connect to the provider using this key.");u(!0),I()}catch($){throw console.error("Failed to save API key:",$),$}},removeApiKey:async()=>{try{await k(""),u(!1),C()}catch(Q){console.error("Failed to remove API key:",Q),A()}},saveCredentials:async({username:Q,applicationPassword:q})=>{try{let se=(await k({username:Q,password:q}))?.[t];if(!se?.username||!se?.password)throw new Error((0,pe.__)("It was not possible to save these credentials."));u(!0),I()}catch($){throw console.error("Failed to save credentials:",$),$}},removeCredentials:async()=>{try{await k({username:"",password:""}),u(!1),C()}catch(Q){console.error("Failed to remove credentials:",Q),A()}}}}var ue=b(W()),Rf=()=>(0,ue.jsx)("svg",{width:"40",height:"40",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:(0,ue.jsx)("path",{d:"M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364l2.0201-1.1685a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.4043-.6813zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z",fill:"currentColor"})}),Ef=()=>(0,ue.jsx)("svg",{width:"40",height:"40",viewBox:"0 0 32 32",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:(0,ue.jsx)("path",{d:"M6.2 21.024L12.416 17.536L12.52 17.232L12.416 17.064H12.112L11.072 17L7.52 16.904L4.44 16.776L1.456 16.616L0.704 16.456L0 15.528L0.072 15.064L0.704 14.64L1.608 14.72L3.608 14.856L6.608 15.064L8.784 15.192L12.008 15.528H12.52L12.592 15.32L12.416 15.192L12.28 15.064L9.176 12.96L5.816 10.736L4.056 9.456L3.104 8.808L2.624 8.2L2.416 6.872L3.28 5.92L4.44 6L4.736 6.08L5.912 6.984L8.424 8.928L11.704 11.344L12.184 11.744L12.376 11.608L12.4 11.512L12.184 11.152L10.4 7.928L8.496 4.648L7.648 3.288L7.424 2.472C7.344 2.136 7.288 1.856 7.288 1.512L8.272 0.176L8.816 0L10.128 0.176L10.68 0.656L11.496 2.52L12.816 5.456L14.864 9.448L15.464 10.632L15.784 11.728L15.904 12.064H16.112V11.872L16.28 9.624L16.592 6.864L16.896 3.312L17 2.312L17.496 1.112L18.48 0.464L19.248 0.832L19.88 1.736L19.792 2.32L19.416 4.76L18.68 8.584L18.2 11.144H18.48L18.8 10.824L20.096 9.104L22.272 6.384L23.232 5.304L24.352 4.112L25.072 3.544H26.432L27.432 5.032L26.984 6.568L25.584 8.344L24.424 9.848L22.76 12.088L21.72 13.88L21.816 14.024L22.064 14L25.824 13.2L27.856 12.832L30.28 12.416L31.376 12.928L31.496 13.448L31.064 14.512L28.472 15.152L25.432 15.76L20.904 16.832L20.848 16.872L20.912 16.952L22.952 17.144L23.824 17.192H25.96L29.936 17.488L30.976 18.176L31.6 19.016L31.496 19.656L29.896 20.472L27.736 19.96L22.696 18.76L20.968 18.328H20.728V18.472L22.168 19.88L24.808 22.264L28.112 25.336L28.28 26.096L27.856 26.696L27.408 26.632L24.504 24.448L23.384 23.464L20.848 21.328H20.68V21.552L21.264 22.408L24.352 27.048L24.512 28.472L24.288 28.936L23.488 29.216L22.608 29.056L20.8 26.52L18.936 23.664L17.432 21.104L17.248 21.208L16.36 30.768L15.944 31.256L14.984 31.624L14.184 31.016L13.76 30.032L14.184 28.088L14.696 25.552L15.112 23.536L15.488 21.032L15.712 20.2L15.696 20.144L15.512 20.168L13.624 22.76L10.752 26.64L8.48 29.072L7.936 29.288L6.992 28.8L7.08 27.928L7.608 27.152L10.752 23.152L12.648 20.672L13.872 19.24L13.864 19.032H13.792L5.44 24.456L3.952 24.648L3.312 24.048L3.392 23.064L3.696 22.744L6.208 21.016L6.2 21.024Z",fill:"#D97757"})}),Tf=()=>(0,ue.jsxs)("svg",{width:"40",height:"40",viewBox:"0 0 32 32",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[(0,ue.jsx)("path",{d:"M0 4C0 1.79086 1.79086 0 4 0H28C30.2091 0 32 1.79086 32 4V28C32 30.2091 30.2091 32 28 32H4C1.79086 32 0 30.2091 0 28V4Z",fill:"#F0F0F0"}),(0,ue.jsx)("path",{d:"M14.5 8V12H17.5V8H19V12H20.5C20.7652 12 21.0196 12.1054 21.2071 12.2929C21.3946 12.4804 21.5 12.7348 21.5 13V17L18.5 21V23C18.5 23.2652 18.3946 23.5196 18.2071 23.7071C18.0196 23.8946 17.7652 24 17.5 24H14.5C14.2348 24 13.9804 23.8946 13.7929 23.7071C13.6054 23.5196 13.5 23.2652 13.5 23V21L10.5 17V13C10.5 12.7348 10.6054 12.4804 10.7929 12.2929C10.9804 12.1054 11.2348 12 11.5 12H13V8H14.5ZM15 20.5V22.5H17V20.5L20 16.5V13.5H12V16.5L15 20.5Z",fill:"#949494"})]}),kf=()=>(0,ue.jsxs)("svg",{width:"40",height:"40",viewBox:"0 0 44 44",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[(0,ue.jsx)("rect",{width:"44",height:"44",fill:"#357B49",rx:"6"}),(0,ue.jsx)("path",{fill:"#fff",fillRule:"evenodd",d:"m29.746 28.31-6.392-16.797c-.152-.397-.305-.672-.789-.675-.673 0-1.408.611-1.746 1.316l-7.378 16.154c-.072.16-.143.311-.214.454-.5.995-1.045 1.546-2.357 1.626a.399.399 0 0 0-.16.033l-.01.004a.399.399 0 0 0-.23.392v.01c0 .054.01.106.03.155l.004.01a.416.416 0 0 0 .394.252h6.212a.417.417 0 0 0 .307-.12.416.416 0 0 0 .124-.305.398.398 0 0 0-.105-.302.399.399 0 0 0-.294-.127c-.757 0-2.197-.062-2.197-1.164.02-.318.103-.63.245-.916l1.399-3.152c.52-1.163 1.654-1.163 2.572-1.163h5.843c.023 0 .044 0 .062.003.13.014.16.081.214.242l1.534 4.07a2.857 2.857 0 0 1 .216 1.04c0 .054-.003.104-.01.153-.09.726-.831.887-1.49.887a.4.4 0 0 0-.294.127l-.007.008-.007.008a.401.401 0 0 0-.092.286v.01c0 .054.01.106.03.155l.005.01a.42.42 0 0 0 .395.252h7.011a.413.413 0 0 0 .279-.13.412.412 0 0 0 .11-.297.387.387 0 0 0-.09-.294.388.388 0 0 0-.277-.135c-1.448-.122-2.295-.643-2.847-2.08Zm-11.985-5.844 2.847-6.304c.361-.728.659-1.486.889-2.265 0-.06.03-.092.06-.092s.061.032.061.091c.02.122.045.247.073.374.197.888.584 1.878.914 2.723l.176.453 1.684 4.529a.927.927 0 0 1 .092.4.473.473 0 0 1-.009.094c-.041.202-.228.272-.602.272h-6.063c-.122 0-.184-.03-.184-.092a.36.36 0 0 1 .062-.183Zm17.107-.721c0 .786-.446 1.231-1.25 1.231-.806 0-1.125-.409-1.125-1.034 0-.786.465-1.231 1.25-1.231.785 0 1.125.427 1.125 1.034ZM9.629 23.002c.803 0 1.25-.447 1.25-1.231 0-.607-.343-1.036-1.128-1.036-.785 0-1.25.447-1.25 1.231 0 .625.325 1.036 1.128 1.036Z",clipRule:"evenodd"})]}),Pf=()=>(0,ue.jsxs)("svg",{width:"40",height:"40",style:{flex:"none",lineHeight:1},viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[(0,ue.jsx)("path",{d:"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z",fill:"#3186FF"}),(0,ue.jsx)("path",{d:"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z",fill:"url(#lobe-icons-gemini-fill-0)"}),(0,ue.jsx)("path",{d:"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z",fill:"url(#lobe-icons-gemini-fill-1)"}),(0,ue.jsx)("path",{d:"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z",fill:"url(#lobe-icons-gemini-fill-2)"}),(0,ue.jsxs)("defs",{children:[(0,ue.jsxs)("linearGradient",{gradientUnits:"userSpaceOnUse",id:"lobe-icons-gemini-fill-0",x1:"7",x2:"11",y1:"15.5",y2:"12",children:[(0,ue.jsx)("stop",{stopColor:"#08B962"}),(0,ue.jsx)("stop",{offset:"1",stopColor:"#08B962",stopOpacity:"0"})]}),(0,ue.jsxs)("linearGradient",{gradientUnits:"userSpaceOnUse",id:"lobe-icons-gemini-fill-1",x1:"8",x2:"11.5",y1:"5.5",y2:"11",children:[(0,ue.jsx)("stop",{stopColor:"#F94543"}),(0,ue.jsx)("stop",{offset:"1",stopColor:"#F94543",stopOpacity:"0"})]}),(0,ue.jsxs)("linearGradient",{gradientUnits:"userSpaceOnUse",id:"lobe-icons-gemini-fill-2",x1:"3.5",x2:"17.5",y1:"13.5",y2:"12",children:[(0,ue.jsx)("stop",{stopColor:"#FABC12"}),(0,ue.jsx)("stop",{offset:".46",stopColor:"#FABC12",stopOpacity:"0"})]})]})]});var _e=b(W()),{store:Mh}=Lo(Lh);function Of(){try{return JSON.parse(document.getElementById("wp-script-module-data-options-connectors-wp-admin")?.textContent??"{}")}catch{return{}}}function ra(){return Of().connectors??{}}function Nf(){return!!Of().isFileModDisabled}var Bh={google:Pf,openai:Rf,anthropic:Ef,akismet:kf};function Hh(e,t){if(t)return(0,_e.jsx)("img",{src:t,alt:"",width:40,height:40});let o=Bh[e];return o?(0,_e.jsx)(o,{}):(0,_e.jsx)(Tf,{})}var zh=()=>(0,_e.jsx)("span",{style:{color:"#345b37",backgroundColor:"#eff8f0",padding:"4px 12px",borderRadius:"2px",fontSize:"13px",fontWeight:"var(--wpds-typography-font-weight-emphasis)",whiteSpace:"nowrap"},children:(0,lo.__)("Connected")}),Dh=({slug:e})=>(0,_e.jsx)(co,{href:(0,lo.sprintf)((0,lo.__)("https://wordpress.org/plugins/%s/"),e),openInNewTab:!0,children:(0,lo.__)("Learn more")}),jh=()=>(0,_e.jsx)(Yi,{children:(0,lo.__)("Not available")});function If({isConnected:e,showUnavailableBadge:t,pluginSlug:o,isExpanded:n,isBusy:r,pluginStatus:i,actionButtonRef:s,handleButtonClick:a,getButtonLabel:l}){return(0,_e.jsxs)(kr.__experimentalHStack,{spacing:3,expanded:!1,children:[e&&(0,_e.jsx)(zh,{}),t&&(o?(0,_e.jsx)(Dh,{slug:o}):(0,_e.jsx)(jh,{})),!t&&(0,_e.jsx)(kr.Button,{ref:s,variant:n||e?"tertiary":"secondary",size:"compact",onClick:a,disabled:i==="checking"||r,isBusy:r,accessibleWhenDisabled:!0,children:l()})]})}function Lf(e){let t=e?.replace(/\.php$/,"");return t?.includes("/")?t.split("/")[0]:t}function Fh({name:e,description:t,logo:o,authentication:n,plugin:r}){let i=n?.method==="api_key"?n:void 0,s=i?.settingName??"",a=i?.credentialsUrl??void 0,l=Lf(r?.file),{pluginStatus:c,canInstallPlugins:d,canActivatePlugins:m,isExpanded:u,setIsExpanded:f,isBusy:p,isConnected:g,currentApiKey:h,hasResolvedSettings:y,keySource:_,handleButtonClick:v,getButtonLabel:w,saveApiKey:R,removeApiKey:x}=oa({file:r?.file,settingName:s,connectorName:e,isInstalled:r?.isInstalled,isActivated:r?.isActivated,keySource:i?.keySource,initialIsConnected:i?.isConnected}),S=_==="env"||_==="constant",E=c==="not-installed"&&d===!1||c==="inactive"&&m===!1,T=(0,na.useRef)(null);return(0,_e.jsx)(Cf,{className:l?`connector-item--${l}`:void 0,logo:o,name:e,description:t,actionArea:(0,_e.jsx)(If,{isConnected:g,showUnavailableBadge:E,pluginSlug:l,isExpanded:u,isBusy:p,pluginStatus:c,actionButtonRef:T,handleButtonClick:v,getButtonLabel:w}),children:u&&c==="active"&&y&&(0,_e.jsx)(Nh,{initialValue:S?"\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022":h,helpUrl:a,readOnly:g||S,keySource:_,onRemove:S?void 0:async()=>{await x(),T.current?.focus()},onSave:async P=>{await R(P),f(!1),T.current?.focus()}},g?"connected":"setup")})}function Vh({name:e,description:t,logo:o,authentication:n,plugin:r}){let i=n?.method==="application_password"?n:void 0,s=i?.settingName??"",a=i?.credentialsUrl??void 0,l=Lf(r?.file),{pluginStatus:c,canInstallPlugins:d,canActivatePlugins:m,isExpanded:u,setIsExpanded:f,isBusy:p,isConnected:g,currentUsername:h,hasResolvedSettings:y,keySource:_,handleButtonClick:v,getButtonLabel:w,saveCredentials:R,removeCredentials:x}=oa({file:r?.file,settingName:s,connectorName:e,isInstalled:r?.isInstalled,isActivated:r?.isActivated,keySource:i?.keySource,initialIsConnected:i?.isConnected}),S=_==="env"||_==="constant",E=(0,na.useRef)(null),T=c==="not-installed"&&d===!1||c==="inactive"&&m===!1;return(0,_e.jsx)(Cf,{className:l?`connector-item--${l}`:void 0,logo:o,name:e,description:t,actionArea:(0,_e.jsx)(If,{isConnected:g,showUnavailableBadge:T,pluginSlug:l,isExpanded:u,isBusy:p,pluginStatus:c,actionButtonRef:E,handleButtonClick:v,getButtonLabel:w}),children:u&&c==="active"&&y&&(0,_e.jsx)(Ih,{initialUsername:S?"\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022":h,helpUrl:a,readOnly:g||S,keySource:_,onRemove:S?void 0:async()=>{await x(),E.current?.focus()},onSave:async P=>{await R(P),f(!1),E.current?.focus()}},g?"connected":"setup")})}function Mf(){let e=ra(),t=o=>o.replace(/[^a-z0-9-_]/gi,"-");for(let[o,n]of Object.entries(e)){if(o==="akismet"&&!n.plugin?.isInstalled)continue;let{authentication:r}=n,i=t(o),s={name:n.name,description:n.description,type:n.type,logo:Hh(o,n.logoUrl),authentication:r,plugin:n.plugin},a=Lo((0,Af.select)(Mh)).getConnector(i);r.method==="api_key"&&!a?.render?s.render=Fh:r.method==="application_password"&&!a?.render&&(s.render=Vh),Oh(i,s)}}var Pr=b(W());function Bf(){return(0,Pr.jsx)("div",{className:"ai-plugin-callout__decoration","aria-hidden":"true",children:(0,Pr.jsx)("svg",{viewBox:"0 0 248 248",xmlns:"http://www.w3.org/2000/svg",xmlnsXlink:"http://www.w3.org/1999/xlink",focusable:"false",style:{width:"100%",height:"100%"},children:(0,Pr.jsx)("image",{href:"data:image/png;base64,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",width:"248",height:"248",style:{mixBlendMode:"multiply"}})})})}var Rt=b(W()),Wh="ai",Yh="ai-wp-admin",ia="ai/ai",Uh="https://wordpress.org/plugins/ai/",aa=Object.values(ra()),Gh=aa.some(e=>e.type==="ai_provider"),Df=[];for(let e of aa)e.type==="ai_provider"&&e.authentication.method==="api_key"&&Df.push(e.authentication.settingName);function jf(){let[e,t]=(0,Et.useState)(!1),[o,n]=(0,Et.useState)(!1),r=(0,Et.useRef)(null);(0,Et.useEffect)(()=>{o&&r.current?.focus()},[o]);let i=(0,Et.useRef)(aa.some(R=>R.type==="ai_provider"&&R.authentication.method==="api_key"&&R.authentication.isConnected)).current,{pluginStatus:s,canInstallPlugins:a,canManagePlugins:l,hasConnectedProvider:c}=(0,un.useSelect)(R=>{let x=R(sa.store),S=!!x.canUser("create",{kind:"root",name:"plugin"}),E=x.getEntityRecord("root","site"),T=i||Df.some(H=>!!E?.[H]),P=x.getEntityRecord("root","plugin",ia);return x.hasFinishedResolution("getEntityRecord",["root","plugin",ia])?P?{pluginStatus:P.status==="active"?"active":"inactive",canInstallPlugins:S,canManagePlugins:!0,hasConnectedProvider:T}:{pluginStatus:"not-installed",canInstallPlugins:S,canManagePlugins:S,hasConnectedProvider:T}:{pluginStatus:"checking",canInstallPlugins:S,canManagePlugins:void 0,hasConnectedProvider:T}},[]),{saveEntityRecord:d}=(0,un.useDispatch)(sa.store),{createSuccessNotice:m,createErrorNotice:u}=(0,un.useDispatch)(Hf.store),f=async()=>{t(!0);try{await d("root","plugin",{slug:Wh,status:"active"},{throwOnError:!0}),n(!0),m((0,Qe.__)("AI plugin installed and activated successfully."),{id:"ai-plugin-install-success",type:"snackbar"})}catch{u((0,Qe.__)("Failed to install the AI plugin."),{id:"ai-plugin-install-error",type:"snackbar"})}finally{t(!1)}},p=async()=>{t(!0);try{await d("root","plugin",{plugin:ia,status:"active"},{throwOnError:!0}),n(!0),m((0,Qe.__)("AI plugin activated successfully."),{id:"ai-plugin-activate-success",type:"snackbar"})}catch{u((0,Qe.__)("Failed to activate the AI plugin."),{id:"ai-plugin-activate-error",type:"snackbar"})}finally{t(!1)}};if(!Gh||s==="checking"||s==="active"&&i&&!o||s==="inactive"&&l===!1)return null;let g=s==="active"&&!c,h=s==="active"&&c&&(!i||o),y=s==="not-installed"||s==="inactive",_=s==="not-installed"&&a===!1,v=()=>h?(0,Qe.__)("The AI plugin is ready to use. You can use it to generate featured images, alt text, titles, excerpts and more. Learn more"):g?(0,Qe.__)("The AI plugin is installed. Connect an AI provider below to generate featured images, alt text, titles, excerpts, and more. Learn more"):(0,Qe.__)("The AI plugin can use your AI connectors to generate featured images, alt text, titles, excerpts and more. Learn more"),w=()=>s==="not-installed"?{label:e?(0,Qe.__)("Installing\u2026"):(0,Qe.__)("Install the AI plugin"),disabled:e,onClick:e?void 0:f}:{label:e?(0,Qe.__)("Activating\u2026"):(0,Qe.__)("Activate the AI plugin"),disabled:e,onClick:e?void 0:p};return(0,Rt.jsxs)("div",{className:"ai-plugin-callout",children:[(0,Rt.jsxs)("div",{className:"ai-plugin-callout__content",children:[(0,Rt.jsx)("p",{children:(0,Et.createInterpolateElement)(v(),{strong:(0,Rt.jsx)("strong",{}),a:(0,Rt.jsx)(dn.ExternalLink,{href:Uh})})}),!_&&(y?(0,Rt.jsx)(dn.Button,{variant:"primary",size:"compact",isBusy:e,disabled:w().disabled,accessibleWhenDisabled:!0,onClick:w().onClick,children:w().label}):(0,Rt.jsx)(dn.Button,{ref:r,variant:"secondary",size:"compact",href:(0,zf.addQueryArgs)("options-general.php",{page:Yh}),children:(0,Qe.__)("Control features in the AI plugin")}))]}),(0,Rt.jsx)(Bf,{})]})}var Re=b(W()),{store:Xh}=Lo(Kh);Mf();function qh(){let e=Nf(),{connectors:t,canInstallPlugins:o,isAiPluginInstalled:n}=(0,Ff.useSelect)(c=>{let d=c(Wf.store),m=d.getEntityRecord("root","plugin","ai/ai");return{connectors:Lo(c(Xh)).getConnectors(),canInstallPlugins:d.canUser("create",{kind:"root",name:"plugin"}),isAiPluginInstalled:!!m}},[]),r=t.filter(c=>c.render),i=Array.from(new Set(t.filter(c=>c.type==="ai_provider").map(c=>c.plugin?.file?.split("/")[0]).filter(c=>!!c))).sort(),s=new Set(t.filter(c=>c.plugin?.isInstalled).map(c=>c.plugin?.file?.split("/")[0]).filter(c=>!!c));n&&s.add("ai");let a=["ai",...i].filter(c=>!s.has(c)),l=r.length===0;return(0,Re.jsx)($s,{title:(0,At.__)("Connectors"),subTitle:(0,At.__)("All of your API keys and credentials are stored here and shared across plugins. Configure once and use everywhere."),children:(0,Re.jsxs)("div",{className:`connectors-page${l?" connectors-page--empty":""}`,children:[a.length>0&&(e||!o)&&(0,Re.jsx)(nn.Root,{intent:"info",className:"connectors-page__file-mods-notice",children:(0,Re.jsx)(nn.Description,{children:e?(0,At.__)("Plugins cannot be installed here due to your site configuration. Install them manually using your normal deployment workflow."):(0,At.__)("You do not have permission to install plugins. Please ask a site administrator to install them for you.")})}),l?(0,Re.jsxs)(ut.__experimentalVStack,{alignment:"center",spacing:3,style:{maxWidth:480},children:[(0,Re.jsxs)(ut.__experimentalVStack,{alignment:"center",spacing:2,children:[(0,Re.jsx)(ut.__experimentalHeading,{level:2,size:15,children:(0,At.__)("No connectors yet")}),(0,Re.jsx)(ut.__experimentalText,{size:12,children:(0,At.__)("Connectors appear here when you install plugins that use external services. Each plugin registers the API keys it needs, and you manage them all in one place.")})]}),(0,Re.jsx)(ut.Button,{variant:"secondary",href:"plugin-install.php",__next40pxDefaultSize:!0,children:(0,At.__)("Learn more")})]}):(0,Re.jsxs)(ut.__experimentalVStack,{spacing:3,children:[(0,Re.jsx)(jf,{}),(0,Re.jsx)(ut.__experimentalVStack,{spacing:3,role:"list",children:t.map(c=>c.render?(0,Re.jsx)(c.render,{slug:c.slug,name:c.name,description:c.description,type:c.type,logo:c.logo,authentication:c.authentication,plugin:c.plugin},c.slug):null)})]}),o&&!e&&(0,Re.jsx)("p",{children:(0,Vf.createInterpolateElement)((0,At.__)("If the connector you need is not listed, search the plugin directory to see if a connector is available."),{a:(0,Re.jsx)("a",{href:"plugin-install.php?s=connector&tab=search&type=tag"})})})]})})}function Zh(){return(0,Re.jsx)(qh,{})}var Qh=Zh;export{Qh as stage}; +var Zf=Object.create;var Lr=Object.defineProperty;var Qf=Object.getOwnPropertyDescriptor;var Jf=Object.getOwnPropertyNames;var $f=Object.getPrototypeOf,ep=Object.prototype.hasOwnProperty;var ke=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),Mt=(e,t)=>{for(var o in t)Lr(e,o,{get:t[o],enumerable:!0})},tp=(e,t,o,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of Jf(t))!ep.call(e,r)&&r!==o&&Lr(e,r,{get:()=>t[r],enumerable:!(n=Qf(t,r))||n.enumerable});return e};var b=(e,t,o)=>(o=e!=null?Zf($f(e)):{},tp(t||!e||!e.__esModule?Lr(o,"default",{value:e,enumerable:!0}):o,e));var st=ke(($h,da)=>{da.exports=window.wp.i18n});var ce=ke((t0,fa)=>{fa.exports=window.wp.element});var z=ke((o0,pa)=>{pa.exports=window.React});var W=ke((l0,ha)=>{ha.exports=window.ReactJSXRuntime});var Ht=ke((bw,Ua)=>{Ua.exports=window.ReactDOM});var Gc=ke(Uc=>{"use strict";var xo=z();function ng(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var rg=typeof Object.is=="function"?Object.is:ng,ig=xo.useState,sg=xo.useEffect,ag=xo.useLayoutEffect,cg=xo.useDebugValue;function lg(e,t){var o=t(),n=ig({inst:{value:o,getSnapshot:t}}),r=n[0].inst,i=n[1];return ag(function(){r.value=o,r.getSnapshot=t,hi(r)&&i({inst:r})},[e,o,t]),sg(function(){return hi(r)&&i({inst:r}),e(function(){hi(r)&&i({inst:r})})},[e]),cg(o),o}function hi(e){var t=e.getSnapshot;e=e.value;try{var o=t();return!rg(e,o)}catch{return!0}}function dg(e,t){return t()}var ug=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?dg:lg;Uc.useSyncExternalStore=xo.useSyncExternalStore!==void 0?xo.useSyncExternalStore:ug});var Kn=ke((av,Kc)=>{"use strict";Kc.exports=Gc()});var qc=ke(Xc=>{"use strict";var Xn=z(),fg=Kn();function pg(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var mg=typeof Object.is=="function"?Object.is:pg,gg=fg.useSyncExternalStore,bg=Xn.useRef,hg=Xn.useEffect,wg=Xn.useMemo,vg=Xn.useDebugValue;Xc.useSyncExternalStoreWithSelector=function(e,t,o,n,r){var i=bg(null);if(i.current===null){var s={hasValue:!1,value:null};i.current=s}else s=i.current;i=wg(function(){function l(f){if(!c){if(c=!0,d=f,f=n(f),r!==void 0&&s.hasValue){var p=s.value;if(r(p,f))return m=p}return m=f}if(p=m,mg(d,f))return p;var g=n(f);return r!==void 0&&r(p,g)?(d=f,p):(d=f,m=g)}var c=!1,d,m,u=o===void 0?null:o;return[function(){return l(t())},u===null?void 0:function(){return l(u())}]},[t,o,n,r]);var a=gg(e,i[0],i[1]);return hg(function(){s.hasValue=!0,s.value=a},[a]),vg(a),a}});var Qc=ke((lv,Zc)=>{"use strict";Zc.exports=qc()});var Gd=ke((I4,Ud)=>{Ud.exports=window.wp.theme});var Ji=ke((L4,Kd)=>{Kd.exports=window.wp.privateApis});var ao=ke((a5,au)=>{au.exports=window.wp.primitives});var an=ke((U3,lf)=>{lf.exports=window.wp.components});var ln=ke((i8,hf)=>{hf.exports=window.wp.data});var Tr=ke((s8,wf)=>{wf.exports=window.wp.coreData});var ea=ke((l8,_f)=>{_f.exports=window.wp.notices});var xf=ke((d8,yf)=>{yf.exports=window.wp.url});function ua(e){var t,o,n="";if(typeof e=="string"||typeof e=="number")n+=e;else if(typeof e=="object")if(Array.isArray(e)){var r=e.length;for(t=0;te();function Y(e){let t=Te(ip).current;return t.next=e,rp(t.effect),t.trampoline}function ip(){let e={next:void 0,callback:sp,trampoline:(...t)=>e.callback?.(...t),effect:()=>{e.callback=e.next}};return e}function sp(){}var ba=b(z(),1),ap=()=>{},F=typeof document<"u"?ba.useLayoutEffect:ap;function cp(e,t){return function(n,...r){let i=new URL(e);return i.searchParams.set("code",n.toString()),r.forEach(s=>i.searchParams.append("args[]",s)),`${t} error #${n}; visit ${i} for the full message.`}}var lp=cp("https://base-ui.com/production-error","Base UI"),De=lp;var qt=b(z(),1);function Br(e,t,o,n){let r=Te(va).current;return dp(r,e,t,o,n)&&_a(r,[e,t,o,n]),r.callback}function wa(e){let t=Te(va).current;return up(t,e)&&_a(t,e),t.callback}function va(){return{callback:null,cleanup:null,refs:[]}}function dp(e,t,o,n,r){return e.refs[0]!==t||e.refs[1]!==o||e.refs[2]!==n||e.refs[3]!==r}function up(e,t){return e.refs.length!==t.length||e.refs.some((o,n)=>o!==t[n])}function _a(e,t){if(e.refs=t,t.every(o=>o==null)){e.callback=null;return}e.callback=o=>{if(e.cleanup&&(e.cleanup(),e.cleanup=null),o!=null){let n=Array(t.length).fill(null);for(let r=0;r{for(let r=0;r=e}function Hr(e){if(!xa.isValidElement(e))return null;let t=e,o=t.props;return(po(19)?o?.ref:t.ref)??null}function zo(e,t){if(e&&!t)return e;if(!e&&t)return t;if(e||t)return{...e,...t}}function Ge(){}var Sa=Object.freeze([]),me=Object.freeze({});function Ra(e,t){let o={};for(let n in e){let r=e[n];if(t?.hasOwnProperty(n)){let i=t[n](r);i!=null&&Object.assign(o,i);continue}r===!0?o[`data-${n.toLowerCase()}`]="":r&&(o[`data-${n.toLowerCase()}`]=r.toString())}return o}function Ea(e,t){return typeof e=="function"?e(t):e}function ka(e,t){return typeof e=="function"?e(t):e}var zr={};function ve(e,t,o,n,r){if(!o&&!n&&!r&&!e)return xn(t);let i=xn(e);return t&&(i=Do(i,t)),o&&(i=Do(i,o)),n&&(i=Do(i,n)),r&&(i=Do(i,r)),i}function Ta(e){if(e.length===0)return zr;if(e.length===1)return xn(e[0]);let t=xn(e[0]);for(let o=1;o=65&&r<=90&&(typeof t=="function"||typeof t>"u")}function Dr(e){return typeof e=="function"}function Ca(e,t){return Dr(e)?e(t):e??zr}function gp(e,t){return t?e?(...o)=>{let n=o[0];if(Oa(n)){let i=n;jo(i);let s=t(...o);return i.baseUIHandlerPrevented||e?.(...o),s}let r=t(...o);return e?.(...o),r}:Aa(t):e}function Aa(e){return e&&((...t)=>{let o=t[0];return Oa(o)&&jo(o),e(...t)})}function jo(e){return e.preventBaseUIHandler=()=>{e.baseUIHandlerPrevented=!0},e}function jr(e,t){return t?e?t+" "+e:t:e}function Oa(e){return e!=null&&typeof e=="object"&&"nativeEvent"in e}var Fr=b(z(),1);function Oe(e,t,o={}){let n=t.render,r=bp(t,o);if(o.enabled===!1)return null;let i=o.state??me;return vp(e,n,r,i)}function bp(e,t={}){let{className:o,style:n,render:r}=e,{state:i=me,ref:s,props:a,stateAttributesMapping:l,enabled:c=!0}=t,d=c?Ea(o,i):void 0,m=c?ka(n,i):void 0,u=c?Ra(i,l):me,f=c&&a?hp(a):void 0,p=c?zo(u,f)??{}:me;return typeof document<"u"&&(c?Array.isArray(s)?p.ref=wa([p.ref,Hr(r),...s]):p.ref=Br(p.ref,Hr(r),s):Br(null,null)),c?(d!==void 0&&(p.className=jr(p.className,d)),m!==void 0&&(p.style=zo(p.style,m)),p):me}function hp(e){return Array.isArray(e)?Ta(e):ve(void 0,e)}var wp=Symbol.for("react.lazy");function vp(e,t,o,n){if(t){if(typeof t=="function")return t(o,n);let r=ve(o,t.props);r.ref=o.ref;let i=t;return i?.$$typeof===wp&&(i=qt.Children.toArray(t)[0]),qt.cloneElement(i,r)}if(e&&typeof e=="string")return _p(e,o);throw new Error(De(8))}function _p(e,t){return e==="button"?(0,Fr.createElement)("button",{type:"button",...t,key:t.key}):e==="img"?(0,Fr.createElement)("img",{alt:"",...t,key:t.key}):qt.createElement(e,t)}var Sn=b(z(),1);var Na=0;function yp(e,t="mui"){let[o,n]=Sn.useState(e),r=e||o;return Sn.useEffect(()=>{o==null&&(Na+=1,n(`${t}-${Na}`))},[o,t]),r}var Ia=Ho.useId;function mo(e,t){if(Ia!==void 0){let o=Ia();return e??(t?`${t}-${o}`:o)}return yp(e,t)}function La(e){return mo(e,"base-ui")}var G={};Mt(G,{cancelOpen:()=>qp,chipRemovePress:()=>Op,clearPress:()=>Ap,closePress:()=>Pp,closeWatcher:()=>Vp,decrementPress:()=>Lp,disabled:()=>Qp,drag:()=>Gp,escapeKey:()=>Fp,focusOut:()=>jp,imperativeAction:()=>em,incrementPress:()=>Ip,initial:()=>$p,inputBlur:()=>Hp,inputChange:()=>Mp,inputClear:()=>Bp,inputPaste:()=>zp,inputPress:()=>Dp,itemPress:()=>Tp,keyboard:()=>Yp,linkPress:()=>Cp,listNavigation:()=>Wp,missing:()=>Jp,none:()=>xp,outsidePress:()=>kp,pointer:()=>Up,scrub:()=>Xp,siblingOpen:()=>Zp,swipe:()=>tm,trackPress:()=>Np,triggerFocus:()=>Ep,triggerHover:()=>Rp,triggerPress:()=>Sp,wheel:()=>Kp,windowResize:()=>om});var xp="none",Sp="trigger-press",Rp="trigger-hover",Ep="trigger-focus",kp="outside-press",Tp="item-press",Pp="close-press",Cp="link-press",Ap="clear-press",Op="chip-remove-press",Np="track-press",Ip="increment-press",Lp="decrement-press",Mp="input-change",Bp="input-clear",Hp="input-blur",zp="input-paste",Dp="input-press",jp="focus-out",Fp="escape-key",Vp="close-watcher",Wp="list-navigation",Yp="keyboard",Up="pointer",Gp="drag",Kp="wheel",Xp="scrub",qp="cancel-open",Zp="sibling-open",Qp="disabled",Jp="missing",$p="initial",em="imperative-action",tm="swipe",om="window-resize";function ee(e,t,o,n){let r=!1,i=!1,s=n??me;return{reason:e,event:t??new Event("base-ui"),cancel(){r=!0},allowPropagation(){i=!0},get isCanceled(){return r},get isPropagationAllowed(){return i},trigger:o,...s}}var Wr=b(z(),1);var Ma=b(z(),1);function go(e){Ma.useEffect(e,Sa)}var Rn=null,Y0=globalThis.requestAnimationFrame,Vr=class{callbacks=[];callbacksCount=0;nextId=1;startId=1;isScheduled=!1;tick=t=>{this.isScheduled=!1;let o=this.callbacks,n=this.callbacksCount;if(this.callbacks=[],this.callbacksCount=0,this.startId=this.nextId,n>0)for(let r=0;r=this.callbacks.length||(this.callbacks[o]=null,this.callbacksCount-=1)}},En=new Vr;var gt=class e{static create(){return new e}static request(t){return En.request(t)}static cancel(t){return En.cancel(t)}currentId=Rn;request(t){this.cancel(),this.currentId=En.request(()=>{this.currentId=Rn,t()})}cancel=()=>{this.currentId!==Rn&&(En.cancel(this.currentId),this.currentId=Rn)};disposeEffect=()=>this.cancel};function bo(){let e=Te(gt.create).current;return go(e.disposeEffect),e}function Ba(e,t=!1,o=!1){let[n,r]=Wr.useState(e&&t?"idle":void 0),[i,s]=Wr.useState(e);return e&&!i&&(s(!0),r("starting")),!e&&i&&n!=="ending"&&!o&&r("ending"),!e&&!i&&n==="ending"&&r(void 0),F(()=>{if(!e&&i&&n!=="ending"&&o){let a=gt.request(()=>{r("ending")});return()=>{gt.cancel(a)}}},[e,i,n,o]),F(()=>{if(!e||t)return;let a=gt.request(()=>{r(void 0)});return()=>{gt.cancel(a)}},[t,e]),F(()=>{if(!e||!t)return;e&&i&&n!=="idle"&&r("starting");let a=gt.request(()=>{r("idle")});return()=>{gt.cancel(a)}},[t,e,i,n]),{mounted:i,setMounted:s,transitionStatus:n}}var Yr=(function(e){return e.startingStyle="data-starting-style",e.endingStyle="data-ending-style",e})({}),nm={"data-starting-style":""},rm={"data-ending-style":""},Ha={transitionStatus(e){return e==="starting"?nm:e==="ending"?rm:null}};var wo=b(z(),1);function kn(){return typeof window<"u"}function Qt(e){return Tn(e)?(e.nodeName||"").toLowerCase():"#document"}function fe(e){var t;return(e==null||(t=e.ownerDocument)==null?void 0:t.defaultView)||window}function ht(e){var t;return(t=(Tn(e)?e.ownerDocument:e.document)||window.document)==null?void 0:t.documentElement}function Tn(e){return kn()?e instanceof Node||e instanceof fe(e).Node:!1}function U(e){return kn()?e instanceof Element||e instanceof fe(e).Element:!1}function he(e){return kn()?e instanceof HTMLElement||e instanceof fe(e).HTMLElement:!1}function ho(e){return!kn()||typeof ShadowRoot>"u"?!1:e instanceof ShadowRoot||e instanceof fe(e).ShadowRoot}function Fo(e){let{overflow:t,overflowX:o,overflowY:n,display:r}=Le(e);return/auto|scroll|overlay|hidden|clip/.test(t+n+o)&&r!=="inline"&&r!=="contents"}function za(e){return/^(table|td|th)$/.test(Qt(e))}function Vo(e){try{if(e.matches(":popover-open"))return!0}catch{}try{return e.matches(":modal")}catch{return!1}}var im=/transform|translate|scale|rotate|perspective|filter/,sm=/paint|layout|strict|content/,Zt=e=>!!e&&e!=="none",Ur;function Pn(e){let t=U(e)?Le(e):e;return Zt(t.transform)||Zt(t.translate)||Zt(t.scale)||Zt(t.rotate)||Zt(t.perspective)||!Cn()&&(Zt(t.backdropFilter)||Zt(t.filter))||im.test(t.willChange||"")||sm.test(t.contain||"")}function Da(e){let t=bt(e);for(;he(t)&&!wt(t);){if(Pn(t))return t;if(Vo(t))return null;t=bt(t)}return null}function Cn(){return Ur==null&&(Ur=typeof CSS<"u"&&CSS.supports&&CSS.supports("-webkit-backdrop-filter","none")),Ur}function wt(e){return/^(html|body|#document)$/.test(Qt(e))}function Le(e){return fe(e).getComputedStyle(e)}function Wo(e){return U(e)?{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}:{scrollLeft:e.scrollX,scrollTop:e.scrollY}}function bt(e){if(Qt(e)==="html")return e;let t=e.assignedSlot||e.parentNode||ho(e)&&e.host||ht(e);return ho(t)?t.host:t}function ja(e){let t=bt(e);return wt(t)?(e.ownerDocument||e).body:he(t)&&Fo(t)?t:ja(t)}function Bt(e,t,o){var n;t===void 0&&(t=[]),o===void 0&&(o=!0);let r=ja(e),i=r===((n=e.ownerDocument)==null?void 0:n.body),s=fe(r);if(i){let a=An(s);return t.concat(s,s.visualViewport||[],Fo(r)?r:[],a&&o?Bt(a):[])}else return t.concat(r,Bt(r,[],o))}function An(e){return e.parent&&Object.getPrototypeOf(e.parent)?e.frameElement:null}var On=b(z(),1),am=On.createContext(void 0);function Fa(e=!1){let t=On.useContext(am);if(t===void 0&&!e)throw new Error(De(16));return t}var Va=b(z(),1);function Wa(e){let{focusableWhenDisabled:t,disabled:o,composite:n=!1,tabIndex:r=0,isNativeButton:i}=e,s=n&&t!==!1,a=n&&t===!1;return{props:Va.useMemo(()=>{let c={onKeyDown(d){o&&t&&d.key!=="Tab"&&d.preventDefault()}};return n||(c.tabIndex=r,!i&&o&&(c.tabIndex=t?r:-1)),(i&&(t||s)||!i&&o)&&(c["aria-disabled"]=o),i&&(!t||a)&&(c.disabled=o),c},[n,o,t,s,a,i,r])}}function Pe(e){return e?.ownerDocument||document}function Nn(e,t,{detail:o=0}={}){e.dispatchEvent(new(fe(e)).PointerEvent("click",{bubbles:!0,cancelable:!0,composed:!0,detail:o,shiftKey:t.shiftKey,ctrlKey:t.ctrlKey,altKey:t.altKey,metaKey:t.metaKey}))}function Ya(e={}){let{disabled:t=!1,focusableWhenDisabled:o,tabIndex:n=0,native:r=!0,composite:i}=e,s=wo.useRef(null),a=Fa(!0),l=i??a!==void 0,{props:c}=Wa({focusableWhenDisabled:o,disabled:t,composite:l,tabIndex:n,isNativeButton:r}),d=wo.useCallback(()=>{let f=s.current;Gr(f)&&l&&t&&c.disabled===void 0&&f.disabled&&(f.disabled=!1)},[t,c.disabled,l]);F(d,[d]);let m=wo.useCallback((f={})=>{let{onClick:p,onMouseDown:g,onKeyUp:h,onKeyDown:y,onPointerDown:_,...v}=f;return ve({onClick(w){if(t){w.preventDefault();return}p?.(w)},onMouseDown(w){t||g?.(w)},onKeyDown(w){if(t||(jo(w),y?.(w),w.baseUIHandlerPrevented))return;let R=w.target===w.currentTarget,x=w.currentTarget,S=Gr(x),E=!r&&cm(x),k=R&&(r?S:!E),P=w.key==="Enter",N=w.key===" ",H=x.getAttribute("role"),j=H?.startsWith("menuitem")||H==="option"||H==="gridcell";if(R&&l&&N){if(w.defaultPrevented&&j)return;w.preventDefault(),(!r||S)&&(w.preventBaseUIHandler(),Nn(x,w));return}if(!k||r||!N&&!P){R&&E&&N&&w.preventDefault();return}w.defaultPrevented||(w.preventDefault(),P&&(w.preventBaseUIHandler(),Nn(x,w)))},onKeyUp(w){if(!t){if(jo(w),h?.(w),w.target===w.currentTarget&&r&&l&&Gr(w.currentTarget)&&w.key===" "){w.preventDefault();return}w.baseUIHandlerPrevented||w.target===w.currentTarget&&!r&&!l&&!w.defaultPrevented&&w.key===" "&&(w.preventBaseUIHandler(),Nn(w.currentTarget,w))}},onPointerDown(w){if(t){w.preventDefault();return}_?.(w)}},r?{type:"button"}:{role:"button"},c,v)},[t,c,l,r]),u=Y(f=>{s.current=f,d()});return{getButtonProps:m,buttonRef:u}}function Gr(e){return he(e)&&e.tagName==="BUTTON"}function cm(e){return he(e)&&e.tagName==="A"&&!!e.href}function oe(e,t,o,n){return e.addEventListener(t,o,n),()=>{e.removeEventListener(t,o,n)}}function je(e){let t=Te(lm,e).current;return t.next=e,F(t.effect),t}function lm(e){let t={current:e,next:e,effect:()=>{t.current=t.next}};return t}var Xa=b(z(),1);var Ka=b(Ht(),1);function Ga(e){return e==null?e:"current"in e?e.current:e}function vo(e,t=!1){let o=bo();return Y((n,r=null)=>{o.cancel();let i=Ga(e);if(i==null)return;let s=i,a=()=>{Ka.flushSync(n)};if(typeof s.getAnimations!="function"||globalThis.BASE_UI_ANIMATIONS_DISABLED){n();return}function l(){Promise.all(s.getAnimations().map(c=>c.finished)).then(()=>{r?.aborted||a()},()=>{if(r?.aborted)return;if(s.getAnimations().some(d=>d.pending||d.playState!=="finished")){l();return}a()})}if(t){let c="data-starting-style";if(!s.hasAttribute(c)){o.request(l);return}let d=new MutationObserver(()=>{s.hasAttribute(c)||(d.disconnect(),l())});d.observe(s,{attributes:!0,attributeFilter:[c]}),r?.addEventListener("abort",()=>d.disconnect(),{once:!0});return}o.request(l)})}function In(e){let{enabled:t=!0,open:o,ref:n,onComplete:r}=e,i=Y(r),s=vo(n,o);Xa.useEffect(()=>{if(!t)return;let a=new AbortController;return s(i,a.signal),()=>{a.abort()}},[t,o,i,s])}var Tt={};Mt(Tt,{engine:()=>Qr,env:()=>$r,os:()=>qr,screenReader:()=>Jr});var qr={};Mt(qr,{android:()=>Qa,apple:()=>Xr,ios:()=>Kr,linux:()=>mm,mac:()=>Ja,windows:()=>pm});function dm(){return typeof navigator>"u"?{userAgent:"",platform:"",maxTouchPoints:0}:{userAgent:navigator.userAgent,platform:navigator.platform??"",maxTouchPoints:navigator.maxTouchPoints??0}}var{userAgent:um,platform:fm,maxTouchPoints:qa}=dm(),Jt=um.toLowerCase(),$t=fm.toLowerCase();var Kr=/^i(os$|p)/.test($t)||$t==="macintel"&&qa>1,Za="android",Qa=$t===Za||Jt.includes(Za),Ja=!Kr&&$t.startsWith("mac"),pm=$t.startsWith("win"),mm=!Qa&&/^(linux|chrome os)/.test($t),Xr=Ja||Kr;var Qr={};Mt(Qr,{blink:()=>bm,gecko:()=>gm,webkit:()=>Zr});var Zr=typeof CSS<"u"&&!!CSS.supports?.("-webkit-backdrop-filter:none"),gm=!Zr&&Jt.includes("firefox"),bm=!Zr&&Jt.includes("chrom");var Jr={};Mt(Jr,{voiceOver:()=>hm});var hm=Xr;var $r={};Mt($r,{jsdom:()=>wm});var wm=/jsdom|happydom/.test(Jt);var Yo=0,Ke=class e{static create(){return new e}currentId=Yo;start(t,o){this.clear(),this.currentId=setTimeout(()=>{this.currentId=Yo,o()},t)}isStarted(){return this.currentId!==Yo}clear=()=>{this.currentId!==Yo&&(clearTimeout(this.currentId),this.currentId=Yo)};disposeEffect=()=>this.clear};function at(){let e=Te(Ke.create).current;return go(e.disposeEffect),e}var Be=b(z(),1);function $a(e){return"nativeEvent"in e}function Pt(e,t){let o=["mouse","pen"];return t||o.push("",void 0),o.includes(e)}function ec(e){let t=e.type;return t==="click"||t==="mousedown"||t==="keydown"||t==="keyup"}var ei="data-base-ui-focusable";var ti="input:not([type='hidden']):not([disabled]),[contenteditable]:not([contenteditable='false']),textarea:not([disabled])";function Ln(e){let t=e.activeElement;for(;t?.shadowRoot?.activeElement!=null;)t=t.shadowRoot.activeElement;return t}function re(e,t){if(!e||!t)return!1;let o=t.getRootNode?.();if(e.contains(t))return!0;if(o&&ho(o)){let n=t;for(;n;){if(e===n)return!0;n=n.parentNode||n.host}}return!1}function Me(e){return"composedPath"in e?e.composedPath()[0]:e.target}function zt(e,t){if(!U(e))return!1;let o=e;if(t.hasElement(o))return!o.hasAttribute("data-trigger-disabled");for(let[,n]of t.entries())if(re(n,o))return!n.hasAttribute("data-trigger-disabled");return!1}function Mn(e,t){if(t==null)return!1;if("composedPath"in e)return e.composedPath().includes(t);let o=e;return o.target!=null&&t.contains(o.target)}function tc(e){return e.matches("html,body")}function oc(e){return he(e)&&e.matches(ti)}function oi(e){return e?.closest(`button,a[href],[role="button"],select,[tabindex]:not([tabindex="-1"]),${ti}`)!=null}function nc(e){if(!e||Tt.env.jsdom)return!0;try{return e.matches(":focus-visible")}catch{return!0}}function vm(e,t){return t!=null&&!Pt(t)?0:typeof e=="function"?e():e}function $e(e,t,o){let n=vm(e,o);return typeof n=="number"?n:n?.[t]}function ni(e){return typeof e=="function"?e():e}function Bn(e,t){return t||e==="click"||e==="mousedown"}function rc(e){return e?.includes("mouse")&&e!=="mousedown"}var ic=b(W(),1),sc=Be.createContext({hasProvider:!1,timeoutMs:0,delayRef:{current:0},initialDelayRef:{current:0},timeout:new Ke,currentIdRef:{current:null},currentContextRef:{current:null}});function _m(e,t){e.current=t.current}function ri(e){let{children:t,delay:o,timeoutMs:n=0}=e,r=Be.useRef(o),i=Be.useRef(o),s=Be.useRef(null),a=Be.useRef(null),l=at();return F(()=>{if(i.current=o,!s.current){r.current=o;return}r.current={open:$e(r.current,"open"),close:$e(o,"close")}},[o,s,r,i]),(0,ic.jsx)(sc.Provider,{value:Be.useMemo(()=>({hasProvider:!0,delayRef:r,initialDelayRef:i,currentIdRef:s,timeoutMs:n,currentContextRef:a,timeout:l}),[n,l]),children:t})}function ii(e,t={open:!1}){let{open:o}=t,n="rootStore"in e?e.rootStore:e,r=n.useState("floatingId"),i=Be.useContext(sc),{currentIdRef:s,delayRef:a,timeoutMs:l,initialDelayRef:c,currentContextRef:d,hasProvider:m,timeout:u}=i,[f,p]=Be.useState(!1),g=Be.useRef(o);return F(()=>{g.current=o},[o]),F(()=>{function h(){d.current?.setIsInstantPhase(!1),s.current=null,d.current=null,a.current=c.current,u.clear()}if(s.current&&!o&&s.current===r){if(p(!1),l){let y=r;return u.start(l,()=>{n.select("open")||s.current&&s.current!==y||h()}),()=>{(g.current||s.current!==y)&&u.clear()}}h()}},[o,r,s,a,l,c,d,u,n]),F(()=>{if(!o)return;let h=d.current,y=s.current;u.clear(),d.current={onOpenChange:n.setOpen,setIsInstantPhase:p},s.current=r,a.current={open:0,close:$e(c.current,"close")},y!==null&&y!==r?(p(!0),h?.setIsInstantPhase(!0),h?.onOpenChange(!1,ee(G.none))):(p(!1),h?.setIsInstantPhase(!1))},[o,r,n,s,a,c,d,u]),F(()=>()=>{if(s.current===r){if(d.current=null,!g.current)return;s.current=null,_m(a,c),u.clear()}},[d,s,a,r,c,u]),Be.useMemo(()=>({hasProvider:m,delayRef:a,isInstantPhase:f}),[m,a,f])}function ct(...e){return()=>{for(let t=0;t({x:e,y:e}),ym={left:"right",right:"left",bottom:"top",top:"bottom"};function zn(e,t,o){return lt(e,Dt(t,o))}function _t(e,t){return typeof e=="function"?e(t):e}function Ne(e){return e.split("-")[0]}function dt(e){return e.split("-")[1]}function Dn(e){return e==="x"?"y":"x"}function Ko(e){return e==="y"?"height":"width"}function Fe(e){let t=e[0];return t==="t"||t==="b"?"y":"x"}function Xo(e){return Dn(Fe(e))}function lc(e,t,o){o===void 0&&(o=!1);let n=dt(e),r=Xo(e),i=Ko(r),s=r==="x"?n===(o?"end":"start")?"right":"left":n==="start"?"bottom":"top";return t.reference[i]>t.floating[i]&&(s=Uo(s)),[s,Uo(s)]}function dc(e){let t=Uo(e);return[Hn(e),t,Hn(t)]}function Hn(e){return e.includes("start")?e.replace("start","end"):e.replace("end","start")}var ac=["left","right"],cc=["right","left"],xm=["top","bottom"],Sm=["bottom","top"];function Rm(e,t,o){switch(e){case"top":case"bottom":return o?t?cc:ac:t?ac:cc;case"left":case"right":return t?xm:Sm;default:return[]}}function uc(e,t,o,n){let r=dt(e),i=Rm(Ne(e),o==="start",n);return r&&(i=i.map(s=>s+"-"+r),t&&(i=i.concat(i.map(Hn)))),i}function Uo(e){let t=Ne(e);return ym[t]+e.slice(t.length)}function Em(e){var t,o,n,r;return{top:(t=e.top)!=null?t:0,right:(o=e.right)!=null?o:0,bottom:(n=e.bottom)!=null?n:0,left:(r=e.left)!=null?r:0}}function jn(e){return typeof e!="number"?Em(e):{top:e,right:e,bottom:e,left:e}}function eo(e){let{x:t,y:o,width:n,height:r}=e;return{width:n,height:r,top:o,left:t,right:t+n,bottom:o+r,x:t,y:o}}function Ct(e,t,o=!0){return e.filter(r=>r.parentId===t).flatMap(r=>[...!o||r.context?.open?[r]:[],...Ct(e,r.id,o)])}function _o(e){return`data-base-ui-${e}`}var He=b(z(),1),mc=b(Ht(),1);var fc={style:{transition:"none"}};var km="data-base-ui-swipe-ignore",Tm="data-swipe-ignore",o1=`[${km}]`,n1=`[${Tm}]`;var pc={fallbackAxisSide:"end"};var gc=b(W(),1),Pm=He.createContext(null),Cm=()=>He.useContext(Pm),Am=_o("portal");function bc(e={}){let{ref:t,container:o,componentProps:n=me,elementProps:r}=e,i=mo(),a=Cm()?.portalNode,[l,c]=He.useState(null),[d,m]=He.useState(null),u=Y(h=>{h!==null&&m(h)}),f=He.useRef(null);F(()=>{if(o===null){f.current&&(f.current=null,m(null),c(null));return}let h=(o&&(Tn(o)?o:o.current))??a??document.body;if(h==null){f.current&&(f.current=null,m(null),c(null));return}f.current!==h&&(f.current=h,m(null),c(h))},[o,a]);let p=Oe("div",n,{ref:[t,u],props:[{id:i,[Am]:""},r]}),g=l&&p?mc.createPortal(p,l):null;return{node:d,nodeId:He.isValidElement(p)?p.props.id:void 0,subtree:g}}var to=b(z(),1);function hc(){let e=new Map;return{emit(t,o){e.get(t)?.forEach(n=>n(o))},on(t,o){e.has(t)||e.set(t,new Set),e.get(t).add(o)},off(t,o){e.get(t)?.delete(o)}}}var Om=b(W(),1),Nm=to.createContext(null),Im=to.createContext(null),Fn=()=>to.useContext(Nm)?.id||null,Ft=e=>{let t=to.useContext(Im);return e??t};var Ve=b(z(),1);function Lm(e,t){let o=null,n=null,r=!1;return{contextElement:e||void 0,getBoundingClientRect(){let i=e?.getBoundingClientRect()||{width:0,height:0,x:0,y:0},s=t.axis==="x"||t.axis==="both",a=t.axis==="y"||t.axis==="both",l=["mouseenter","mousemove"].includes(t.dataRef.current.openEvent?.type||"")&&t.pointerType!=="touch",c=i.width,d=i.height,m=i.x,u=i.y;return o==null&&t.x&&s&&(o=i.x-t.x),n==null&&t.y&&a&&(n=i.y-t.y),m-=o||0,u-=n||0,c=0,d=0,!r||l?(c=t.axis==="y"?i.width:0,d=t.axis==="x"?i.height:0,m=s&&t.x!=null?t.x:m,u=a&&t.y!=null?t.y:u):r&&!l&&(d=t.axis==="x"?i.height:d,c=t.axis==="y"?i.width:c),r=!0,{width:c,height:d,x:m,y:u,top:u,right:m+c,bottom:u+d,left:m}}}}function wc(e){return e!=null&&e.clientX!=null}function si(e,t={}){let{enabled:o=!0,axis:n="both"}=t,r="rootStore"in e?e.rootStore:e,i=r.useState("open"),s=r.useState("floatingElement"),a=r.useState("domReferenceElement"),l=r.context.dataRef,c=Ve.useRef(!1),d=Ve.useRef(null),[m,u]=Ve.useState(),[f,p]=Ve.useState([]),g=Y(w=>{r.set("positionReference",w)}),h=Y((w,R,x)=>{c.current||l.current.openEvent&&!wc(l.current.openEvent)||r.set("positionReference",Lm(x??a,{x:w,y:R,axis:n,dataRef:l,pointerType:m}))}),y=Y(w=>{i?d.current||(h(w.clientX,w.clientY,w.currentTarget),p([])):h(w.clientX,w.clientY,w.currentTarget)}),_=Pt(m)?s:i;Ve.useEffect(()=>{if(!o){g(a);return}if(!_)return;function w(){d.current?.(),d.current=null}let R=fe(s);function x(S){let E=Me(S);re(s,E)?w():h(S.clientX,S.clientY)}return!l.current.openEvent||wc(l.current.openEvent)?d.current=oe(R,"mousemove",x):g(a),w},[_,o,s,l,a,r,h,g,f]),Ve.useEffect(()=>()=>{r.set("positionReference",null)},[r]),Ve.useEffect(()=>{o&&!s&&(c.current=!1)},[o,s]),Ve.useEffect(()=>{!o&&i&&(c.current=!0)},[o,i]);let v=Ve.useMemo(()=>{function w(R){u(R.pointerType)}return{onPointerDown:w,onPointerEnter:w,onMouseMove:y,onMouseEnter:y}},[y]);return Ve.useMemo(()=>o?{reference:v,trigger:v}:{},[o,v])}var Xe=b(z(),1);function Mm(){return!1}function Bm(e){return{escapeKey:typeof e=="boolean"?e:e?.escapeKey??!1,outsidePress:typeof e=="boolean"?e:e?.outsidePress??!0}}function ai(e,t={}){let{enabled:o=!0,escapeKey:n=!0,outsidePress:r=!0,outsidePressEvent:i="sloppy",referencePress:s=Mm,bubbles:a,externalTree:l}=t,c="rootStore"in e?e.rootStore:e,d=c.useState("open"),m=c.useState("floatingElement"),{dataRef:u}=c.context,f=Ft(l),p=Y(typeof r=="function"?r:()=>!1),g=typeof r=="function"?p:r,h=g!==!1,y=Y(()=>i),{escapeKey:_,outsidePress:v}=Bm(a),w=Xe.useRef(!1),R=Xe.useRef(!1),x=Xe.useRef(!1),S=Xe.useRef(!1),E=Xe.useRef(""),k=Xe.useRef(null),P=at(),N=at(),H=Y(()=>{N.clear(),u.current.insideReactTree=!1}),j=Y(O=>{let V=u.current.floatingContext?.nodeId;return(f?Ct(f.nodesRef.current,V):[]).some(ie=>ie.context?.open&&!ie.context.dataRef.current[O])}),L=Y(O=>Mn(O,c.select("floatingElement"))||Mn(O,c.select("domReferenceElement"))),T=Y(O=>{s()&&c.setOpen(!1,ee(G.triggerPress,O.nativeEvent))}),I=Y(O=>{if(!d||!o||!n||O.key!=="Escape"||S.current||!_&&j("__escapeKeyBubbles"))return;let V=$a(O)?O.nativeEvent:O,Z=ee(G.escapeKey,V);c.setOpen(!1,Z),Z.isCanceled||O.preventDefault(),!_&&!Z.isPropagationAllowed&&O.stopPropagation()}),C=Y(()=>{u.current.insideReactTree=!0,N.start(0,H)}),A=Y(O=>{if(!d||!o||O.button!==0)return;let V=Me(O.nativeEvent);re(c.select("floatingElement"),V)&&(w.current||(w.current=!0,R.current=!1))}),M=Y(O=>{!d||!o||(O.defaultPrevented||O.nativeEvent.defaultPrevented)&&w.current&&(R.current=!0)});Xe.useEffect(()=>{if(!d||!o)return H;u.current.__escapeKeyBubbles=_,u.current.__outsidePressBubbles=v;let O=new Ke,V=new Ke;function Z(){O.clear(),S.current=!0}function ie(){O.start(Tt.engine.webkit?5:0,()=>{S.current=!1})}function K(){x.current=!0,V.start(0,()=>{x.current=!1})}function Q(){w.current=!1,R.current=!1}function q(){let B=E.current,D=B==="pen"||!B?"mouse":B,Se=y(),Ae=typeof Se=="function"?Se():Se;return typeof Ae=="string"?Ae:Ae[D]}function $(B){let D=q();return D==="intentional"&&B.type!=="click"||D==="sloppy"&&B.type==="click"}function ne(B){let D=u.current.floatingContext?.nodeId,Se=f&&Ct(f.nodesRef.current,D).some(Ae=>Mn(B,Ae.context?.elements.floating));return L(B)||Se}function se(B){if($(B)){B.type!=="click"&&!L(B)&&(V.clear(),x.current=!1),H();return}if(u.current.insideReactTree){H();return}let D=Me(B),Se=`[${_o("inert")}]`,Ae=U(D)?D.getRootNode():null,Nt=Array.from((ho(Ae)?Ae:Pe(c.select("floatingElement"))).querySelectorAll(Se)),it=c.context.triggerElements;if(D&&(it.hasElement(D)||it.hasMatchingElement(Ye=>re(Ye,D))))return;let It=U(D)?D:null;for(;It&&!wt(It);){let Ye=bt(It);if(wt(Ye)||!U(Ye))break;It=Ye}if(!(Nt.length&&U(D)&&!tc(D)&&!re(D,c.select("floatingElement"))&&Nt.every(Ye=>!re(It,Ye)))){if(he(D)&&!("touches"in B)){let Ye=wt(D),uo=Le(D),Xt=/auto|scroll/,gn=Ye||Xt.test(uo.overflowX),fo=Ye||Xt.test(uo.overflowY),Lt=gn&&D.clientWidth>0&&D.scrollWidth>D.clientWidth,bn=fo&&D.clientHeight>0&&D.scrollHeight>D.clientHeight,hn=uo.direction==="rtl",wn=bn&&(hn?B.offsetX<=D.offsetWidth-D.clientWidth:B.offsetX>D.clientWidth),vn=Lt&&B.offsetY>D.clientHeight;if(wn||vn)return}if(!ne(B)){if(q()==="intentional"&&x.current){V.clear(),x.current=!1;return}typeof g=="function"&&!g(B)||j("__outsidePressBubbles")||(c.setOpen(!1,ee(G.outsidePress,B)),H())}}}function ze(B){q()!=="sloppy"||B.pointerType==="touch"||!c.select("open")||!o||L(B)||se(B)}function ae(B){if(q()!=="sloppy"||!c.select("open")||!o||L(B))return;let D=B.touches[0];D&&(k.current={startTime:Date.now(),startX:D.clientX,startY:D.clientY,dismissOnTouchEnd:!1,dismissOnMouseDown:!0},P.start(1e3,()=>{k.current&&(k.current.dismissOnTouchEnd=!1,k.current.dismissOnMouseDown=!1)}))}function ge(B,D){let Se=Me(B);if(!Se)return;let Ae=oe(Se,B.type,()=>{D(B),Ae()})}function be(B){E.current="touch",ge(B,ae)}function Ee(B){P.clear(),B.type==="pointerdown"&&(E.current=B.pointerType),!(B.type==="mousedown"&&k.current&&!k.current.dismissOnMouseDown)&&ge(B,D=>{D.type==="pointerdown"?ze(D):se(D)})}function ye(B){if(!w.current)return;let D=R.current;if(Q(),q()==="intentional"){if(B.type==="pointercancel"){D&&K();return}if(!ne(B)){if(D){K();return}typeof g=="function"&&!g(B)||(V.clear(),x.current=!0,H())}}}function Kt(B){if(q()!=="sloppy"||!k.current||L(B))return;let D=B.touches[0];if(!D)return;let Se=Math.abs(D.clientX-k.current.startX),Ae=Math.abs(D.clientY-k.current.startY),Nt=Math.sqrt(Se*Se+Ae*Ae);Nt>5&&(k.current.dismissOnTouchEnd=!0),Nt>10&&(se(B),P.clear(),k.current=null)}function rt(B){ge(B,Kt)}function ft(B){q()!=="sloppy"||!k.current||L(B)||(k.current.dismissOnTouchEnd&&se(B),P.clear(),k.current=null)}function Ot(B){ge(B,ft)}let xe=Pe(m),mn=ct(n&&ct(oe(xe,"keydown",I),oe(xe,"compositionstart",Z),oe(xe,"compositionend",ie)),h&&ct(oe(xe,"click",Ee,!0),oe(xe,"pointerdown",Ee,!0),oe(xe,"pointerup",ye,!0),oe(xe,"pointercancel",ye,!0),oe(xe,"mousedown",Ee,!0),oe(xe,"mouseup",ye,!0),oe(xe,"touchstart",be,!0),oe(xe,"touchmove",rt,!0),oe(xe,"touchend",Ot,!0)));return()=>{mn(),O.clear(),V.clear(),Q(),x.current=!1,H()}},[u,m,n,h,g,d,o,_,v,I,H,y,j,L,f,c,P]);let X=Xe.useMemo(()=>({onKeyDown:I,onPointerDown:T,onClick:T}),[I,T]),de=Xe.useMemo(()=>({onKeyDown:I,onPointerDown:M,onMouseDown:M,onClickCapture:C,onMouseDownCapture(O){C(),A(O)},onPointerDownCapture(O){C(),A(O)},onMouseUpCapture:C,onTouchEndCapture:C,onTouchMoveCapture:C}),[I,C,A,M]);return Xe.useMemo(()=>o?{reference:X,floating:de,trigger:X}:{},[o,X,de])}var Ie=b(z(),1);function vc(e,t,o){let{reference:n,floating:r}=e,i=Fe(t),s=Xo(t),a=Ko(s),l=Ne(t),c=i==="y",d=n.x+n.width/2-r.width/2,m=n.y+n.height/2-r.height/2,u=n[a]/2-r[a]/2,f;switch(l){case"top":f={x:d,y:n.y-r.height};break;case"bottom":f={x:d,y:n.y+n.height};break;case"right":f={x:n.x+n.width,y:m};break;case"left":f={x:n.x-r.width,y:m};break;default:f={x:n.x,y:n.y}}let p=dt(t);return p&&(f[s]+=u*(p==="end"?1:-1)*(o&&c?-1:1)),f}async function _c(e,t){var o;t===void 0&&(t={});let{x:n,y:r,platform:i,rects:s,elements:a,strategy:l}=e,{boundary:c="clippingAncestors",rootBoundary:d="viewport",elementContext:m="floating",altBoundary:u=!1,padding:f=0}=_t(t,e),p=jn(f),h=a[u?m==="floating"?"reference":"floating":m],y=eo(await i.getClippingRect({element:(o=await(i.isElement==null?void 0:i.isElement(h)))==null||o?h:h.contextElement||await(i.getDocumentElement==null?void 0:i.getDocumentElement(a.floating)),boundary:c,rootBoundary:d,strategy:l})),_=m==="floating"?{x:n,y:r,width:s.floating.width,height:s.floating.height}:s.reference,v=await(i.getOffsetParent==null?void 0:i.getOffsetParent(a.floating)),w=await(i.isElement==null?void 0:i.isElement(v))&&await(i.getScale==null?void 0:i.getScale(v))||{x:1,y:1},R=eo(i.convertOffsetParentRelativeRectToViewportRelativeRect?await i.convertOffsetParentRelativeRectToViewportRelativeRect({elements:a,rect:_,offsetParent:v,strategy:l}):_);return{top:(y.top-R.top+p.top)/w.y,bottom:(R.bottom-y.bottom+p.bottom)/w.y,left:(y.left-R.left+p.left)/w.x,right:(R.right-y.right+p.right)/w.x}}var Hm=50,yc=async(e,t,o)=>{let{placement:n="bottom",strategy:r="absolute",middleware:i=[],platform:s}=o,a=s.detectOverflow?s:{...s,detectOverflow:_c},l=await(s.isRTL==null?void 0:s.isRTL(t)),c=await s.getElementRects({reference:e,floating:t,strategy:r}),{x:d,y:m}=vc(c,n,l),u=n,f=0,p={};for(let g=0;gL<=0)){var N,H;let L=(((N=i.flip)==null?void 0:N.index)||0)+1,T=S[L];if(T&&(!(m==="alignment"?_!==Fe(T):!1)||P.every(A=>Fe(A.placement)===_?A.overflows[0]>0:!0)))return{data:{index:L,overflows:P},reset:{placement:T}};let I=(H=P.filter(C=>C.overflows[0]<=0).sort((C,A)=>C.overflows[1]-A.overflows[1])[0])==null?void 0:H.placement;if(!I)switch(f){case"bestFit":{var j;let C=(j=P.filter(A=>{if(x){let M=Fe(A.placement);return M===_||M==="y"}return!0}).map(A=>[A.placement,A.overflows.filter(M=>M>0).reduce((M,X)=>M+X,0)]).sort((A,M)=>A[1]-M[1])[0])==null?void 0:j[0];C&&(I=C);break}case"initialPlacement":I=a;break}if(r!==I)return{reset:{placement:I}}}return{}}}};var Sc=new Set(["left","top"]);async function zm(e,t){let{placement:o,platform:n,elements:r}=e,i=await(n.isRTL==null?void 0:n.isRTL(r.floating)),s=Ne(o),a=dt(o),l=Fe(o)==="y",c=Sc.has(s)?-1:1,d=i&&l?-1:1,m=_t(t,e),{mainAxis:u,crossAxis:f,alignmentAxis:p}=typeof m=="number"?{mainAxis:m,crossAxis:0,alignmentAxis:null}:{mainAxis:m.mainAxis||0,crossAxis:m.crossAxis||0,alignmentAxis:m.alignmentAxis};return a&&typeof p=="number"&&(f=a==="end"?p*-1:p),l?{x:f*d,y:u*c}:{x:u*c,y:f*d}}var Rc=function(e){return e===void 0&&(e=0),{name:"offset",options:e,async fn(t){var o,n;let{x:r,y:i,placement:s,middlewareData:a}=t,l=await zm(t,e);return s===((o=a.offset)==null?void 0:o.placement)&&(n=a.arrow)!=null&&n.alignmentOffset?{}:{x:r+l.x,y:i+l.y,data:{...l,placement:s}}}}},Ec=function(e){return e===void 0&&(e={}),{name:"shift",options:e,async fn(t){let{x:o,y:n,placement:r,platform:i}=t,{mainAxis:s=!0,crossAxis:a=!1,limiter:l={fn:_=>{let{x:v,y:w}=_;return{x:v,y:w}}},...c}=_t(e,t),d={x:o,y:n},m=await i.detectOverflow(t,c),u=Fe(r),f=Dn(u),p=d[f],g=d[u],h=(_,v)=>zn(v+m[_==="y"?"top":"left"],v,v-m[_==="y"?"bottom":"right"]);s&&(p=h(f,p)),a&&(g=h(u,g));let y=l.fn({...t,[f]:p,[u]:g});return{...y,data:{x:y.x-o,y:y.y-n,enabled:{[f]:s,[u]:a}}}}}},kc=function(e){return e===void 0&&(e={}),{options:e,fn(t){var o,n;let{x:r,y:i,placement:s,rects:a,middlewareData:l}=t,{offset:c=0,mainAxis:d=!0,crossAxis:m=!0}=_t(e,t),u={x:r,y:i},f=Fe(s),p=Dn(f),g=u[p],h=u[f],y=_t(c,t),_=typeof y=="number"?{mainAxis:y,crossAxis:0}:{mainAxis:(o=y.mainAxis)!=null?o:0,crossAxis:(n=y.crossAxis)!=null?n:0};if(d){let R=p==="y"?"height":"width",x=a.reference[p]-a.floating[R]+_.mainAxis,S=a.reference[p]+a.reference[R]-_.mainAxis;gS&&(g=S)}if(m){var v,w;let R=p==="y"?"width":"height",x=Sc.has(Ne(s)),S=a.reference[f]-a.floating[R]+(x&&((v=l.offset)==null?void 0:v[f])||0)+(x?0:_.crossAxis),E=a.reference[f]+a.reference[R]+(x?0:((w=l.offset)==null?void 0:w[f])||0)-(x?_.crossAxis:0);hE&&(h=E)}return{[p]:g,[f]:h}}}},Tc=function(e){return e===void 0&&(e={}),{name:"size",options:e,async fn(t){let{placement:o,rects:n,platform:r,elements:i}=t,{apply:s=()=>{},...a}=_t(e,t),l=await r.detectOverflow(t,a),c=Ne(o),d=dt(o),m=Fe(o)==="y",{width:u,height:f}=n.floating,p,g;c==="top"||c==="bottom"?(p=c,g=d===(await(r.isRTL==null?void 0:r.isRTL(i.floating))?"start":"end")?"left":"right"):(g=c,p=d==="end"?"top":"bottom");let h=f-l.top-l.bottom,y=u-l.left-l.right,_=Dt(f-l[p],h),v=Dt(u-l[g],y),w=t.middlewareData.shift,R=!w,x=_,S=v;w!=null&&w.enabled.x&&(S=y),w!=null&&w.enabled.y&&(x=h),R&&!d&&(m?S=u-2*lt(l.left,l.right):x=f-2*lt(l.top,l.bottom)),await s({...t,availableWidth:S,availableHeight:x});let E=await r.getDimensions(i.floating);return u!==E.width||f!==E.height?{reset:{rects:!0}}:{}}}};function Ac(e){let t=Le(e),o=parseFloat(t.width)||0,n=parseFloat(t.height)||0,r=he(e),i=r?e.offsetWidth:o,s=r?e.offsetHeight:n,a=jt(o)!==i||jt(n)!==s;return a&&(o=i,n=s),{width:o,height:n,$:a}}function li(e){return U(e)?e:e.contextElement}function yo(e){let t=li(e);if(!he(t))return vt(1);let o=t.getBoundingClientRect(),{width:n,height:r,$:i}=Ac(t),s=(i?jt(o.width):o.width)/n,a=(i?jt(o.height):o.height)/r;return(!s||!Number.isFinite(s))&&(s=1),(!a||!Number.isFinite(a))&&(a=1),{x:s,y:a}}var Dm=vt(0);function Oc(e){let t=fe(e);return!Cn()||!t.visualViewport?Dm:{x:t.visualViewport.offsetLeft,y:t.visualViewport.offsetTop}}function jm(e,t,o){return t===void 0&&(t=!1),!!o&&t&&o===fe(e)}function oo(e,t,o,n){t===void 0&&(t=!1),o===void 0&&(o=!1);let r=e.getBoundingClientRect(),i=li(e),s=vt(1);t&&(n?U(n)&&(s=yo(n)):s=yo(e));let a=jm(i,o,n)?Oc(i):vt(0),l=(r.left+a.x)/s.x,c=(r.top+a.y)/s.y,d=r.width/s.x,m=r.height/s.y;if(i&&n){let u=fe(i),f=U(n)?fe(n):n,p=u,g=An(p);for(;g&&f!==p;){let h=yo(g),y=g.getBoundingClientRect(),_=Le(g),v=y.left+(g.clientLeft+parseFloat(_.paddingLeft))*h.x,w=y.top+(g.clientTop+parseFloat(_.paddingTop))*h.y;l*=h.x,c*=h.y,d*=h.x,m*=h.y,l+=v,c+=w,p=fe(g),g=An(p)}}return eo({width:d,height:m,x:l,y:c})}function Vn(e,t){let o=Wo(e).scrollLeft;return t?t.left+o:oo(ht(e)).left+o}function Nc(e,t){let o=e.getBoundingClientRect(),n=o.left+t.scrollLeft-Vn(e,o),r=o.top+t.scrollTop;return{x:n,y:r}}function Fm(e){let{elements:t,rect:o,offsetParent:n,strategy:r}=e,i=r==="fixed",s=ht(n),a=t?Vo(t.floating):!1;if(n===s||a&&i)return o;let l={scrollLeft:0,scrollTop:0},c=vt(1),d=vt(0),m=he(n);if((m||!i)&&((Qt(n)!=="body"||Fo(s))&&(l=Wo(n)),m)){let f=oo(n);c=yo(n),d.x=f.x+n.clientLeft,d.y=f.y+n.clientTop}let u=s&&!m&&!i?Nc(s,l):vt(0);return{width:o.width*c.x,height:o.height*c.y,x:o.x*c.x-l.scrollLeft*c.x+d.x+u.x,y:o.y*c.y-l.scrollTop*c.y+d.y+u.y}}function Vm(e){return e.getClientRects?Array.from(e.getClientRects()):[]}function Wm(e){let t=Wo(e),o=e.ownerDocument.body,n=lt(e.scrollWidth,e.clientWidth,o.scrollWidth,o.clientWidth),r=lt(e.scrollHeight,e.clientHeight,o.scrollHeight,o.clientHeight),i=-t.scrollLeft+Vn(e),s=-t.scrollTop;return Le(o).direction==="rtl"&&(i+=lt(e.clientWidth,o.clientWidth)-n),{width:n,height:r,x:i,y:s}}var Ym=25;function Um(e,t,o){o===void 0&&(o="viewport");let n=o==="layoutViewport",r=fe(e),i=ht(e),s=r.visualViewport,a=i.clientWidth,l=i.clientHeight,c=0,d=0;if(s){let u=!Cn()||t==="fixed";n?u||(c=-s.offsetLeft,d=-s.offsetTop):(a=s.width,l=s.height,u&&(c=s.offsetLeft,d=s.offsetTop))}if(Vn(i)<=0){let u=i.ownerDocument,f=u.body,p=getComputedStyle(f),g=u.compatMode==="CSS1Compat"&&parseFloat(p.marginLeft)+parseFloat(p.marginRight)||0,h=Math.abs(i.clientWidth-f.clientWidth-g),y=getComputedStyle(i).scrollbarGutter==="stable both-edges"?h/2:h;y<=Ym&&(a-=y)}return{width:a,height:l,x:c,y:d}}function Gm(e,t){let o=oo(e,!0,t==="fixed"),n=o.top+e.clientTop,r=o.left+e.clientLeft,i=yo(e),s=e.clientWidth*i.x,a=e.clientHeight*i.y,l=r*i.x,c=n*i.y;return{width:s,height:a,x:l,y:c}}function Pc(e,t,o){let n;if(t==="viewport"||t==="layoutViewport")n=Um(e,o,t);else if(t==="document")n=Wm(ht(e));else if(U(t))n=Gm(t,o);else{let r=Oc(e);n={x:t.x-r.x,y:t.y-r.y,width:t.width,height:t.height}}return eo(n)}function Km(e,t){let o=t.get(e);if(o)return o;let n=Bt(e,[],!1).filter(a=>U(a)&&Qt(a)!=="body"),r=null,i=Le(e).position==="fixed",s=i?bt(e):e;for(;U(s)&&!wt(s);){let a=Le(s),l=Pn(s),c=r?r.position:i?"fixed":"";!l&&(c==="fixed"||c==="absolute"&&a.position==="static")?n=n.filter(m=>m!==s):r=a,s=bt(s)}return t.set(e,n),n}function Xm(e){let{element:t,boundary:o,rootBoundary:n,strategy:r}=e,s=[...o==="clippingAncestors"?Vo(t)?[]:Km(t,this._c):[].concat(o),n],a=Pc(t,s[0],r),l=a.top,c=a.right,d=a.bottom,m=a.left;for(let u=1;u{a(!1,1e-7)},1e3)}S=!1}try{n=new IntersectionObserver(E,{...x,root:i.ownerDocument})}catch{n=new IntersectionObserver(E,x)}n.observe(e)}let l=fe(e),c=()=>a(o);return l.addEventListener("resize",c),a(!0),()=>{l.removeEventListener("resize",c),s()}}function qo(e,t,o,n){n===void 0&&(n={});let{ancestorScroll:r=!0,ancestorResize:i=!0,elementResize:s=typeof ResizeObserver=="function",layoutShift:a=typeof IntersectionObserver=="function",animationFrame:l=!1}=n,c=li(e),d=r||i?[...c?Bt(c):[],...t?Bt(t):[]]:[];d.forEach(y=>{r&&y.addEventListener("scroll",o),i&&y.addEventListener("resize",o)});let m=c&&a?$m(c,o,i):null,u=-1,f=null;s&&(f=new ResizeObserver(y=>{let[_]=y;_&&_.target===c&&f&&t&&(f.unobserve(t),cancelAnimationFrame(u),u=requestAnimationFrame(()=>{var v;(v=f)==null||v.observe(t)})),o()}),c&&!l&&f.observe(c),t&&f.observe(t));let p,g=l?oo(e):null;l&&h();function h(){let y=oo(e);g&&!Lc(g,y)&&o(),g=y,p=requestAnimationFrame(h)}return o(),()=>{var y;d.forEach(_=>{r&&_.removeEventListener("scroll",o),i&&_.removeEventListener("resize",o)}),m?.(),(y=f)==null||y.disconnect(),f=null,l&&cancelAnimationFrame(p)}}var Mc=Rc;var Bc=Ec,Hc=xc,zc=Tc;var Dc=kc,Wn=(e,t,o)=>{let n=new Map,r=o??{},i={...di,...r.platform,_c:n};return yc(e,t,{...r,platform:i})};var we=b(z(),1),Fc=b(z(),1),Vc=b(Ht(),1),tg=typeof document<"u",og=function(){},Yn=tg?Fc.useLayoutEffect:og;function Un(e,t){if(e===t)return!0;if(typeof e!=typeof t)return!1;if(typeof e=="function"&&e.toString()===t.toString())return!0;let o,n,r;if(e&&t&&typeof e=="object"){if(Array.isArray(e)){if(o=e.length,o!==t.length)return!1;for(n=o;n--!==0;)if(!Un(e[n],t[n]))return!1;return!0}if(r=Object.keys(e),o=r.length,o!==Object.keys(t).length)return!1;for(n=o;n--!==0;)if(!{}.hasOwnProperty.call(t,r[n]))return!1;for(n=o;n--!==0;){let i=r[n];if(!(i==="_owner"&&e.$$typeof)&&!Un(e[i],t[i]))return!1}return!0}return e!==e&&t!==t}function Wc(e){return typeof window>"u"?1:(e.ownerDocument.defaultView||window).devicePixelRatio||1}function jc(e,t){let o=Wc(e);return Math.round(t*o)/o}function ui(e){let t=we.useRef(e);return Yn(()=>{t.current=e}),t}function Yc(e){e===void 0&&(e={});let{placement:t="bottom",strategy:o="absolute",middleware:n=[],platform:r,elements:{reference:i,floating:s}={},transform:a=!0,whileElementsMounted:l,open:c}=e,[d,m]=we.useState({x:0,y:0,strategy:o,placement:t,middlewareData:{},isPositioned:!1}),[u,f]=we.useState(n);Un(u,n)||f(n);let[p,g]=we.useState(null),[h,y]=we.useState(null),_=we.useCallback(A=>{A!==x.current&&(x.current=A,g(A))},[]),v=we.useCallback(A=>{A!==S.current&&(S.current=A,y(A))},[]),w=i||p,R=s||h,x=we.useRef(null),S=we.useRef(null),E=we.useRef(d),k=l!=null,P=ui(l),N=ui(r),H=ui(c),j=we.useCallback(()=>{if(!x.current||!S.current)return;let A={placement:t,strategy:o,middleware:u};N.current&&(A.platform=N.current),Wn(x.current,S.current,A).then(M=>{let X={...M,isPositioned:H.current!==!1};L.current&&!Un(E.current,X)&&(E.current=X,Vc.flushSync(()=>{m(X)}))})},[u,t,o,N,H]);Yn(()=>{c===!1&&E.current.isPositioned&&(E.current.isPositioned=!1,m(A=>({...A,isPositioned:!1})))},[c]);let L=we.useRef(!1);Yn(()=>(L.current=!0,()=>{L.current=!1}),[]),Yn(()=>{if(w&&(x.current=w),R&&(S.current=R),w&&R){if(P.current)return P.current(w,R,j);j()}},[w,R,j,P,k]);let T=we.useMemo(()=>({reference:x,floating:S,setReference:_,setFloating:v}),[_,v]),I=we.useMemo(()=>({reference:w,floating:R}),[w,R]),C=we.useMemo(()=>{let A={position:o,left:0,top:0};if(!I.floating)return A;let M=jc(I.floating,d.x),X=jc(I.floating,d.y);return a?{...A,transform:"translate("+M+"px, "+X+"px)",...Wc(I.floating)>=1.5&&{willChange:"transform"}}:{position:o,left:M,top:X}},[o,a,I.floating,d.x,d.y]);return we.useMemo(()=>({...d,update:j,refs:T,elements:I,floatingStyles:C}),[d,j,T,I,C])}var fi=(e,t)=>{let o=Mc(e);return{name:o.name,fn:o.fn,options:[e,t]}},pi=(e,t)=>{let o=Bc(e);return{name:o.name,fn:o.fn,options:[e,t]}},mi=(e,t)=>({fn:Dc(e).fn,options:[e,t]}),gi=(e,t)=>{let o=Hc(e);return{name:o.name,fn:o.fn,options:[e,t]}},bi=(e,t)=>{let o=zc(e);return{name:o.name,fn:o.fn,options:[e,t]}};var Gn=class{attachedStores=[];attachedStoreValue=null;storeListeners=new Set;constructor(t,o,n=!0){this.fallbackStore=t,this.componentName=o,this.throwOnMissingTrigger=n}get attachedStore(){return this.attachedStoreValue}get store(){return this.attachedStoreValue??this.fallbackStore}get serverStore(){return this.fallbackStore}subscribeStore(t){return this.storeListeners.add(t),()=>{this.storeListeners.delete(t)}}attachStore(t){return this.attachedStores.push(t),this.setActiveStore(t),()=>{let o=this.attachedStores.lastIndexOf(t);o!==-1&&this.attachedStores.splice(o,1),this.setActiveStore(this.attachedStores[this.attachedStores.length-1]??null)}}setActiveStore(t){this.attachedStoreValue!==t&&(this.attachedStoreValue=t,this.storeListeners.forEach(o=>{o()}))}openByTrigger(t){let o=this.attachedStore;if(o===null)return;let n;if(t){for(let r=this.attachedStores.length-1;r>=0&&!n;r-=1)n=this.attachedStores[r].context.triggerElements.getById(t);n??=this.fallbackStore.context.triggerElements.getById(t)}if(t&&!n&&this.throwOnMissingTrigger)throw new Error(De(99,this.componentName,t,this.componentName));o.setOpen(!0,ee(G.imperativeAction,void 0,n))}closePopup(){let t=this.attachedStore;t!==null&&t.setOpen(!1,ee(G.imperativeAction))}};var ro=b(z(),1),sl=b(Ht(),1);var rl=b(z(),1);var ol=b(z(),1),yi=b(Kn(),1),nl=b(Qc(),1);var Jc=b(z(),1);var wi=[],vi;function $c(){return vi}function el(e){wi.push(e)}function _i(e){let t=(o,n)=>{let r=Te(_g).current,i;try{vi=r;for(let s of wi)s.before(r);i=e(o,n);for(let s of wi)s.after(r);r.didInitialize=!0}finally{vi=void 0}return i};return t.displayName=e.displayName||e.name,t}function tl(e){return Jc.forwardRef(_i(e))}function _g(){return{didInitialize:!1}}var yg=po(19),xg=yg?Rg:Eg;function qn(e,t,o,n,r){return xg(e,t,o,n,r)}function Sg(e,t,o,n,r){let i=ol.useCallback(()=>t(e.getSnapshot(),o,n,r),[e,t,o,n,r]);return(0,yi.useSyncExternalStore)(e.subscribe,i,i)}el({before(e){e.syncIndex=0,e.didInitialize||(e.syncTick=1,e.syncHooks=[],e.didChangeStore=!0,e.getSnapshot=()=>{let t=!1;for(let o=0;o0&&(e.didChangeStore&&(e.didChangeStore=!1,e.subscribe=t=>{let o=new Set;for(let r of e.syncHooks)o.add(r.store);let n=[];for(let r of o)n.push(r.subscribe(t));return()=>{for(let r of n)r()}}),(0,yi.useSyncExternalStore)(e.subscribe,e.getSnapshot,e.getSnapshot))}});function Rg(e,t,o,n,r){let i=$c();if(!i)return Sg(e,t,o,n,r);let s=i.syncIndex;i.syncIndex+=1;let a;return i.didInitialize?(a=i.syncHooks[s],(a.store!==e||a.selector!==t||!Object.is(a.a1,o)||!Object.is(a.a2,n)||!Object.is(a.a3,r))&&(a.store!==e&&(i.didChangeStore=!0),a.store=e,a.selector=t,a.a1=o,a.a2=n,a.a3=r,a.value=t(e.getSnapshot(),o,n,r))):(a={store:e,selector:t,a1:o,a2:n,a3:r,value:t(e.getSnapshot(),o,n,r)},i.syncHooks.push(a)),a.value}function Eg(e,t,o,n,r){return(0,nl.useSyncExternalStoreWithSelector)(e.subscribe,e.getSnapshot,e.getSnapshot,i=>t(i,o,n,r))}var Zn=class{constructor(t){this.state=t,this.listeners=new Set,this.updateTick=0}subscribe=t=>(this.listeners.add(t),()=>{this.listeners.delete(t)});getSnapshot=()=>this.state;setState(t){if(this.state===t)return;this.state=t,this.updateTick+=1;let o=this.updateTick;for(let n of this.listeners){if(o!==this.updateTick)return;n(t)}}update(t){for(let o in t)if(!Object.is(this.state[o],t[o])){this.setState({...this.state,...t});return}}set(t,o){Object.is(this.state[t],o)||this.setState({...this.state,[t]:o})}notifyAll(){let t={...this.state};this.setState(t)}use(t,o,n,r){return qn(this,t,o,n,r)}};var no=b(z(),1);var Vt=class extends Zn{constructor(t,o={},n){super(t),this.context=o,this.selectors=n}useSyncedValue(t,o){no.useDebugValue(t);let n=this;F(()=>{n.state[t]!==o&&n.set(t,o)},[n,t,o])}useSyncedValueWithCleanup(t,o){let n=this;F(()=>(n.state[t]!==o&&n.set(t,o),()=>{n.set(t,void 0)}),[n,t,o])}useSyncedValues(t){let o=this,n=Object.values(t);F(()=>{o.update(t)},[o,...n])}useControlledProp(t,o){no.useDebugValue(t);let n=this,r=o!==void 0;F(()=>{r&&!Object.is(n.state[t],o)&&n.setState({...n.state,[t]:o})},[n,t,o,r])}select(t,o,n,r){let i=this.selectors[t];return i(this.state,o,n,r)}useState(t,o,n,r){return no.useDebugValue(t),qn(this,this.selectors[t],o,n,r)}useContextCallback(t,o){no.useDebugValue(t);let n=Y(o??Ge);this.context[t]=n}useStateSetter(t){let o=no.useRef(void 0);return o.current===void 0&&(o.current=n=>{this.set(t,n)}),o.current}observe(t,o){let n;typeof t=="function"?n=t:n=this.selectors[t];let r=n(this.state);return o(r,r,this),this.subscribe(i=>{let s=n(i);if(!Object.is(r,s)){let a=r;r=s,o(s,a,this)}})}};var kg={open:e=>e.open,transitionStatus:e=>e.transitionStatus,domReferenceElement:e=>e.domReferenceElement,referenceElement:e=>e.positionReference??e.referenceElement,floatingElement:e=>e.floatingElement,floatingId:e=>e.floatingId},Wt=class extends Vt{constructor(t){let{syncOnly:o,nested:n,onOpenChange:r,triggerElements:i,...s}=t;super({...s,positionReference:s.referenceElement,domReferenceElement:s.referenceElement},{onOpenChange:r,dataRef:{current:{}},events:hc(),nested:n,triggerElements:i},kg),this.syncOnly=o}syncOpenEvent=(t,o)=>{(!t||!this.state.open||o!=null&&ec(o))&&(this.context.dataRef.current.openEvent=t?o:void 0)};dispatchOpenChange=(t,o)=>{this.syncOpenEvent(t,o.event);let n={open:t,reason:o.reason,nativeEvent:o.event,nested:this.context.nested,triggerElement:o.trigger};this.context.events.emit("openchange",n)};setOpen=(t,o)=>{if(this.syncOnly){this.context.onOpenChange?.(t,o);return}this.dispatchOpenChange(t,o),this.context.onOpenChange?.(t,o)}};function il(e){let{popupStore:t,treatPopupAsFloatingElement:o=!1,floatingRootContext:n,floatingId:r,nested:i,onOpenChange:s}=e,a=t.useState("open"),l=t.useState("activeTriggerElement"),c=t.useState(o?"popupElement":"positionerElement"),d=t.context.triggerElements,m=s,u=rl.useRef(null);n===void 0&&u.current===null&&(u.current=new Wt({open:a,transitionStatus:void 0,referenceElement:l,floatingElement:c,triggerElements:d,onOpenChange:m,floatingId:r,syncOnly:!0,nested:i}));let f=n??u.current;return t.useSyncedValue("floatingId",r),F(()=>{let p={open:a,floatingId:r,referenceElement:l,floatingElement:c};U(l)&&(p.domReferenceElement=l),f.state.positionReference===f.state.referenceElement&&(p.positionReference=l),f.update(p)},[a,r,l,c,f]),f.context.onOpenChange=m,f.context.nested=i,f}var al={tabIndex:-1,[ei]:""};function cl(e,t=!1){let o=mo(),n=Fn()!=null,r=Te(()=>e(o,n)).current;return il({popupStore:r,treatPopupAsFloatingElement:t,floatingRootContext:r.state.floatingRootContext,floatingId:o,nested:n,onOpenChange:r.setOpen}),r}function ll({handle:e,store:t}){return F(()=>e.attachStore(t),[e,t]),null}function Tg(e,t){let o=ro.useRef(null),n=ro.useRef(null);return ro.useCallback(r=>{if(e===void 0)return;let i=!1;if(o.current!==null){let s=o.current,a=n.current,l=t.context.triggerElements.getById(s);a&&l===a&&(t.context.triggerElements.delete(s),i=!0),o.current=null,n.current=null}if(r!==null&&(o.current=e,n.current=r,t.context.triggerElements.add(e,r),i=!0),i){let s=t.context.triggerElements.size;t.select("open")&&t.state.triggerCount!==s&&t.set("triggerCount",s)}},[t,e])}function Pg(e,t,o,n=!1){t?e.preventUnmountingOnClose=!1:n&&(e.preventUnmountingOnClose=!0);let r=o?.id??null;(r||t)&&(e.activeTriggerId=r,e.activeTriggerElement=o??null)}function Cg(e){let t=!1;return e.preventUnmountOnClose=()=>{t=!0},()=>t}function dl(e,t,o,n={}){let r=o.reason,i=r===G.triggerHover,s=t&&r===G.triggerFocus,a=!t&&(r===G.triggerPress||r===G.escapeKey),l=Cg(o);if(e.context.onOpenChange?.(t,o),o.isCanceled)return;n.onBeforeDispatch?.(),e.state.floatingRootContext.dispatchOpenChange(t,o);let c=()=>{let d={...n.extraState,open:t};s?d.instantType="focus":a?d.instantType="dismiss":i&&(d.instantType=void 0),Pg(d,t,o.trigger,l()),e.update(d)};i?sl.flushSync(c):c()}function ul(e,t,o,n){let r=o.useState("isMountedByTrigger",e),i=Tg(e,o),s=Y(l=>{let c=o.select("open"),d=o.select("activeTriggerId");if(d===e){o.update({activeTriggerElement:l,...c?n:null});return}d==null&&c&&o.update({activeTriggerId:e,activeTriggerElement:l,...n})}),a=ro.useCallback(l=>{i(l),l&&s(l)},[i,s]);return F(()=>{r&&o.update({activeTriggerElement:t.current,...n})},[r,o,t,...Object.values(n)]),{registerTrigger:a,isMountedByThisTrigger:r}}function fl(e,t={}){let{closeOnActiveTriggerUnmount:o=!1}=t,n=ro.useRef(null),r=e.useState("open"),i=e.useState("triggerCount"),s=e.useState("activeTriggerId"),a=e.useState("activeTriggerElement");F(()=>{if(!r){n.current=null,e.state.triggerCount!==0&&e.set("triggerCount",0);return}let l=e.context.triggerElements.size,c={};e.state.triggerCount!==l&&(c.triggerCount=l);let d=e.select("activeTriggerId"),m=null;if(d){let u=e.context.triggerElements.getById(d);if(u)n.current=d,u!==e.state.activeTriggerElement&&(c.activeTriggerElement=u);else{for(let[f,p]of e.context.triggerElements.entries())if(p===e.state.activeTriggerElement){c.activeTriggerId=f,c.activeTriggerElement=p,n.current=f;break}c.activeTriggerId===void 0&&(n.current===d?m=d:n.current=null)}}else n.current=null;if(!m&&!d&&l===1){let u=e.context.triggerElements.entries().next();if(!u.done){let[f,p]=u.value;c.activeTriggerId=f,c.activeTriggerElement=p,n.current=f}}(c.triggerCount!==void 0||c.activeTriggerId!==void 0||c.activeTriggerElement!==void 0)&&e.update(c),m&&o&&queueMicrotask(()=>{if(e.select("open")&&e.select("activeTriggerId")===m&&!e.context.triggerElements.getById(m)){let u=ee(G.none);e.setOpen(!1,u),u.isCanceled||e.update({activeTriggerId:null,activeTriggerElement:null})}})},[r,e,i,s,a,o])}function pl(e,t,o){let{mounted:n,setMounted:r,transitionStatus:i}=Ba(e),s=t.useState("preventUnmountingOnClose"),a=e?!1:s;t.useSyncedValues({mounted:n,transitionStatus:i,preventUnmountingOnClose:a});let l=Y(()=>{r(!1),t.update({activeTriggerId:null,activeTriggerElement:null,mounted:!1,preventUnmountingOnClose:!1}),o?.(),t.context.onOpenChangeComplete?.(!1)});return In({enabled:n&&!e&&!a,open:e,ref:t.context.popupRef,onComplete(){e||l()}}),{forceUnmount:l,transitionStatus:i}}function ml(e,t){e.useSyncedValues(t),F(()=>()=>{e.update({activeTriggerProps:me,inactiveTriggerProps:me,popupProps:me})},[e])}var io=class{constructor(){this.idMap=new Map}add(t,o){this.idMap.set(t,o)}delete(t){this.idMap.delete(t)}hasElement(t){for(let o of this.idMap.values())if(o===t)return!0;return!1}hasMatchingElement(t){for(let o of this.idMap.values())if(t(o))return!0;return!1}getById(t){return this.idMap.get(t)}entries(){return this.idMap.entries()}elements(){return this.idMap.values()}get size(){return this.idMap.size}};function gl(){return new Wt({open:!1,transitionStatus:void 0,floatingElement:null,referenceElement:null,triggerElements:new io,floatingId:void 0,syncOnly:!1,nested:!1,onOpenChange:void 0})}function hl(){return{open:!1,openProp:void 0,mounted:!1,transitionStatus:void 0,floatingRootContext:gl(),floatingId:void 0,triggerCount:0,preventUnmountingOnClose:!1,payload:void 0,activeTriggerId:null,activeTriggerElement:null,triggerIdProp:void 0,popupElement:null,positionerElement:null,activeTriggerProps:me,inactiveTriggerProps:me,popupProps:me}}function wl(e,t,o=!1){return new Wt({open:!1,transitionStatus:void 0,floatingElement:null,referenceElement:null,triggerElements:e,floatingId:t,syncOnly:!0,nested:o,onOpenChange:void 0})}var Zo=e=>e.triggerIdProp??e.activeTriggerId,xi=e=>e.openProp??e.open,bl=e=>(e.popupElement?.id??e.floatingId)||void 0;function vl(e,t){return t!==void 0&&xi(e)&&Zo(e)===t}function Ag(e,t){return vl(e,t)?!0:t!==void 0&&xi(e)&&Zo(e)==null&&e.triggerCount===1}var _l={open:xi,mounted:e=>e.mounted,transitionStatus:e=>e.transitionStatus,floatingRootContext:e=>e.floatingRootContext,triggerCount:e=>e.triggerCount,preventUnmountingOnClose:e=>e.preventUnmountingOnClose,payload:e=>e.payload,activeTriggerId:Zo,activeTriggerElement:e=>e.mounted?e.activeTriggerElement:null,popupId:bl,isTriggerActive:(e,t)=>t!==void 0&&Zo(e)===t,isOpenedByTrigger:(e,t)=>vl(e,t),isMountedByTrigger:(e,t)=>t!==void 0&&Zo(e)===t&&e.mounted,triggerProps:(e,t)=>t?e.activeTriggerProps:e.inactiveTriggerProps,triggerPopupId:(e,t)=>Ag(e,t)?bl(e):void 0,popupProps:e=>e.popupProps,popupElement:e=>e.popupElement,positionerElement:e=>e.positionerElement};var Si=b(z(),1),yl=b(Kn(),1);function xl(e){let t=Si.useCallback(n=>e===void 0?Ge:e.subscribeStore(n),[e]),o=Si.useCallback(()=>e===void 0?void 0:e.store,[e]);return(0,yl.useSyncExternalStore)(t,o,()=>e?.serverStore)}function Sl(e){return Og(e,e.rootContext)}function Og(e,t){let{nodeId:o,externalTree:n}=e,r=t.useState("referenceElement"),i=t.useState("floatingElement"),s=t.useState("domReferenceElement"),a=t.useState("open"),l=t.useState("floatingId"),[c,d]=Ie.useState(null),[m,u]=Ie.useState(void 0),[f,p]=Ie.useState(void 0),g=Ie.useRef(null),h=Ft(n),y=Ie.useMemo(()=>({reference:r,floating:i,domReference:s}),[r,i,s]),_=Yc({...e,elements:{...y,...c&&{reference:c}}}),v=U(m)?m:null,w=f===void 0?t.state.floatingElement:f;t.useSyncedValue("referenceElement",m??null),t.useSyncedValue("domReferenceElement",m===void 0?s:v),t.useSyncedValue("floatingElement",w);let R=Ie.useCallback(N=>{let H=U(N)?{getBoundingClientRect:()=>N.getBoundingClientRect(),getClientRects:()=>N.getClientRects(),contextElement:N}:N;d(H),_.refs.setReference(H)},[_.refs]),x=Ie.useCallback(N=>{(U(N)||N===null)&&(g.current=N,u(N)),(U(_.refs.reference.current)||_.refs.reference.current===null||N!==null&&!U(N))&&_.refs.setReference(N)},[_.refs,u]),S=Ie.useCallback(N=>{p(N),_.refs.setFloating(N)},[_.refs]),E=Ie.useMemo(()=>({..._.refs,setReference:x,setFloating:S,setPositionReference:R,domReference:g}),[_.refs,x,S,R]),k=Ie.useMemo(()=>({..._.elements,domReference:s}),[_.elements,s]),P=Ie.useMemo(()=>({..._,dataRef:t.context.dataRef,open:a,onOpenChange:t.setOpen,events:t.context.events,floatingId:l,refs:E,elements:k,nodeId:o,rootStore:t}),[_,E,k,o,t,a,l]);return F(()=>{s&&(g.current=s)},[s]),F(()=>{t.context.dataRef.current.floatingContext=P;let N=h?.nodesRef.current.find(H=>H.id===o);N&&(N.context=P)}),Ie.useMemo(()=>({..._,context:P,refs:E,elements:k,rootStore:t}),[_,E,k,P,t])}var yt=b(z(),1);var Ri=Tt.os.mac&&Tt.engine.webkit;function Ei(e,t={}){let{enabled:o=!0,delay:n}=t,r="rootStore"in e?e.rootStore:e,{events:i,dataRef:s}=r.context,a=yt.useRef(!1),l=yt.useRef(null),c=yt.useRef(!0),d=at();yt.useEffect(()=>{let u=r.select("domReferenceElement");if(!o)return;let f=fe(u);function p(){let y=r.select("domReferenceElement");!r.select("open")&&he(y)&&y===Ln(Pe(y))&&(a.current=!0)}function g(){c.current=!0}function h(){c.current=!1}return ct(oe(f,"blur",p),Ri&&oe(f,"keydown",g,!0),Ri&&oe(f,"pointerdown",h,!0))},[r,o]),yt.useEffect(()=>{if(!o)return;function u(f){if(f.reason===G.triggerPress||f.reason===G.escapeKey){let p=r.select("domReferenceElement");U(p)&&(l.current=p,a.current=!0)}}return i.on("openchange",u),()=>{i.off("openchange",u)}},[i,o,r]);let m=yt.useMemo(()=>{function u(){a.current=!1,l.current=null}return{onMouseLeave(){u()},onFocus(f){let p=f.currentTarget;if(a.current){if(l.current===p)return;u()}let g=Me(f.nativeEvent);if(U(g)){if(Ri&&!f.relatedTarget){if(!c.current&&!oc(g))return}else if(!nc(g))return}let h=zt(f.relatedTarget,r.context.triggerElements),{nativeEvent:y,currentTarget:_}=f,v=typeof n=="function"?n():n;if(r.select("open")&&h||v===0||v===void 0){r.setOpen(!0,ee(G.triggerFocus,y,_));return}d.start(v,()=>{a.current||r.setOpen(!0,ee(G.triggerFocus,y,_))})},onBlur(f){u();let p=f.relatedTarget,g=f.nativeEvent,h=U(p)&&p.hasAttribute(_o("focus-guard"))&&p.getAttribute("data-type")==="outside";d.start(0,()=>{let y=r.select("domReferenceElement"),_=Ln(Pe(y));!p&&_===y||re(s.current.floatingContext?.refs.floating.current,_)||re(y,_)||h||zt(p??_,r.context.triggerElements)||r.setOpen(!1,ee(G.triggerFocus,g))})}}},[s,n,r,d]);return yt.useMemo(()=>o?{reference:m,trigger:m}:{},[o,m])}var Ti=b(z(),1);var ki=class e{constructor(){this.pointerType=void 0,this.interactedInside=!1,this.handler=void 0,this.blockMouseMove=!0,this.performedPointerEventsMutation=!1,this.pointerEventsScopeElement=null,this.pointerEventsReferenceElement=null,this.pointerEventsFloatingElement=null,this.restTimeoutPending=!1,this.openChangeTimeout=new Ke,this.restTimeout=new Ke,this.handleCloseOptions=void 0}static create(){return new e}dispose=()=>{this.openChangeTimeout.clear(),this.restTimeout.clear()};disposeEffect=()=>this.dispose},Qn=new WeakMap;function So(e){if(!e.performedPointerEventsMutation)return;let t=e.pointerEventsScopeElement;t&&Qn.get(t)===e&&(e.pointerEventsScopeElement?.style.removeProperty("pointer-events"),e.pointerEventsReferenceElement?.style.removeProperty("pointer-events"),e.pointerEventsFloatingElement?.style.removeProperty("pointer-events"),Qn.delete(t)),e.performedPointerEventsMutation=!1,e.pointerEventsScopeElement=null,e.pointerEventsReferenceElement=null,e.pointerEventsFloatingElement=null}function Jn(e,t){let{scopeElement:o,referenceElement:n,floatingElement:r}=t,i=Qn.get(o);i&&i!==e&&So(i),So(e),e.performedPointerEventsMutation=!0,e.pointerEventsScopeElement=o,e.pointerEventsReferenceElement=n,e.pointerEventsFloatingElement=r,Qn.set(o,e),o.style.pointerEvents="none",n.style.pointerEvents="auto",r.style.pointerEvents="auto"}function Ro(e){let t=e.context.dataRef.current,o=Te(()=>t.hoverInteractionState??ki.create()).current;return t.hoverInteractionState||(t.hoverInteractionState=o),go(t.hoverInteractionState.disposeEffect),t.hoverInteractionState}function Pi(e,t={}){let{enabled:o=!0,closeDelay:n=0,nodeId:r}=t,i="rootStore"in e?e.rootStore:e,s=i.useState("open"),a=i.useState("floatingElement"),l=i.useState("domReferenceElement"),{dataRef:c}=i.context,d=Ft(),m=Fn(),u=Ro(i),f=at(),p=Y(()=>Bn(c.current.openEvent?.type,u.interactedInside)),g=Y(()=>rc(c.current.openEvent?.type)),h=Y(()=>{So(u)});F(()=>{s||(u.pointerType=void 0,u.restTimeoutPending=!1,u.interactedInside=!1,h())},[s,u,h]),Ti.useEffect(()=>h,[h]),F(()=>{if(o&&s&&u.handleCloseOptions?.blockPointerEvents&&g()&&U(l)&&a){let y=l,_=a,v=Pe(a),w=d?.nodesRef.current.find(E=>E.id===m)?.context?.elements.floating;w&&(w.style.pointerEvents="");let R=u.pointerEventsScopeElement!==_?u.pointerEventsScopeElement:null,x=w!==_?w:null,S=u.handleCloseOptions?.getScope?.()??R??x??y.closest("[data-rootownerid]")??v.body;return Jn(u,{scopeElement:S,referenceElement:y,floatingElement:_}),()=>{h()}}},[o,s,l,a,u,g,d,m,h]),Ti.useEffect(()=>{if(!o)return;function y(){return!!(d&&m&&Ct(d.nodesRef.current,m).length>0)}function _(E){let k=$e(n,"close",u.pointerType),P=()=>{i.setOpen(!1,ee(G.triggerHover,E)),d?.events.emit("floating.closed",E)};k?u.openChangeTimeout.start(k,P):(u.openChangeTimeout.clear(),P())}function v(E){let k=Me(E);if(!oi(k)){u.interactedInside=!1;return}u.interactedInside=k?.closest("[aria-haspopup]")!=null}function w(){u.openChangeTimeout.clear(),f.clear(),d?.events.off("floating.closed",x),h()}function R(E){if(y()&&d){d.events.on("floating.closed",x);return}if(zt(E.relatedTarget,i.context.triggerElements))return;let k=c.current.floatingContext?.nodeId??r,P=E.relatedTarget;if(!(d&&k&&U(P)&&Ct(d.nodesRef.current,k,!1).some(H=>re(H.context?.elements.floating,P)))){if(u.handler){u.handler(E);return}h(),g()&&!p()&&_(E)}}function x(E){!d||!m||y()||f.start(0,()=>{d.events.off("floating.closed",x),i.setOpen(!1,ee(G.triggerHover,E)),d.events.emit("floating.closed",E)})}let S=a;return ct(S&&oe(S,"mouseenter",w),S&&oe(S,"mouseleave",R),S&&oe(S,"pointerdown",v,!0),()=>{d?.events.off("floating.closed",x)})},[o,a,i,c,n,r,g,p,h,u,d,m,f])}var Yt=b(z(),1),Rl=b(Ht(),1);var Ng={current:null};function Ci(e,t={}){let{enabled:o=!0,delay:n=0,handleClose:r=null,mouseOnly:i=!1,restMs:s=0,move:a=!0,triggerElementRef:l=Ng,externalTree:c,isActiveTrigger:d=!0,getHandleCloseContext:m,isClosing:u,shouldOpen:f,guardStaleOpen:p=!1}=t,g="rootStore"in e?e.rootStore:e,{dataRef:h,events:y}=g.context,_=Ft(c),v=Ro(g),w=Yt.useRef(!1),R=je(r),x=je(n),S=je(s),E=je(o),k=je(f),P=je(u),N=Y(()=>Bn(h.current.openEvent?.type,v.interactedInside)),H=Y(()=>k.current?.()!==!1),j=Y((I,C,A)=>{let M=g.context.triggerElements;if(M.hasElement(C))return!I||!re(I,C);if(!U(A))return!1;let X=A;return M.hasMatchingElement(de=>re(de,X))&&(!I||!re(I,X))}),L=Y(()=>{if(!v.handler)return;Pe(g.select("domReferenceElement")).removeEventListener("mousemove",v.handler),v.handler=void 0}),T=Y(()=>{So(v)});return d&&(v.handleCloseOptions=R.current?.__options),Yt.useEffect(()=>L,[L]),Yt.useEffect(()=>{if(!o)return;function I(C){C.open?w.current=!1:(w.current=C.reason===G.triggerHover,L(),v.openChangeTimeout.clear(),v.restTimeout.clear(),v.blockMouseMove=!0,v.restTimeoutPending=!1)}return y.on("openchange",I),()=>{y.off("openchange",I)}},[o,y,v,L]),Yt.useEffect(()=>{if(!o)return;function I(O,V=!0){let Z=$e(x.current,"close",v.pointerType);Z?v.openChangeTimeout.start(Z,()=>{g.setOpen(!1,ee(G.triggerHover,O)),_?.events.emit("floating.closed",O)}):V&&(v.openChangeTimeout.clear(),g.setOpen(!1,ee(G.triggerHover,O)),_?.events.emit("floating.closed",O))}let C=l.current??(d?g.select("domReferenceElement"):null);if(!U(C))return;function A(O){if(v.openChangeTimeout.clear(),v.blockMouseMove=!1,i&&!Pt(v.pointerType))return;let V=ni(S.current),Z=$e(x.current,"open",v.pointerType),ie=Me(O),K=O.currentTarget??null,Q=g.select("domReferenceElement"),q=K;if(U(ie)&&!g.context.triggerElements.hasElement(ie)){for(let ye of g.context.triggerElements.elements())if(re(ye,ie)){q=ye;break}}U(K)&&U(Q)&&!g.context.triggerElements.hasElement(K)&&re(K,Q)&&(q=Q);let $=q==null?!1:j(Q,q,ie),ne=g.select("open"),se=P.current?.()??g.select("transitionStatus")==="ending",ze=!ne&&se&&w.current,ae=!$&&U(q)&&U(Q)&&re(Q,q)&&ze,ge=V>0&&!Z,be=$&&(ne||ze)||ae,Ee=!ne||$;if(be){H()&&g.setOpen(!0,ee(G.triggerHover,O,q));return}ge||(Z?v.openChangeTimeout.start(Z,()=>{Ee&&H()&&g.setOpen(!0,ee(G.triggerHover,O,q))}):Ee&&H()&&g.setOpen(!0,ee(G.triggerHover,O,q)))}function M(O){if(N()){T();return}L();let V=g.select("domReferenceElement"),Z=Pe(V);v.restTimeout.clear(),v.restTimeoutPending=!1;let ie=h.current.floatingContext??m?.();if(zt(O.relatedTarget,g.context.triggerElements))return;if(R.current&&ie){g.select("open")||v.openChangeTimeout.clear();let Q=l.current;v.handler=R.current({...ie,tree:_,x:O.clientX,y:O.clientY,onClose(){T(),L(),E.current&&!N()&&Q===g.select("domReferenceElement")&&I(O,!0)}}),Z.addEventListener("mousemove",v.handler),v.handler(O);return}(v.pointerType!=="touch"||!re(g.select("floatingElement"),O.relatedTarget))&&I(O)}function X(O){re(C,O.relatedTarget)||(v.openChangeTimeout.clear(),v.restTimeout.clear(),v.restTimeoutPending=!1)}let de=p?oe(C,"mouseout",X):void 0;return a?ct(oe(C,"mousemove",A,{once:!0}),oe(C,"mouseenter",A),oe(C,"mouseleave",M),de):ct(oe(C,"mouseenter",A),oe(C,"mouseleave",M),de)},[L,T,h,x,g,o,R,v,d,j,N,i,a,S,l,_,E,m,P,H,p]),Yt.useMemo(()=>{if(!o)return;function I(C){v.pointerType=C.pointerType}return{onPointerDown:I,onPointerEnter:I,onMouseMove(C){let{nativeEvent:A}=C,M=C.currentTarget,X=g.select("domReferenceElement"),de=g.select("open"),O=j(X,M,C.target);if(i&&!Pt(v.pointerType))return;if(de&&O&&v.handleCloseOptions?.blockPointerEvents){let ie=g.select("floatingElement");if(ie){let K=v.handleCloseOptions?.getScope?.()??M.ownerDocument.body;Jn(v,{scopeElement:K,referenceElement:M,floatingElement:ie})}}let V=ni(S.current);if(de&&!O||V===0||!O&&v.restTimeoutPending&&C.movementX**2+C.movementY**2<2)return;v.restTimeout.clear();function Z(){if(v.restTimeoutPending=!1,N())return;let ie=g.select("open");!v.blockMouseMove&&(!ie||O)&&H()&&g.setOpen(!0,ee(G.triggerHover,A,M))}v.pointerType==="touch"?Rl.flushSync(()=>{Z()}):O&&de?Z():(v.restTimeoutPending=!0,v.restTimeout.start(V,Z))}}},[o,v,N,j,i,g,S,H])}var El=.1,Ig=El*El,le=.5;function $n(e,t,o,n,r,i){return n>=t!=i>=t&&e<=(r-o)*(t-n)/(i-n)+o}function er(e,t,o,n,r,i,s,a,l,c){let d=!1;return $n(e,t,o,n,r,i)&&(d=!d),$n(e,t,r,i,s,a)&&(d=!d),$n(e,t,s,a,l,c)&&(d=!d),$n(e,t,l,c,o,n)&&(d=!d),d}function Lg(e,t,o){return e>=o.x&&e<=o.x+o.width&&t>=o.y&&t<=o.y+o.height}function tr(e,t,o,n,r,i){let s=Math.min(o,r),a=Math.max(o,r),l=Math.min(n,i),c=Math.max(n,i);return e>=s&&e<=a&&t>=l&&t<=c}function Ai(e={}){let{blockPointerEvents:t=!1}=e,o=new Ke,n=({x:r,y:i,placement:s,elements:a,onClose:l,nodeId:c,tree:d})=>{let m=s?.split("-")[0],u=!1,f=null,p=null,g=typeof performance<"u"?performance.now():0;function h(_,v){let w=performance.now(),R=w-g;if(f===null||p===null||R===0)return f=_,p=v,g=w,!1;let x=_-f,S=v-p,E=x*x+S*S,k=R*R*Ig;return f=_,p=v,g=w,E0)}function j(){H()||y()}if(H())return;let L=w.getBoundingClientRect(),T=R.getBoundingClientRect(),I=r>T.right-T.width/2,C=i>T.bottom-T.height/2,A=T.width>L.width,M=T.height>L.height,X=(A?L:T).left,de=(A?L:T).right,O=(M?L:T).top,V=(M?L:T).bottom;if(m==="top"&&i>=L.bottom-1||m==="bottom"&&i<=L.top+1||m==="left"&&r>=L.right-1||m==="right"&&r<=L.left+1){j();return}let Z=!1;switch(m){case"top":Z=tr(x,S,X,L.top+1,de,T.bottom-1);break;case"bottom":Z=tr(x,S,X,T.top+1,de,L.bottom-1);break;case"left":Z=tr(x,S,T.right-1,V,L.left+1,O);break;case"right":Z=tr(x,S,L.right-1,V,T.left+1,O);break;default:}if(Z)return;if(u&&!Lg(x,S,L)){j();return}if(!k&&h(x,S)){j();return}let ie=!1;switch(m){case"top":{let K=A?le/2:le*4,Q=A||I?r+K:r-K,q=A?r-K:I?r+K:r-K,$=i+le+1,ne=I||A?T.bottom-le:T.top,se=I?A?T.bottom-le:T.top:T.bottom-le;ie=er(x,S,Q,$,q,$,T.left,ne,T.right,se);break}case"bottom":{let K=A?le/2:le*4,Q=A||I?r+K:r-K,q=A?r-K:I?r+K:r-K,$=i-le,ne=I||A?T.top+le:T.bottom,se=I?A?T.top+le:T.bottom:T.top+le;ie=er(x,S,Q,$,q,$,T.left,ne,T.right,se);break}case"left":{let K=M?le/2:le*4,Q=M||C?i+K:i-K,q=M?i-K:C?i+K:i-K,$=r+le+1,ne=C||M?T.right-le:T.left,se=C?M?T.right-le:T.left:T.right-le;ie=er(x,S,ne,T.top,se,T.bottom,$,Q,$,q);break}case"right":{let K=M?le/2:le*4,Q=M||C?i+K:i-K,q=M?i-K:C?i+K:i-K,$=r-le,ne=C||M?T.left+le:T.right,se=C?M?T.left+le:T.right:T.left+le;ie=er(x,S,$,Q,$,q,ne,T.top,se,T.bottom);break}default:}ie?u||o.start(40,j):j()}};return n.__options={...e,blockPointerEvents:t},n}var or=class extends Vt{setState(t){}update(t){}set(t,o){}notifyAll(){}};var hy=(function(e){return e.open="data-open",e.closed="data-closed",e[e.startingStyle=Yr.startingStyle]="startingStyle",e[e.endingStyle=Yr.endingStyle]="endingStyle",e.anchorHidden="data-anchor-hidden",e.side="data-side",e.align="data-align",e})({});var Mg={"data-popup-open":""};var Bg={"data-open":""},Hg={"data-closed":""},zg={"data-anchor-hidden":""},kl={open(e){return e?Mg:null}};var Qo={open(e){return e?Bg:Hg},anchorHidden(e){return e?zg:null}},Tl={...Qo,...Ha};function Pl(e){return po(19)?e:e?"true":void 0}var nr=b(z(),1),Oi=nr.createContext(void 0);function Eo(){return nr.useContext(Oi)?.direction??"ltr"}var qe=b(z(),1);var Dg=e=>({name:"arrow",options:e,async fn(t){let{x:o,y:n,placement:r,rects:i,platform:s,elements:a,middlewareData:l}=t,{element:c,padding:d=0,offsetParent:m="real"}=_t(e,t)||{};if(c==null)return{};let u=jn(d),f={x:o,y:n},p=Xo(r),g=Ko(p),h=await s.getDimensions(c),y=p==="y",_=y?"top":"left",v=y?"bottom":"right",w=y?"clientHeight":"clientWidth",R=i.reference[g]+i.reference[p]-f[p]-i.floating[g],x=f[p]-i.reference[p],S=m==="real"?await s.getOffsetParent?.(c):a.floating,E=a.floating[w]||i.floating[g];(!E||!await s.isElement?.(S))&&(E=a.floating[w]||i.floating[g]);let k=R/2-x/2,P=E/2-h[g]/2-1,N=Math.min(u[_],P),H=Math.min(u[v],P),j=N,L=E-h[g]-H,T=E/2-h[g]/2+k,I=zn(j,T,L),C=!l.arrow&&dt(r)!=null&&T!==I&&i.reference[g]/2-(T({...Dg(e),options:[e,t]});var Al={name:"hide",async fn(e){let{width:t,height:o,x:n,y:r}=e.rects.reference,i=t===0&&o===0&&n===0&&r===0,s=await e.platform.detectOverflow(e,{elementContext:"reference"});return{data:{referenceHidden:s.top-o>=0||s.right-t>=0||s.bottom-o>=0||s.left-t>=0||i}}}};var ko={sideX:"left",sideY:"top"};var Ol="--available-width",Nl="--available-height";function Ml(e,t,o){let n=e==="inline-start"||e==="inline-end";return{top:"top",right:n?o?"inline-start":"inline-end":"right",bottom:"bottom",left:n?o?"inline-end":"inline-start":"left"}[t]}function Il(e,t,o){let{rects:n,placement:r}=e;return{side:Ml(t,Ne(r),o),align:dt(r)||"center",anchor:{width:n.reference.width,height:n.reference.height},positioner:{width:n.floating.width,height:n.floating.height}}}function Bl(e){return jg(e,Sl)}function jg(e,t){let{anchor:o,positionMethod:n="absolute",side:r="bottom",sideOffset:i=0,align:s="center",alignOffset:a=0,collisionBoundary:l,collisionPadding:c=5,sticky:d=!1,arrowPadding:m=5,disableAnchorTracking:u=!1,inline:f,keepMounted:p=!1,floatingRootContext:g,mounted:h,collisionAvoidance:y,shift:_,nodeId:v,adaptiveOrigin:w,lazyFlip:R=!1,externalTree:x}=e,[S,E]=qe.useState(null);!h&&S!==null&&E(null);let k=y.side||"flip",P=y.align||"flip",N=y.fallbackAxisSide||"end",H=_?.crossAxis??!1,j=_?.rootBoundary,L=typeof o=="function"?o:void 0,T=Y(L),I=L?T:o,C=je(o),A=je(h),X=Eo()==="rtl",de=S||{top:"top",right:"right",bottom:"bottom",left:"left","inline-end":X?"left":"right","inline-start":X?"right":"left"}[r],O=s==="center"?de:`${de}-${s}`,V=c;typeof V=="number"?V={top:V,right:V,bottom:V,left:V}:V&&(V={top:V.top||0,right:V.right||0,bottom:V.bottom||0,left:V.left||0});let Z=1,ie=r==="bottom"?Z:0,K=r==="top"?Z:0,Q=r==="right"?Z:0,q=r==="left"?Z:0,$={boundary:l==="clipping-ancestors"?"clippingAncestors":l,padding:V},ne=qe.useRef(null),se=je(i),ze=je(a),ae=typeof i!="function"?i:0,ge=typeof a!="function"?a:0,be=[];f&&be.push(f),be.push(fi(te=>{let Je=Il(te,r,X),pt=typeof se.current=="function"?se.current(Je):se.current,Ue=typeof ze.current=="function"?ze.current(Je):ze.current;return{mainAxis:pt,crossAxis:Ue,alignmentAxis:Ue}},[ae,ge,X,r]));let Ee=P==="none"&&k!=="shift",ye=!Ee&&(d||H||k==="shift"),Kt=k==="none"?null:gi({...$,padding:{top:V.top+Z+ie,right:V.right+Z+q,bottom:V.bottom+Z+K,left:V.left+Z+Q},mainAxis:!H&&k==="flip",crossAxis:P==="flip"?"alignment":!1,fallbackAxisSideDirection:N}),rt=Ee?null:pi({...$,rootBoundary:j,mainAxis:P!=="none",crossAxis:ye,limiter:d||H?void 0:mi(te=>{if(!ne.current)return{};let{width:Je,height:pt}=ne.current.getBoundingClientRect(),Ue=Fe(Ne(te.placement)),kt=Ue==="y"?Je:pt,mt=Ue==="y"?V.left+V.right:V.top+V.bottom;return{offset:kt/2+mt/2}})},[$,d,H,j,V,P]);k==="shift"||P==="shift"||s==="center"?be.push(rt,Kt):be.push(Kt,rt),be.push(bi({...$,apply({elements:{floating:te},availableWidth:Je,availableHeight:pt,rects:Ue}){if(!A.current)return;let kt=te.style;kt.setProperty(Ol,`${Je}px`),kt.setProperty(Nl,`${pt}px`);let mt=fe(te).devicePixelRatio||1,{x:Mo,y:_n,width:yn,height:Ar}=Ue.reference,Or=(Math.round((Mo+yn)*mt)-Math.round(Mo*mt))/mt,Nr=(Math.round((_n+Ar)*mt)-Math.round(_n*mt))/mt;kt.setProperty("--anchor-width",`${Or}px`),kt.setProperty("--anchor-height",`${Nr}px`)}}),Cl(te=>({element:ne.current||Pe(te.elements.floating).createElement("div"),padding:m,offsetParent:"floating"}),[m]),{name:"transformOrigin",fn(te){let{elements:Je,middlewareData:pt,placement:Ue,rects:kt,y:mt}=te,Mo=Ne(Ue),_n=Fe(Mo),yn=ne.current,Ar=pt.arrow?.x||0,Or=pt.arrow?.y||0,Nr=yn?.clientWidth||0,Yf=yn?.clientHeight||0,Ir=Ar+Nr/2,la=Or+Yf/2,Uf=Math.abs(pt.shift?.y||0),Gf=kt.reference.height/2,Bo=typeof i=="function"?i(Il(te,r,X)):i,Kf=Uf>Bo,Xf={top:`${Ir}px calc(100% + ${Bo}px)`,bottom:`${Ir}px ${-Bo}px`,left:`calc(100% + ${Bo}px) ${la}px`,right:`${-Bo}px ${la}px`}[Mo],qf=`${Ir}px ${kt.reference.y+Gf-mt}px`;return Je.floating.style.setProperty("--transform-origin",ye&&_n==="y"&&Kf?qf:Xf),{}}},Al,w),F(()=>{!h&&g&&g.update({referenceElement:null,floatingElement:null,domReferenceElement:null,positionReference:null})},[h,g]);let ft=qe.useMemo(()=>({elementResize:!u&&typeof ResizeObserver<"u",layoutShift:!u&&typeof IntersectionObserver<"u"}),[u]),{refs:Ot,elements:xe,x:mn,y:B,middlewareData:D,update:Se,placement:Ae,context:Nt,isPositioned:it,floatingStyles:It}=t({rootContext:g,open:p?h:void 0,placement:O,middleware:be,strategy:n,whileElementsMounted:p?void 0:(...te)=>qo(...te,ft),nodeId:v,externalTree:x}),{sideX:Ye,sideY:uo}=D.adaptiveOrigin||ko,Xt=it?n:"fixed",gn=qe.useMemo(()=>{let te;return it?w?te={position:Xt,[Ye]:mn,[uo]:B}:te={...It,position:Xt}:te={position:Xt,top:0,left:0},te[Ol]="100vw",te[Nl]="100vh",it||(te.opacity=0),te},[w,Xt,Ye,mn,uo,B,It,it]),fo=qe.useRef(null);F(()=>{if(!h)return;let te=C.current,Je=typeof te=="function"?te():te,Ue=(Ll(Je)?Je.current:Je)||null||null;Ue!==fo.current&&(Ot.setPositionReference(Ue),fo.current=Ue)},[h,Ot,I,C]),qe.useEffect(()=>{if(!h)return;let te=C.current;typeof te!="function"&&Ll(te)&&te.current!==fo.current&&(Ot.setPositionReference(te.current),fo.current=te.current)},[h,Ot,I,C]),qe.useEffect(()=>{if(p&&h&&xe.reference&&xe.floating)return qo(xe.reference,xe.floating,Se,ft)},[p,h,xe,Se,ft]);let Lt=Ne(Ae),bn=Ml(r,Lt,X),hn=dt(Ae)||"center",wn=!!D.hide?.referenceHidden;F(()=>{R&&h&&it&&Lt!==de&&E(Lt)},[R,h,it,Lt,de]);let vn=qe.useMemo(()=>({position:"absolute",top:D.arrow?.y,left:D.arrow?.x}),[D.arrow]),ca=D.arrow?.centerOffset!==0;return qe.useMemo(()=>({positionerStyles:gn,arrowStyles:vn,arrowRef:ne,arrowUncentered:ca,side:bn,align:hn,physicalSide:Lt,anchorHidden:wn,refs:Ot,context:Nt,isPositioned:it,update:Se}),[gn,vn,ne,ca,bn,hn,Lt,wn,Ot,Nt,it,Se])}function Ll(e){return e!=null&&"current"in e}function rr(e){return e==="starting"?fc:me}function Hl(e,t,{styles:o,transitionStatus:n,props:r,refs:i,hidden:s,inert:a=!1}){let l={...o};return a&&(l.pointerEvents="none"),Oe("div",e,{state:t,ref:i,props:[{role:"presentation",hidden:s,style:l},rr(n),r],stateAttributesMapping:Qo})}var zl=b(z(),1);var Ni=zl.forwardRef(function(t,o){let{render:n,className:r,disabled:i=!1,focusableWhenDisabled:s=!1,nativeButton:a=!0,style:l,...c}=t,{getButtonProps:d,buttonRef:m}=Ya({disabled:i,focusableWhenDisabled:s,native:a});return Oe("button",t,{state:{disabled:i},ref:[o,m],props:[c,d]})});var Ce=b(z(),1),Kl=b(Ht(),1);var Dl=b(z(),1);function jl(e){let[t,o]=Dl.useState({current:e,previous:null});return Object.is(e,t.current)||o({current:e,previous:t.current}),t.previous}var To=b(z(),1);function Ii(e){let t=Le(e),o=parseFloat(t.width)||0,n=parseFloat(t.height)||0,r=he(e),i=r?e.offsetWidth:o,s=r?e.offsetHeight:n;return(jt(o)!==i||jt(n)!==s)&&(o=i,n=s),{width:o,height:n}}function Vl(e){let{popupElement:t,positionerElement:o,content:n,mounted:r,onMeasureLayout:i,onMeasureLayoutComplete:s,side:a,direction:l}=e,c=vo(t,!0),d=bo(),m=To.useRef(null),u=To.useRef(!0),f=To.useRef(Ge),p=Y(i),g=Y(s),h=To.useMemo(()=>Fg(a,l),[a,l]);F(()=>{if(!r){f.current=Ge,u.current=!0,m.current=null;return}if(!t||!o)return;f.current=Fl(t,h),Li(t,"auto");let y=sr(t,"position","static"),_=sr(t,"transform","none"),v=sr(t,"scale","1"),w=Fl(o,{"--available-width":"max-content","--available-height":"max-content"});function R(){y(),_(),w()}function x(){R(),v()}if(p?.(),u.current||m.current===null){ir(o,"max-content");let P=Ii(t);return m.current=P,ir(o,P),x(),g?.(null,P),u.current=!1,()=>{f.current(),f.current=Ge}}ir(o,"max-content");let S=m.current,E=Ii(t);m.current=E,Li(t,S),x(),g?.(S,E),ir(o,E);let k=new AbortController;return d.request(()=>{Li(t,E),c(()=>{t.style.setProperty("--popup-width","auto"),t.style.setProperty("--popup-height","auto")},k.signal)}),()=>{k.abort(),d.cancel(),f.current(),f.current=Ge}},[n,t,o,c,d,r,p,g,h])}function Fg(e,t){let o=e==="top",n=e==="left"||e===(t==="rtl"?"inline-end":"inline-start");return!o&&!n?me:{position:"absolute",[o?"bottom":"top"]:"0",[n?"right":"left"]:"0"}}function sr(e,t,o){let n=e.style.getPropertyValue(t);return e.style.setProperty(t,o),()=>{e.style.setProperty(t,n)}}function Fl(e,t){let o=[];for(let[n,r]of Object.entries(t))o.push(sr(e,n,r));return o.length?()=>{o.forEach(n=>n())}:Ge}function Li(e,t){let o=t==="auto"?"auto":`${t.width}px`,n=t==="auto"?"auto":`${t.height}px`;e.style.setProperty("--popup-width",o),e.style.setProperty("--popup-height",n)}function ir(e,t){let o=t==="max-content"?"max-content":`${t.width}px`,n=t==="max-content"?"max-content":`${t.height}px`;e.style.setProperty("--positioner-width",o),e.style.setProperty("--positioner-height",n)}var Wl=b(z(),1);var Yl=b(W(),1),ar=function(t){let{direction:o="ltr"}=t,n=Wl.useMemo(()=>({direction:o}),[o]);return(0,Yl.jsx)(Oi.Provider,{value:n,children:t.children})};var Ul={name:"adaptiveOrigin",async fn(e){let{x:t,y:o,rects:{floating:n},elements:{floating:r},platform:i,strategy:s,placement:a}=e,l=fe(r),c=l.getComputedStyle(r);if(!(c.transitionDuration!=="0s"&&c.transitionDuration!==""))return{x:t,y:o,data:ko};let m=await i.getOffsetParent?.(r),u={width:0,height:0};if(s==="fixed"&&l?.visualViewport)u={width:l.visualViewport.width,height:l.visualViewport.height};else if(m===l){let _=Pe(r);u={width:_.documentElement.clientWidth,height:_.documentElement.clientHeight}}else await i.isElement?.(m)&&(u=await i.getDimensions(m));let f=Ne(a),p=t,g=o;f==="left"&&(p=u.width-(t+n.width)),f==="top"&&(g=u.height-(o+n.height));let h=f==="left"?"right":ko.sideX,y=f==="top"?"bottom":ko.sideY;return{x:p,y:g,data:{sideX:h,sideY:y}}}};var Po=b(W(),1),Xl={activationDirection:e=>e?{"data-activation-direction":e}:null};function ql(e){let{store:t,side:o,children:n}=e,r=Eo(),i=t.useState("activeTriggerElement"),s=t.useState("activeTriggerId"),a=t.useState("open"),l=t.useState("payload"),c=t.useState("mounted"),d=t.useState("popupElement"),m=t.useState("positionerElement"),u=jl(a?i:null),f=Yg(s,l),p=Ce.useRef(null),[g,h]=Ce.useState(null),[y,_]=Ce.useState(null),v=Ce.useRef(null),w=Ce.useRef(null),R=vo(v,!0),x=bo(),S=Ce.useRef(null),[E,k]=Ce.useState(null),[P,N]=Ce.useState(!1);F(()=>(t.set("adaptiveOrigin",Ul),()=>{t.set("adaptiveOrigin",void 0)}),[t]);let H=Y(()=>{v.current?.style.setProperty("animation","none"),v.current?.style.setProperty("transition","none"),w.current?.style.setProperty("display","none")}),j=Y(M=>{v.current?.style.removeProperty("animation"),v.current?.style.removeProperty("transition"),w.current?.style.removeProperty("display"),M&&k(M)}),L=Y(()=>{S.current?.abort();let M=new AbortController;S.current=M,R(()=>{h(null),k(null),p.current=null},M.signal)}),T=Ce.useRef(null);F(()=>{(!a||!c)&&(T.current=null)},[a,c]),F(()=>{if(i&&u&&i!==u&&T.current!==i&&p.current){h(p.current),N(!0);let M=Wg(u,i);_(M),T.current=i}},[i,u]),F(()=>{g!=null&&(S.current?.abort(),N(!0),x.request(()=>{Kl.flushSync(()=>{N(!1)}),L()}))},[f,g,L,x]),F(()=>{let M=v.current;if(!M)return;let X=Pe(M).createElement("div");for(let de of Array.from(M.childNodes))X.appendChild(de.cloneNode(!0));p.current=X});let I=g!=null,C;I?C=(0,Po.jsxs)(Ce.Fragment,{children:[(0,Po.jsx)("div",{"data-previous":!0,inert:Pl(!0),ref:w,style:{...E?{"--popup-width":`${E.width}px`,"--popup-height":`${E.height}px`}:null,position:"absolute"},"data-ending-style":P?void 0:""},"previous"),(0,Po.jsx)("div",{"data-current":!0,ref:v,"data-starting-style":P?"":void 0,children:n},f)]}):C=(0,Po.jsx)("div",{"data-current":!0,ref:v,children:n},f),F(()=>{let M=w.current;!M||!g||M.replaceChildren(...Array.from(g.childNodes))},[g]),Vl({popupElement:d,positionerElement:m,mounted:c,content:l,onMeasureLayout:H,onMeasureLayoutComplete:j,side:o,direction:r});let A={activationDirection:Vg(y),transitioning:I};return{children:C,state:A}}function Vg(e){if(e)return`${Gl(e.horizontal,5,"right","left")} ${Gl(e.vertical,5,"down","up")}`}function Gl(e,t,o,n){return e>t?o:e<-t?n:""}function Wg(e,t){let o=e.getBoundingClientRect(),n=t.getBoundingClientRect(),r={x:o.left+o.width/2,y:o.top+o.height/2},i={x:n.left+n.width/2,y:n.top+n.height/2};return{horizontal:i.x-r.x,vertical:i.y-r.y}}function Yg(e,t){let[o,n]=Ce.useState(0),r=Ce.useRef(e),i=Ce.useRef(t),s=Ce.useRef(!1);return F(()=>{let a=r.current,l=i.current,c=e!==a,d=t!==l;c?(n(m=>m+1),s.current=!d):s.current&&d&&(n(m=>m+1),s.current=!1),r.current=e,i.current=t},[e,t]),`${e??"current"}-${o}`}var cr=b(z(),1),Zl=b(Ht(),1);var Ql=b(W(),1),Jl=cr.forwardRef(function(t,o){let{children:n,container:r,className:i,render:s,style:a,...l}=t,{node:c,subtree:d}=bc({container:r,ref:o,componentProps:t,elementProps:l});return!d&&!c?null:(0,Ql.jsxs)(cr.Fragment,{children:[d,c&&Zl.createPortal(n,c)]})});var tt={};Mt(tt,{Arrow:()=>hd,Handle:()=>$o,Popup:()=>gd,Portal:()=>ud,Positioner:()=>pd,Provider:()=>vd,Root:()=>rd,Trigger:()=>cd,Viewport:()=>yd,createHandle:()=>xd});var Co=b(z(),1);var lr=b(z(),1),Mi=lr.createContext(void 0);function et(e){let t=lr.useContext(Mi);if(t===void 0&&!e)throw new Error(De(72));return t}var $l=b(z(),1);var ed={..._l,disabled:e=>e.disabled,instantType:e=>e.instantType,isInstantPhase:e=>e.isInstantPhase,trackCursorAxis:e=>e.trackCursorAxis,disableHoverablePopup:e=>e.disableHoverablePopup,lastOpenChangeReason:e=>e.openChangeReason,closeOnClick:e=>e.closeOnClick,closeDelay:e=>e.closeDelay,adaptiveOrigin:e=>e.adaptiveOrigin},dr=class extends Vt{constructor(t,o,n){let r=new io;super(od(t,r,o,n),nd(r),ed)}setOpen=(t,o)=>{dl(this,t,o,{extraState:{openChangeReason:o.reason}})};cancelPendingOpen(t){this.state.floatingRootContext.dispatchOpenChange(!1,ee(G.triggerPress,t))}};function td(){let e=new io,t=new or(Object.freeze(od(void 0,e)),Object.freeze(nd(e)),ed);return Object.assign(t,{setOpen:Ge,cancelPendingOpen:Ge})}function od(e,t,o,n=!1){let r={...hl(),disabled:!1,instantType:void 0,isInstantPhase:!1,trackCursorAxis:"none",disableHoverablePopup:!1,openChangeReason:null,closeOnClick:!0,closeDelay:0,adaptiveOrigin:void 0,...e};return r.floatingRootContext=wl(t,o,n),r}function nd(e){return{popupRef:$l.createRef(),onOpenChange:void 0,onOpenChangeComplete:void 0,triggerElements:e}}var Jo=b(W(),1),rd=_i(function(t){let{disabled:o=!1,defaultOpen:n=!1,open:r,disableHoverablePopup:i=!1,trackCursorAxis:s="none",actionsRef:a,onOpenChange:l,onOpenChangeComplete:c,handle:d,triggerId:m,defaultTriggerId:u=null,children:f}=t,p=cl((N,H)=>new dr({open:n,openProp:r,activeTriggerId:u,triggerIdProp:m},N,H));p.useControlledProp("openProp",r),p.useControlledProp("triggerIdProp",m),p.useContextCallback("onOpenChange",l),p.useContextCallback("onOpenChangeComplete",c);let g=p.useState("open"),h=!o&&g,y=p.useState("activeTriggerId"),_=p.useState("mounted"),v=p.useState("payload");p.useSyncedValues({trackCursorAxis:s,disableHoverablePopup:i,disabled:o}),fl(p,{closeOnActiveTriggerUnmount:!0});let{forceUnmount:w,transitionStatus:R}=pl(h,p),x=p.useState("isInstantPhase"),S=p.useState("instantType"),E=p.useState("lastOpenChangeReason"),k=Co.useRef(null);F(()=>{g&&o&&p.setOpen(!1,ee(G.disabled))},[g,o,p]),F(()=>{R==="ending"&&E===G.none||R!=="ending"&&x?(S!=="delay"&&(k.current=S),p.set("instantType","delay")):k.current!==null&&(p.set("instantType",k.current),k.current=null)},[R,x,E,S,p]),F(()=>{h&&y==null&&p.set("payload",void 0)},[p,y,h]),Co.useImperativeHandle(a,()=>({unmount:w,close:()=>p.setOpen(!1,ee(G.imperativeAction))}),[w,p]);let P=h||_||!o&&s!=="none";return(0,Jo.jsxs)(Mi.Provider,{value:p,children:[d&&(0,Jo.jsx)(ll,{handle:d,store:p}),P&&(0,Jo.jsx)(Ug,{store:p,disabled:o,trackCursorAxis:s}),typeof f=="function"?f({payload:v}):f]})});function Ug({store:e,disabled:t,trackCursorAxis:o}){let n=e.useState("floatingRootContext"),r=ai(n,{enabled:!t,referencePress:()=>e.select("closeOnClick")}),i=si(n,{enabled:!t&&o!=="none",axis:o==="none"?void 0:o}),s=Co.useMemo(()=>ve(i.reference,r.reference),[i.reference,r.reference]);return ml(e,{activeTriggerProps:s,inactiveTriggerProps:s,popupProps:r.floating??me}),null}var fr=b(z(),1);var ur=b(z(),1),Bi=ur.createContext(void 0);function id(){return ur.useContext(Bi)}var ad="data-base-ui-tooltip-trigger";function sd(e){if("composedPath"in e){let o=e.composedPath();for(let n=0;nh.select("transitionStatus")==="ending",shouldOpen(){return!X.current}}),Q=Ei(w,{enabled:!I}).reference,q=ae=>{let ge=X.current,be=sd(ae),Ee=ie(be),ye=R.current,Kt=ye&&be&&re(ye,be);if(Ee&&h.select("open")&&h.select("lastOpenChangeReason")===G.triggerHover){h.setOpen(!1,ee(G.triggerHover,ae));return}if(ge&&!Ee&&Kt&&!C.current&&!h.select("open")&&ye&&Pt(O.current)){let rt=()=>{!X.current&&!C.current&&!h.select("open")&&h.setOpen(!0,ee(G.triggerHover,ae,ye))},ft=V();ft===0?(de.clear(),rt()):de.start(ft,rt)}},$=h.useState("triggerProps",k);return Oe("button",t,{state:{open:v},ref:[o,E,R],props:[K,Q,k||A!=="none"?$:void 0,{onMouseOver(ae){q(ae.nativeEvent)},onFocus(ae){Z(sd(ae.nativeEvent))&&ae.preventBaseUIHandler()},onMouseLeave(){X.current=!1,de.clear(),O.current=void 0},onPointerEnter(ae){O.current=ae.pointerType},onPointerDown(ae){O.current=ae.pointerType,h.set("closeOnClick",d),d&&!h.select("open")&&h.cancelPendingOpen(ae.nativeEvent)},onClick(ae){d&&!h.select("open")&&h.cancelPendingOpen(ae.nativeEvent)},id:y,"data-trigger-disabled":I?"":void 0,[ad]:I?void 0:""},f],stateAttributesMapping:kl})});var dd=b(z(),1);var pr=b(z(),1),Hi=pr.createContext(void 0);function ld(){let e=pr.useContext(Hi);if(e===void 0)throw new Error(De(70));return e}var zi=b(W(),1),ud=dd.forwardRef(function(t,o){let{keepMounted:n=!1,...r}=t;return et().useState("mounted")||n?(0,zi.jsx)(Hi.Provider,{value:n,children:(0,zi.jsx)(Jl,{ref:o,...r})}):null});var gr=b(z(),1);var mr=b(z(),1),Di=mr.createContext(void 0);function Ao(){let e=mr.useContext(Di);if(e===void 0)throw new Error(De(71));return e}var fd=b(W(),1),pd=gr.forwardRef(function(t,o){let{render:n,className:r,anchor:i,positionMethod:s="absolute",side:a="top",align:l="center",sideOffset:c=0,alignOffset:d=0,collisionBoundary:m="clipping-ancestors",collisionPadding:u=5,arrowPadding:f=5,sticky:p=!1,disableAnchorTracking:g=!1,collisionAvoidance:h=pc,style:y,..._}=t,v=et(),w=ld(),R=v.useState("open"),x=v.useState("mounted"),S=v.useState("trackCursorAxis"),E=v.useState("disableHoverablePopup"),k=v.useState("floatingRootContext"),P=v.useState("instantType"),N=v.useState("transitionStatus"),H=v.useState("adaptiveOrigin"),j=Bl({anchor:i,positionMethod:s,floatingRootContext:k,mounted:x,side:a,sideOffset:c,align:l,alignOffset:d,collisionBoundary:m,collisionPadding:u,sticky:p,arrowPadding:f,disableAnchorTracking:g,keepMounted:w,collisionAvoidance:h,adaptiveOrigin:H}),L=gr.useMemo(()=>({open:R,side:j.side,align:j.align,anchorHidden:j.anchorHidden,instant:S!=="none"?"tracking-cursor":P}),[R,j.side,j.align,j.anchorHidden,S,P]),T=Hl(t,L,{styles:j.positionerStyles,transitionStatus:N,props:_,refs:[o,v.useStateSetter("positionerElement")],hidden:!x,inert:!R||S==="both"||E});return(0,fd.jsx)(Di.Provider,{value:j,children:T})});var md=b(z(),1);var gd=md.forwardRef(function(t,o){let{render:n,className:r,style:i,...s}=t,a=et(),{side:l,align:c}=Ao(),d=a.useState("open"),m=a.useState("instantType"),u=a.useState("transitionStatus"),f=a.useState("popupProps"),p=a.useState("floatingRootContext"),g=a.useState("disabled"),h=a.useState("closeDelay");In({open:d,ref:a.context.popupRef,onComplete(){d&&a.context.onOpenChangeComplete?.(!0)}}),Pi(p,{enabled:!g,closeDelay:h});let y=a.useStateSetter("popupElement");return Oe("div",t,{state:{open:d,side:l,align:c,instant:m,transitionStatus:u},ref:[o,a.context.popupRef,y],props:[al,f,rr(u),s],stateAttributesMapping:Tl})});var bd=b(z(),1);var hd=bd.forwardRef(function(t,o){let{render:n,className:r,style:i,...s}=t,a=et(),{arrowRef:l,side:c,align:d,arrowUncentered:m,arrowStyles:u}=Ao(),f=a.useState("open"),p=a.useState("instantType");return Oe("div",t,{state:{open:f,side:c,align:d,uncentered:m,instant:p},ref:[o,l],props:[{style:u,"aria-hidden":!0},s],stateAttributesMapping:Qo})});var wd=b(z(),1);var ji=b(W(),1),vd=function(t){let{delay:o,closeDelay:n,timeout:r=400}=t,i=wd.useMemo(()=>({open:o,close:n}),[o,n]);return(0,ji.jsx)(Bi.Provider,{value:o,children:(0,ji.jsx)(ri,{delay:i,timeoutMs:r,children:t.children})})};var _d=b(z(),1);var yd=_d.forwardRef(function(t,o){let{render:n,className:r,style:i,children:s,...a}=t,l=et(),c=Ao(),d=l.useState("instantType"),{children:m,state:u}=ql({store:l,side:c.side,children:s}),f={activationDirection:u.activationDirection,transitioning:u.transitioning,instant:d};return Oe("div",t,{state:f,ref:o,props:[a,{children:m}],stateAttributesMapping:Xl})});var $o=class extends Gn{constructor(){super(td(),"Tooltip")}open(t){this.openByTrigger(t)}close(){this.closePopup()}get isOpen(){return this.attachedStore?.select("open")??!1}};function xd(){return new $o}function ot(e){return Oe(e.defaultTagName??"div",e,e)}var Ed=b(ce(),1),Fi="data-wp-hash";function Vi(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&qg(document)),e.__wpStyleRuntime}function Xg(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Fi}]`))if(o.getAttribute(Fi)===t)return!0;return!1}function kd(e,t,o){if(!e.head)return;let n=Vi(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Xg(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Fi,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function qg(e){let t=Vi();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)kd(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Td(e,t){let o=Vi();o.styles.set(e,t);for(let n of o.documents.keys())kd(n,e,t)}typeof process>"u",Td("3167e7d116",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._83ed8a8da5dd50ea__text{text-wrap:pretty;margin:0}._14437cfb77831647__heading-2xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-2xl,32px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-2xl,32px);--_gcd-p-line-height:var(--wpds-typography-line-height-2xl,40px);font-size:var(--wpds-typography-font-size-2xl,32px);line-height:var(--wpds-typography-line-height-2xl,40px)}._14437cfb77831647__heading-2xl,._3c78b7fa9b4072dd__heading-xl{font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-emphasis,600)}._3c78b7fa9b4072dd__heading-xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-p-line-height:var(--wpds-typography-line-height-md,24px);font-size:var(--wpds-typography-font-size-xl,20px);line-height:var(--wpds-typography-line-height-md,24px)}.aa58f227716bcde2__heading-lg{--_gcd-heading-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-lg,15px)}.aa58f227716bcde2__heading-lg,.fc4da56d8dfe52c4__heading-md{font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:var(--wpds-typography-line-height-sm,20px)}.fc4da56d8dfe52c4__heading-md{--_gcd-heading-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-md,13px)}.a9b78c7c82e8dff7__heading-sm{--_gcd-heading-font-size:var(--wpds-typography-font-size-xs,11px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-xs,11px);--_gcd-p-line-height:var(--wpds-typography-line-height-xs,16px);font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-xs,11px);font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:var(--wpds-typography-line-height-xs,16px);text-transform:uppercase}._305ff559e52180d5__body-xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-p-line-height:var(--wpds-typography-line-height-xl,32px);font-size:var(--wpds-typography-font-size-xl,20px);line-height:var(--wpds-typography-line-height-xl,32px)}._305ff559e52180d5__body-xl,.ca1aa3fc2029e958__body-lg{font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-default,400)}.ca1aa3fc2029e958__body-lg{--_gcd-heading-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-p-line-height:var(--wpds-typography-line-height-md,24px);font-size:var(--wpds-typography-font-size-lg,15px);line-height:var(--wpds-typography-line-height-md,24px)}._131101940be12424__body-md{--_gcd-heading-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-md,13px);line-height:var(--wpds-typography-line-height-sm,20px)}._0e8d87a42c1f75fa__body-sm,._131101940be12424__body-md{font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-default,400)}._0e8d87a42c1f75fa__body-sm{--_gcd-heading-font-size:var(--wpds-typography-font-size-sm,12px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-sm,12px);--_gcd-p-line-height:var(--wpds-typography-line-height-xs,16px);font-size:var(--wpds-typography-font-size-sm,12px);line-height:var(--wpds-typography-line-height-xs,16px)}}}');var Sd={text:"_83ed8a8da5dd50ea__text","heading-2xl":"_14437cfb77831647__heading-2xl","heading-xl":"_3c78b7fa9b4072dd__heading-xl","heading-lg":"aa58f227716bcde2__heading-lg","heading-md":"fc4da56d8dfe52c4__heading-md","heading-sm":"a9b78c7c82e8dff7__heading-sm","body-xl":"_305ff559e52180d5__body-xl","body-lg":"ca1aa3fc2029e958__body-lg","body-md":"_131101940be12424__body-md","body-sm":"_0e8d87a42c1f75fa__body-sm"};typeof process>"u",Td("e8e31009f5","._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-weak,#707070))}&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}.c59a0ebebd71fa4a__ol{list-style:var(--_gcd-ol-list-style,none);margin:var(--_gcd-ol-margin,0);padding-block:var(--_gcd-ol-padding-block,0);padding-inline:var(--_gcd-ol-padding-inline,0)}._46b5cb0c8e24e8c9__li{margin:var(--_gcd-li-margin,0)}");var Rd={button:"_6defc79820e382c6__button",input:"d2cff2e5dea83bd1__input",textarea:"_547d86373d02e108__textarea",div:"_8c15fd0ed9f28ba4__div",p:"_43cec3e1eec1066d__p",heading:"e97669c6d9a38497__heading",a:"_2c0831b0499dbd6e__a",ol:"c59a0ebebd71fa4a__ol",li:"_46b5cb0c8e24e8c9__li"},We=(0,Ed.forwardRef)(function({variant:t="body-md",render:o,className:n,...r},i){return ot({render:o,defaultTagName:"span",ref:i,props:ve(r,{className:J(Sd.text,Rd.heading,Rd.p,Sd[t],n)})})});var Od=b(W(),1),Wi="data-wp-hash";function Yi(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Qg(document)),e.__wpStyleRuntime}function Zg(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Wi}]`))if(o.getAttribute(Wi)===t)return!0;return!1}function Ad(e,t,o){if(!e.head)return;let n=Yi(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Zg(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Wi,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Qg(e){let t=Yi();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Ad(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Jg(e,t){let o=Yi();o.styles.set(e,t);for(let n of o.documents.keys())Ad(n,e,t)}typeof process>"u",Jg("59353631d1","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._96e6251aad1a6136__badge{border-radius:var(--wpds-border-radius-lg,8px);padding-block:var(--wpds-dimension-padding-xs,4px);padding-inline:var(--wpds-dimension-padding-sm,8px)}._99f7158cb520f750__is-high-intent{background-color:var(--wpds-color-background-surface-error,#f7e6e3);color:var(--wpds-color-foreground-content-error,#470000)}.c20ebef2365bc8b7__is-medium-intent{background-color:var(--wpds-color-background-surface-warning,#fae8c8);color:var(--wpds-color-foreground-content-warning,#2e1900)}._365e1626c6202e52__is-low-intent{background-color:var(--wpds-color-background-surface-caution,#ffea8f);color:var(--wpds-color-foreground-content-caution,#281d00)}._33f8198127ddf4ef__is-stable-intent{background-color:var(--wpds-color-background-surface-success,#ccf4d2);color:var(--wpds-color-foreground-content-success,#002900)}._04c1aca8fc449412__is-informational-intent{background-color:var(--wpds-color-background-surface-info,#e0ebf8);color:var(--wpds-color-foreground-content-info,#001b4f)}._90726e69d495ec19__is-draft-intent{background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);color:var(--wpds-color-foreground-content-neutral,#1e1e1e)}._898f4a544993bd39__is-none-intent{background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);padding-block:calc(var(--wpds-dimension-padding-xs, 4px) - var(--wpds-border-width-xs, 1px));padding-inline:calc(var(--wpds-dimension-padding-sm, 8px) - var(--wpds-border-width-xs, 1px))}}}");var Pd={badge:"_96e6251aad1a6136__badge","is-high-intent":"_99f7158cb520f750__is-high-intent","is-medium-intent":"c20ebef2365bc8b7__is-medium-intent","is-low-intent":"_365e1626c6202e52__is-low-intent","is-stable-intent":"_33f8198127ddf4ef__is-stable-intent","is-informational-intent":"_04c1aca8fc449412__is-informational-intent","is-draft-intent":"_90726e69d495ec19__is-draft-intent","is-none-intent":"_898f4a544993bd39__is-none-intent"},Ui=(0,Cd.forwardRef)(function({intent:t="none",className:o,...n},r){return(0,Od.jsx)(We,{ref:r,className:J(Pd.badge,Pd[`is-${t}-intent`],o),...n,variant:"body-sm"})});var Qd=b(ce(),1);var Bd=b(ce(),1);var Ki="data-wp-hash";function Xi(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&eb(document)),e.__wpStyleRuntime}function $g(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Ki}]`))if(o.getAttribute(Ki)===t)return!0;return!1}function Id(e,t,o){if(!e.head)return;let n=Xi(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if($g(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Ki,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function eb(e){let t=Xi();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Id(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function tb(e,t){let o=Xi();o.styles.set(e,t);for(let n of o.documents.keys())Id(n,e,t)}typeof process>"u",tb("be37f31c1e","._11fc52b637ff8a7e__slot{inset:0;isolation:isolate;pointer-events:none;position:fixed;z-index:1000000003}@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._11fc52b637ff8a7e__slot>*{pointer-events:auto}}}");var Nd={slot:"_11fc52b637ff8a7e__slot"},Ld="data-wp-compat-overlay-slot";function ob(){return typeof document>"u"?null:document}function nb(){let e;try{e=window.top?.wp}catch{}let t=e??window.wp;return typeof t?.components=="object"&&t.components!==null}var xt=null;function Gi(e){return e.setAttribute("aria-hidden","false"),e}function rb(e){let t=e.createElement("div");return t.setAttribute(Ld,""),Nd.slot&&t.classList.add(Nd.slot),e.body.appendChild(t),t}function Md(){if(typeof window>"u"||!nb()&&window.__wpUiCompatOverlaySlotEnabled!==!0)return;let e=ob();if(!e||!e.body)return;if(xt&&xt.ownerDocument===e&&xt.isConnected)return Gi(xt);let t=e.querySelector(`[${Ld}]`);return t instanceof HTMLDivElement?(xt=Gi(t),xt):(xt?.isConnected&&xt.remove(),xt=Gi(rb(e)),xt)}var Hd=b(W(),1),zd=(0,Bd.forwardRef)(function({container:t,...o},n){return(0,Hd.jsx)(tt.Portal,{container:t??Md(),...o,ref:n})});var Dd=b(ce(),1),Vd=b(W(),1),qi="data-wp-hash";function Zi(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&sb(document)),e.__wpStyleRuntime}function ib(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${qi}]`))if(o.getAttribute(qi)===t)return!0;return!1}function jd(e,t,o){if(!e.head)return;let n=Zi(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(ib(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(qi,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function sb(e){let t=Zi();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)jd(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Fd(e,t){let o=Zi();o.styles.set(e,t);for(let n of o.documents.keys())jd(n,e,t)}typeof process>"u",Fd("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var ab={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",Fd("19fcc06039",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}');var cb={positioner:"_480b748dd3510e64__positioner",popup:"_50096b232db7709d__popup"},Wd=(0,Dd.forwardRef)(function({align:t="center",className:o,side:n="top",sideOffset:r=4,...i},s){return(0,Vd.jsx)(tt.Positioner,{ref:s,align:t,side:n,sideOffset:r,...i,className:J(ab["box-sizing"],cb.positioner,o)})});var Yd=b(ce(),1);function Qi(e,t,o){return(0,Yd.cloneElement)(e??t,{children:o})}var lb=b(Gd(),1);var Xd=b(Ji(),1),{lock:M4,unlock:qd}=(0,Xd.__dangerousOptInToUnstableAPIsOnlyForCoreModules)("I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.","@wordpress/ui");function db(){let e=lb;if(e.ThemeProvider)return e.ThemeProvider;if(!e.privateApis)throw new Error("@wordpress/ui: @wordpress/theme must expose `ThemeProvider` or `privateApis.ThemeProvider`.");return qd(e.privateApis).ThemeProvider}var Zd=db();var en=b(W(),1),$i="data-wp-hash";function es(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&fb(document)),e.__wpStyleRuntime}function ub(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${$i}]`))if(o.getAttribute($i)===t)return!0;return!1}function Jd(e,t,o){if(!e.head)return;let n=es(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(ub(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute($i,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function fb(e){let t=es();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Jd(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function pb(e,t){let o=es();o.styles.set(e,t);for(let n of o.documents.keys())Jd(n,e,t)}typeof process>"u",pb("19fcc06039",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}');var mb={positioner:"_480b748dd3510e64__positioner",popup:"_50096b232db7709d__popup"},gb={background:"#1e1e1e"},ts=(0,Qd.forwardRef)(function({portal:t,positioner:o,children:n,className:r,...i},s){let a=(0,en.jsx)(Zd,{color:gb,children:(0,en.jsx)(tt.Popup,{ref:s,className:J(mb.popup,r),...i,children:n})}),l=Qi(o,(0,en.jsx)(Wd,{}),a);return Qi(t,(0,en.jsx)(zd,{}),l)});var $d=b(ce(),1),eu=b(W(),1),os=(0,$d.forwardRef)(function(t,o){return(0,eu.jsx)(tt.Trigger,{ref:o,...t})});var tu=b(st(),1),ou=b(W(),1);function nu({children:e}){return(0,ou.jsx)(ar,{direction:(0,tu.isRTL)()?"rtl":"ltr",children:e})}var ns=b(W(),1);function rs(e){return(0,ns.jsx)(nu,{children:(0,ns.jsx)(tt.Root,{...e})})}var ru=b(ce(),1),iu=b(st(),1),Oo=b(W(),1),is="data-wp-hash";function ss(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&wb(document)),e.__wpStyleRuntime}function hb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${is}]`))if(o.getAttribute(is)===t)return!0;return!1}function su(e,t,o){if(!e.head)return;let n=ss(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(hb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(is,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function wb(e){let t=ss();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)su(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function hr(e,t){let o=ss();o.styles.set(e,t);for(let n of o.documents.keys())su(n,e,t)}typeof process>"u",hr("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var vb={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",hr("08122b3d53","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{.af79fb116edb0dd7__outset-ring--focus:focus,.dfcfdc28396e5d98__outset-ring--focus-visible:focus-visible,.e5cd9ee879f6403a__outset-ring--focus-within:focus-within,:focus-visible ._81935a08e952f267__outset-ring--focus-parent-visible{--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within,.abc777e9713fa711__outset-ring--focus-except-active:focus{outline:none}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within:not(:has(:active)),.abc777e9713fa711__outset-ring--focus-except-active:focus:not(:active){--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}}}");var _b={"outset-ring--focus":"af79fb116edb0dd7__outset-ring--focus","outset-ring--focus-visible":"dfcfdc28396e5d98__outset-ring--focus-visible","outset-ring--focus-within":"e5cd9ee879f6403a__outset-ring--focus-within","outset-ring--focus-parent-visible":"_81935a08e952f267__outset-ring--focus-parent-visible","outset-ring--focus-except-active":"abc777e9713fa711__outset-ring--focus-except-active","outset-ring--focus-within-except-active":"_3c9f5ee9fc9c136d__outset-ring--focus-within-except-active"};typeof process>"u",hr("e8e6a9be37",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.d4250949359b05ce__link{text-decoration-thickness:from-font;text-underline-offset:.2em}.c6055659b8e2cd2c__is-brand,.c6055659b8e2cd2c__is-brand:visited{--_gcd-a-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9))}.c6055659b8e2cd2c__is-brand:active,.c6055659b8e2cd2c__is-brand:hover{--_gcd-a-color:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));color:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000))}._92e0dfcaeee15b88__is-neutral,._92e0dfcaeee15b88__is-neutral:visited{--_gcd-a-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);text-decoration-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d)}._92e0dfcaeee15b88__is-neutral:active,._92e0dfcaeee15b88__is-neutral:hover{--_gcd-a-color:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);color:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e)}.cf122a9bf1035d42__is-unstyled{--_gcd-a-color:inherit;color:inherit;text-decoration:none}._0cb411afac4c86c7__link-icon{display:inline-block;font-weight:var(--wpds-typography-font-weight-default,400);line-height:1;margin-inline-start:var(--wpds-dimension-padding-xs,4px);text-decoration:none}._0cb411afac4c86c7__link-icon:after{content:"\\2197"}._0cb411afac4c86c7__link-icon:dir(rtl):after{content:"\\2196"}}}');var br={link:"d4250949359b05ce__link","is-brand":"c6055659b8e2cd2c__is-brand","is-neutral":"_92e0dfcaeee15b88__is-neutral","is-unstyled":"cf122a9bf1035d42__is-unstyled","link-icon":"_0cb411afac4c86c7__link-icon"};typeof process>"u",hr("e8e31009f5","._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-weak,#707070))}&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}.c59a0ebebd71fa4a__ol{list-style:var(--_gcd-ol-list-style,none);margin:var(--_gcd-ol-margin,0);padding-block:var(--_gcd-ol-padding-block,0);padding-inline:var(--_gcd-ol-padding-inline,0)}._46b5cb0c8e24e8c9__li{margin:var(--_gcd-li-margin,0)}");var yb={button:"_6defc79820e382c6__button",input:"d2cff2e5dea83bd1__input",textarea:"_547d86373d02e108__textarea",div:"_8c15fd0ed9f28ba4__div",p:"_43cec3e1eec1066d__p",heading:"e97669c6d9a38497__heading",a:"_2c0831b0499dbd6e__a",ol:"c59a0ebebd71fa4a__ol",li:"_46b5cb0c8e24e8c9__li"},so=(0,ru.forwardRef)(function({children:t,variant:o="default",tone:n="brand",openInNewTab:r=!1,target:i,render:s,className:a,...l},c){let d=r||/^_blank$/i.test(i??"");return ot({render:s,defaultTagName:"a",ref:c,props:ve(l,{className:J(yb.a,vb["box-sizing"],_b["outset-ring--focus-except-active"],o!=="unstyled"&&br.link,o!=="unstyled"&&br[`is-${n}`],o==="unstyled"&&br["is-unstyled"],a),target:i??(r?"_blank":void 0),children:(0,Oo.jsxs)(Oo.Fragment,{children:[t,d&&(0,Oo.jsx)("span",{className:br["link-icon"],role:"img","aria-label":(0,iu.__)("(opens in a new tab)")})]})})})});var wr=b(ao(),1),as=b(W(),1),cs=(0,as.jsx)(wr.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",style:{fill:"none"},stroke:"currentColor",strokeWidth:"1.5",children:(0,as.jsx)(wr.Path,{d:"M12 8L12 13M12 14.5L12 16M4.75 12C4.75 7.99593 7.99594 4.75 12 4.75C16.0041 4.75 19.25 7.99594 19.25 12C19.25 16.0041 16.0041 19.25 12 19.25C7.99594 19.25 4.75 16.0041 4.75 12Z",strokeLinejoin:"round",vectorEffect:"non-scaling-stroke"})});var vr=b(ao(),1),ls=b(W(),1),ds=(0,ls.jsx)(vr.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",style:{fill:"none"},stroke:"currentColor",strokeWidth:"1.5",children:(0,ls.jsx)(vr.Path,{d:"M7.75 16.25L16.25 7.75M16.25 16.25L7.75 7.75",vectorEffect:"non-scaling-stroke"})});var _r=b(ao(),1),us=b(W(),1),fs=(0,us.jsx)(_r.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,us.jsx)(_r.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M12.218 5.377a.25.25 0 0 0-.436 0l-7.29 12.96a.25.25 0 0 0 .218.373h14.58a.25.25 0 0 0 .218-.372l-7.29-12.96Zm-1.743-.735c.669-1.19 2.381-1.19 3.05 0l7.29 12.96a1.75 1.75 0 0 1-1.525 2.608H4.71a1.75 1.75 0 0 1-1.525-2.608l7.29-12.96ZM12.75 17.46h-1.5v-1.5h1.5v1.5Zm-1.5-3h1.5v-5h-1.5v5Z"})});var yr=b(ao(),1),ps=b(W(),1),ms=(0,ps.jsx)(yr.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",style:{fill:"none"},stroke:"currentColor",strokeWidth:"1.5",children:(0,ps.jsx)(yr.Path,{d:"M12 16V11M12 9.5V8M19.25 12C19.25 16.0041 16.0041 19.25 12 19.25C7.99594 19.25 4.75 16.0041 4.75 12C4.75 7.99594 7.99594 4.75 12 4.75C16.0041 4.75 19.25 7.99594 19.25 12Z",strokeLinejoin:"round",vectorEffect:"non-scaling-stroke"})});var tn=b(ao(),1),on=b(W(),1),gs=(0,on.jsxs)(tn.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",style:{fill:"none"},stroke:"currentColor",strokeWidth:"1.5",children:[(0,on.jsx)(tn.Path,{d:"M12 19.25C16.0041 19.25 19.25 16.0041 19.25 12C19.25 7.99594 16.0041 4.75 12 4.75C7.99594 4.75 4.75 7.99594 4.75 12C4.75 16.0041 7.99594 19.25 12 19.25Z",strokeLinejoin:"round",vectorEffect:"non-scaling-stroke"}),(0,on.jsx)(tn.Path,{d:"M9 12L11 14L15 10",vectorEffect:"non-scaling-stroke"})]});var cu=b(ce(),1),lu=b(ao(),1),du=b(W(),1),co=(0,cu.forwardRef)(function({icon:t,size:o=24,style:n,...r},i){let s=t.props.style||n?{...t.props.style,...n}:void 0;return(0,du.jsx)(lu.SVG,{ref:i,...t.props,...r,...s?{style:s}:{},width:o,height:o})});var nn=b(ce(),1),Sr=b(st(),1);var uu=b(ce(),1),bs="data-wp-hash";function hs(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Sb(document)),e.__wpStyleRuntime}function xb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${bs}]`))if(o.getAttribute(bs)===t)return!0;return!1}function fu(e,t,o){if(!e.head)return;let n=hs(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(xb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(bs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Sb(e){let t=hs();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)fu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Rb(e,t){let o=hs();o.styles.set(e,t);for(let n of o.documents.keys())fu(n,e,t)}typeof process>"u",Rb("fa606a57ae","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.f37b9e2e191ebd66__visually-hidden{word-wrap:normal;border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-break:normal}}}");var Eb={"visually-hidden":"f37b9e2e191ebd66__visually-hidden"},ws=(0,uu.forwardRef)(function({render:t,...o},n){return ot({render:t,ref:n,props:ve({className:Eb["visually-hidden"]},o,{"data-visually-hidden":""})})});var xr=b(W(),1);function pu({"aria-describedby":e,"aria-keyshortcuts":t,shortcut:o}){let n=(0,nn.useId)(),r=o?n:void 0,i=[e,r].filter(Boolean).join(" ");return{descriptionId:r,targetProps:{"aria-describedby":i||void 0,"aria-keyshortcuts":o?.ariaKeyShortcut??t}}}var mu=(0,nn.forwardRef)(function({descriptionId:t,shortcut:o},n){return(0,xr.jsx)(ws,{id:t,"aria-hidden":"true",render:(0,xr.jsx)("span",{ref:n}),children:(0,Sr.sprintf)((0,Sr.__)("Keyboard shortcut: %s"),o.label??o.ariaKeyShortcut)})}),gu=(0,nn.forwardRef)(function({className:t,shortcut:o},n){return(0,xr.jsx)("span",{ref:n,"aria-hidden":"true",className:t,dir:"ltr",children:o.displayShortcut})});var Rr=b(ce(),1),bu=b(st(),1),wu=b(W(),1);import{speak as kb}from"@wordpress/a11y";var vs="data-wp-hash";function _s(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Pb(document)),e.__wpStyleRuntime}function Tb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${vs}]`))if(o.getAttribute(vs)===t)return!0;return!1}function hu(e,t,o){if(!e.head)return;let n=_s(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Tb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(vs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Pb(e){let t=_s();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)hu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Er(e,t){let o=_s();o.styles.set(e,t);for(let n of o.documents.keys())hu(n,e,t)}typeof process>"u",Er("effc4e3032",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._97b0fc33c028be1a__button,.abbb272e2ce49bd6__is-unstyled{appearance:none;padding:0}._97b0fc33c028be1a__button{--wp-ui-button-font-weight:var(--wpds-typography-font-weight-emphasis,600);--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-strong,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-strong-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 93%,#000));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand-strong,#fff);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-strong-active,#fff);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-strong-disabled,#8d8d8d);--wp-ui-button-padding-block:var(--wpds-dimension-padding-xs,4px);--wp-ui-button-padding-inline:var(--wpds-dimension-padding-md,12px);--wp-ui-button-height:var(--wpds-dimension-size-lg,40px);--wp-ui-button-aspect-ratio:auto;--wp-ui-button-font-size:var(--wpds-typography-font-size-md,13px);--wp-ui-button-min-width:calc(4ch + var(--wp-ui-button-padding-inline)*2);--wp-ui-button-icon-margin:calc((var(--wpds-dimension-size-2xs, 16px) - var(--wpds-dimension-size-sm, 24px))/2);--wp-ui-button-border-color:var(--wp-ui-button-background-color);--wp-ui-button-border-color-active:var(--wp-ui-button-background-color-active);--wp-ui-button-border-color-disabled:var(--wp-ui-button-background-color-disabled);--_gcd-button-font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);--_gcd-button-font-size:var(--wp-ui-button-font-size);--_gcd-button-font-weight:var(--wp-ui-button-font-weight);align-items:center;aspect-ratio:var(--wp-ui-button-aspect-ratio);background-clip:border-box;background-color:var(--wp-ui-button-background-color);border-color:var(--wp-ui-button-border-color);border-radius:var(--wpds-border-radius-sm,2px);border-style:solid;border-width:1px;color:var(--wp-ui-button-foreground-color);display:inline-flex;font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wp-ui-button-font-size);font-weight:var(--wp-ui-button-font-weight);gap:var(--wpds-dimension-gap-sm,8px);justify-content:center;line-height:var(--wpds-typography-line-height-sm,20px);max-width:100%;min-height:var(--wp-ui-button-height);min-width:var(--wp-ui-button-min-width);overflow-wrap:anywhere;padding-block:var(--wp-ui-button-padding-block);padding-inline:var(--wp-ui-button-padding-inline);position:relative;text-align:center;text-decoration:none;&:not([data-disabled]){cursor:var(--wpds-cursor-control,pointer)}@media not (prefers-reduced-motion){transition:color .1s ease-out;*{transition:opacity .1s ease-out}}&[href]{cursor:pointer}[href]{color:inherit;text-decoration:inherit}&:not([data-disabled]):is(:hover,:active,:focus){background-color:var(--wp-ui-button-background-color-active);border-color:var(--wp-ui-button-border-color-active);color:var(--wp-ui-button-foreground-color-active)}&[data-disabled]:not(._914b42f315c0e580__is-loading){background-color:var(--wp-ui-button-background-color-disabled);border-color:var(--wp-ui-button-border-color-disabled);color:var(--wp-ui-button-foreground-color-disabled);@media (forced-colors:active){border-bottom-color:GrayText;border-left-color:GrayText;border-right-color:GrayText;border-top-color:GrayText;color:GrayText}}&:before{aspect-ratio:1;border:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid;border-block-end-color:transparent;border-block-start-color:var(--wp-ui-button-foreground-color);border-inline-end-color:var(--wp-ui-button-foreground-color);border-inline-start-color:transparent;border-radius:50%;box-sizing:border-box;content:"";display:block;height:var(--wp-ui-button-font-size);left:50%;opacity:0;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);@media not (prefers-reduced-motion){transition:opacity .1s ease-out}@media (forced-colors:active){border-block-end-style:none;border-bottom-color:ButtonText;border-inline-start-style:none;border-left-color:ButtonText;border-right-color:ButtonText;border-top-color:ButtonText}}}._908205475f9f2a92__is-small{--wp-ui-button-padding-block:0px;--wp-ui-button-padding-inline:var(--wpds-dimension-padding-sm,8px);--wp-ui-button-height:var(--wpds-dimension-size-sm,24px)}._9f6fc6553aeb36fe__icon{margin:var(--wp-ui-button-icon-margin)}.dd460c965226cc77__is-brand{&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 85%,#000));--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-brand-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000)}}.e722a8f96726aa99__is-neutral{&.ad0619a3217c6a5b__is-minimal[aria-pressed=true],&.b50b3358c5fb4d0b__is-solid{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-strong,#2d2d2d);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-strong-active,#1e1e1e);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral-strong,#f0f0f0);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-strong-active,#f0f0f0);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-strong-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d);--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-neutral-active,#6e6e6e);--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-neutral-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000)}}.abbb272e2ce49bd6__is-unstyled{background:none;border:none;min-width:unset}.cf59cf1b69629838__is-compact{--wp-ui-button-height:var(--wpds-dimension-size-md,32px)}._914b42f315c0e580__is-loading:not(.abbb272e2ce49bd6__is-unstyled){color:transparent;&:not([data-disabled]):is(:hover,:active,:focus){color:transparent}@media (forced-colors:active){color:ButtonFace}*{opacity:0}&:before{opacity:1;transition-delay:.05s;@media not (prefers-reduced-motion){animation:_5a1d53da6f830c8d__loading-animation 1s linear infinite}}}}@keyframes _5a1d53da6f830c8d__loading-animation{0%{transform:translate(-50%,-50%) rotate(0deg)}to{transform:translate(-50%,-50%) rotate(1turn)}}}');var rn={button:"_97b0fc33c028be1a__button","is-unstyled":"abbb272e2ce49bd6__is-unstyled","is-loading":"_914b42f315c0e580__is-loading","is-small":"_908205475f9f2a92__is-small",icon:"_9f6fc6553aeb36fe__icon","is-brand":"dd460c965226cc77__is-brand","is-outline":"_62d5a778b7b258ee__is-outline","is-minimal":"ad0619a3217c6a5b__is-minimal","is-neutral":"e722a8f96726aa99__is-neutral","is-solid":"b50b3358c5fb4d0b__is-solid","is-compact":"cf59cf1b69629838__is-compact","loading-animation":"_5a1d53da6f830c8d__loading-animation"};typeof process>"u",Er("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var Cb={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",Er("08122b3d53","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{.af79fb116edb0dd7__outset-ring--focus:focus,.dfcfdc28396e5d98__outset-ring--focus-visible:focus-visible,.e5cd9ee879f6403a__outset-ring--focus-within:focus-within,:focus-visible ._81935a08e952f267__outset-ring--focus-parent-visible{--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within,.abc777e9713fa711__outset-ring--focus-except-active:focus{outline:none}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within:not(:has(:active)),.abc777e9713fa711__outset-ring--focus-except-active:focus:not(:active){--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}}}");var Ab={"outset-ring--focus":"af79fb116edb0dd7__outset-ring--focus","outset-ring--focus-visible":"dfcfdc28396e5d98__outset-ring--focus-visible","outset-ring--focus-within":"e5cd9ee879f6403a__outset-ring--focus-within","outset-ring--focus-parent-visible":"_81935a08e952f267__outset-ring--focus-parent-visible","outset-ring--focus-except-active":"abc777e9713fa711__outset-ring--focus-except-active","outset-ring--focus-within-except-active":"_3c9f5ee9fc9c136d__outset-ring--focus-within-except-active"};typeof process>"u",Er("e8e31009f5","._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-weak,#707070))}&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}.c59a0ebebd71fa4a__ol{list-style:var(--_gcd-ol-list-style,none);margin:var(--_gcd-ol-margin,0);padding-block:var(--_gcd-ol-padding-block,0);padding-inline:var(--_gcd-ol-padding-inline,0)}._46b5cb0c8e24e8c9__li{margin:var(--_gcd-li-margin,0)}");var Ob={button:"_6defc79820e382c6__button",input:"d2cff2e5dea83bd1__input",textarea:"_547d86373d02e108__textarea",div:"_8c15fd0ed9f28ba4__div",p:"_43cec3e1eec1066d__p",heading:"e97669c6d9a38497__heading",a:"_2c0831b0499dbd6e__a",ol:"c59a0ebebd71fa4a__ol",li:"_46b5cb0c8e24e8c9__li"},vu=(0,Rr.forwardRef)(function({tone:t="brand",variant:o="solid",size:n="default",className:r,focusableWhenDisabled:i=!0,disabled:s,loading:a,loadingAnnouncement:l=(0,bu.__)("Loading"),children:c,...d},m){let u=J(Ob.button,Cb["box-sizing"],Ab["outset-ring--focus-except-active"],o!=="unstyled"&&rn.button,rn[`is-${t}`],rn[`is-${o}`],rn[`is-${n}`],a&&rn["is-loading"],r);return(0,Rr.useEffect)(()=>{a&&l&&kb(l)},[a,l]),(0,wu.jsx)(Ni,{ref:m,className:u,focusableWhenDisabled:i,disabled:s??a,...d,children:c})});var _u=b(ce(),1);var xu=b(W(),1),ys="data-wp-hash";function xs(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Ib(document)),e.__wpStyleRuntime}function Nb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${ys}]`))if(o.getAttribute(ys)===t)return!0;return!1}function yu(e,t,o){if(!e.head)return;let n=xs(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Nb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(ys,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Ib(e){let t=xs();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)yu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Lb(e,t){let o=xs();o.styles.set(e,t);for(let n of o.documents.keys())yu(n,e,t)}typeof process>"u",Lb("effc4e3032",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._97b0fc33c028be1a__button,.abbb272e2ce49bd6__is-unstyled{appearance:none;padding:0}._97b0fc33c028be1a__button{--wp-ui-button-font-weight:var(--wpds-typography-font-weight-emphasis,600);--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-strong,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-strong-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 93%,#000));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand-strong,#fff);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-strong-active,#fff);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-strong-disabled,#8d8d8d);--wp-ui-button-padding-block:var(--wpds-dimension-padding-xs,4px);--wp-ui-button-padding-inline:var(--wpds-dimension-padding-md,12px);--wp-ui-button-height:var(--wpds-dimension-size-lg,40px);--wp-ui-button-aspect-ratio:auto;--wp-ui-button-font-size:var(--wpds-typography-font-size-md,13px);--wp-ui-button-min-width:calc(4ch + var(--wp-ui-button-padding-inline)*2);--wp-ui-button-icon-margin:calc((var(--wpds-dimension-size-2xs, 16px) - var(--wpds-dimension-size-sm, 24px))/2);--wp-ui-button-border-color:var(--wp-ui-button-background-color);--wp-ui-button-border-color-active:var(--wp-ui-button-background-color-active);--wp-ui-button-border-color-disabled:var(--wp-ui-button-background-color-disabled);--_gcd-button-font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);--_gcd-button-font-size:var(--wp-ui-button-font-size);--_gcd-button-font-weight:var(--wp-ui-button-font-weight);align-items:center;aspect-ratio:var(--wp-ui-button-aspect-ratio);background-clip:border-box;background-color:var(--wp-ui-button-background-color);border-color:var(--wp-ui-button-border-color);border-radius:var(--wpds-border-radius-sm,2px);border-style:solid;border-width:1px;color:var(--wp-ui-button-foreground-color);display:inline-flex;font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wp-ui-button-font-size);font-weight:var(--wp-ui-button-font-weight);gap:var(--wpds-dimension-gap-sm,8px);justify-content:center;line-height:var(--wpds-typography-line-height-sm,20px);max-width:100%;min-height:var(--wp-ui-button-height);min-width:var(--wp-ui-button-min-width);overflow-wrap:anywhere;padding-block:var(--wp-ui-button-padding-block);padding-inline:var(--wp-ui-button-padding-inline);position:relative;text-align:center;text-decoration:none;&:not([data-disabled]){cursor:var(--wpds-cursor-control,pointer)}@media not (prefers-reduced-motion){transition:color .1s ease-out;*{transition:opacity .1s ease-out}}&[href]{cursor:pointer}[href]{color:inherit;text-decoration:inherit}&:not([data-disabled]):is(:hover,:active,:focus){background-color:var(--wp-ui-button-background-color-active);border-color:var(--wp-ui-button-border-color-active);color:var(--wp-ui-button-foreground-color-active)}&[data-disabled]:not(._914b42f315c0e580__is-loading){background-color:var(--wp-ui-button-background-color-disabled);border-color:var(--wp-ui-button-border-color-disabled);color:var(--wp-ui-button-foreground-color-disabled);@media (forced-colors:active){border-bottom-color:GrayText;border-left-color:GrayText;border-right-color:GrayText;border-top-color:GrayText;color:GrayText}}&:before{aspect-ratio:1;border:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid;border-block-end-color:transparent;border-block-start-color:var(--wp-ui-button-foreground-color);border-inline-end-color:var(--wp-ui-button-foreground-color);border-inline-start-color:transparent;border-radius:50%;box-sizing:border-box;content:"";display:block;height:var(--wp-ui-button-font-size);left:50%;opacity:0;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);@media not (prefers-reduced-motion){transition:opacity .1s ease-out}@media (forced-colors:active){border-block-end-style:none;border-bottom-color:ButtonText;border-inline-start-style:none;border-left-color:ButtonText;border-right-color:ButtonText;border-top-color:ButtonText}}}._908205475f9f2a92__is-small{--wp-ui-button-padding-block:0px;--wp-ui-button-padding-inline:var(--wpds-dimension-padding-sm,8px);--wp-ui-button-height:var(--wpds-dimension-size-sm,24px)}._9f6fc6553aeb36fe__icon{margin:var(--wp-ui-button-icon-margin)}.dd460c965226cc77__is-brand{&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 85%,#000));--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-brand-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000)}}.e722a8f96726aa99__is-neutral{&.ad0619a3217c6a5b__is-minimal[aria-pressed=true],&.b50b3358c5fb4d0b__is-solid{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-strong,#2d2d2d);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-strong-active,#1e1e1e);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral-strong,#f0f0f0);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-strong-active,#f0f0f0);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-strong-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d);--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-neutral-active,#6e6e6e);--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-neutral-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000)}}.abbb272e2ce49bd6__is-unstyled{background:none;border:none;min-width:unset}.cf59cf1b69629838__is-compact{--wp-ui-button-height:var(--wpds-dimension-size-md,32px)}._914b42f315c0e580__is-loading:not(.abbb272e2ce49bd6__is-unstyled){color:transparent;&:not([data-disabled]):is(:hover,:active,:focus){color:transparent}@media (forced-colors:active){color:ButtonFace}*{opacity:0}&:before{opacity:1;transition-delay:.05s;@media not (prefers-reduced-motion){animation:_5a1d53da6f830c8d__loading-animation 1s linear infinite}}}}@keyframes _5a1d53da6f830c8d__loading-animation{0%{transform:translate(-50%,-50%) rotate(0deg)}to{transform:translate(-50%,-50%) rotate(1turn)}}}');var Mb={button:"_97b0fc33c028be1a__button","is-unstyled":"abbb272e2ce49bd6__is-unstyled","is-loading":"_914b42f315c0e580__is-loading","is-small":"_908205475f9f2a92__is-small",icon:"_9f6fc6553aeb36fe__icon","is-brand":"dd460c965226cc77__is-brand","is-outline":"_62d5a778b7b258ee__is-outline","is-minimal":"ad0619a3217c6a5b__is-minimal","is-neutral":"e722a8f96726aa99__is-neutral","is-solid":"b50b3358c5fb4d0b__is-solid","is-compact":"cf59cf1b69629838__is-compact","loading-animation":"_5a1d53da6f830c8d__loading-animation"},Ss=(0,_u.forwardRef)(function({className:t,icon:o,...n},r){return(0,xu.jsx)(co,{ref:r,icon:o,className:J(Mb.icon,t),size:24,...n})});Ss.displayName="Button.Icon";var kr=Object.assign(vu,{Icon:Ss});var Ru=b(ce(),1);var nt=b(W(),1),Rs="data-wp-hash";function Es(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Hb(document)),e.__wpStyleRuntime}function Bb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Rs}]`))if(o.getAttribute(Rs)===t)return!0;return!1}function Eu(e,t,o){if(!e.head)return;let n=Es(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Bb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Rs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Hb(e){let t=Es();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Eu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function zb(e,t){let o=Es();o.styles.set(e,t);for(let n of o.documents.keys())Eu(n,e,t)}typeof process>"u",zb("c5cdafb1bc","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer compositions{._28cfdc260e755391__icon-button{--wp-ui-button-aspect-ratio:1;--wp-ui-button-padding-inline:0px;--wp-ui-button-min-width:unset}.f1c70d719989a85a__icon{margin:-1px}}}");var Su={"icon-button":"_28cfdc260e755391__icon-button",icon:"f1c70d719989a85a__icon"},ks=(0,Ru.forwardRef)(function({label:t,className:o,children:n,disabled:r,focusableWhenDisabled:i=!0,icon:s,size:a,shortcut:l,positioner:c,"aria-describedby":d,"aria-keyshortcuts":m,...u},f){let p=J(Su["icon-button"],o),{descriptionId:g,targetProps:h}=pu({"aria-describedby":d,"aria-keyshortcuts":m,shortcut:l});return(0,nt.jsxs)(rs,{children:[(0,nt.jsxs)(os,{ref:f,...h,disabled:r&&!i,render:(0,nt.jsx)(kr,{...u,size:a,"aria-label":t,disabled:r,focusableWhenDisabled:i}),className:p,children:[(0,nt.jsx)(co,{icon:s,size:24,className:Su.icon}),l&&g&&(0,nt.jsx)(mu,{descriptionId:g,shortcut:l})]}),(0,nt.jsxs)(ts,{positioner:c,children:[t,l&&(0,nt.jsxs)(nt.Fragment,{children:[" ",(0,nt.jsx)(gu,{shortcut:l})]})]})]})});var ku=b(ce(),1),Ts="data-wp-hash";function Ps(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&jb(document)),e.__wpStyleRuntime}function Db(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Ts}]`))if(o.getAttribute(Ts)===t)return!0;return!1}function Tu(e,t,o){if(!e.head)return;let n=Ps(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Db(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Ts,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function jb(e){let t=Ps();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Tu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Fb(e,t){let o=Ps();o.styles.set(e,t);for(let n of o.documents.keys())Tu(n,e,t)}typeof process>"u",Fb("32aba35fe1","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._19ce0419607e1896__stack{display:flex}}}");var Vb={stack:"_19ce0419607e1896__stack"},Wb={xs:"var(--wpds-dimension-gap-xs, 4px)",sm:"var(--wpds-dimension-gap-sm, 8px)",md:"var(--wpds-dimension-gap-md, 12px)",lg:"var(--wpds-dimension-gap-lg, 16px)",xl:"var(--wpds-dimension-gap-xl, 24px)","2xl":"var(--wpds-dimension-gap-2xl, 32px)","3xl":"var(--wpds-dimension-gap-3xl, 40px)"},Ut=(0,ku.forwardRef)(function({direction:t,gap:o,align:n,justify:r,wrap:i,render:s,...a},l){let c={gap:o&&Wb[o],alignItems:n,justifyContent:r,flexDirection:t,flexWrap:i};return ot({render:s,ref:l,props:ve(a,{style:c,className:Vb.stack})})});var sn={};Mt(sn,{ActionButton:()=>Qu,ActionLink:()=>ef,Actions:()=>Fu,CloseIcon:()=>Gu,Description:()=>zu,Root:()=>Au,Title:()=>Lu});var No=b(ce(),1);import{speak as Yb}from"@wordpress/a11y";var Io=b(W(),1),As="data-wp-hash";function Os(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Gb(document)),e.__wpStyleRuntime}function Ub(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${As}]`))if(o.getAttribute(As)===t)return!0;return!1}function Pu(e,t,o){if(!e.head)return;let n=Os(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Ub(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(As,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Gb(e){let t=Os();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Pu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Cu(e,t){let o=Os();o.styles.set(e,t);for(let n of o.documents.keys())Pu(n,e,t)}typeof process>"u",Cu("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var Kb={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",Cu("42aad93a67","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#aac6e5);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1be80);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#936400)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#92d19d);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#007f2f)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dfafa8);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var Cs={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},Xb={neutral:null,info:ms,warning:cs,success:gs,error:fs};function qb(e){return e==="error"?"assertive":"polite"}function Zb(e){if(e){if(typeof e=="string")return e;try{return(0,No.renderToString)(e)}catch{return}}}function Qb(e,t){let o=Zb(e);(0,No.useEffect)(()=>{o&&Yb(o,t)},[o,t])}var Au=(0,No.forwardRef)(function({intent:t="neutral",children:o,icon:n,spokenMessage:r=o,politeness:i=qb(t),render:s,...a},l){Qb(r,i);let c=n===null?null:n??Xb[t],d=J(Cs.notice,Cs[`is-${t}`],Kb["box-sizing"]);return ot({defaultTagName:"div",render:s,ref:l,props:ve({className:d,children:(0,Io.jsxs)(Io.Fragment,{children:[o,c&&(0,Io.jsx)(co,{className:Cs.icon,icon:c})]})},a)})});var Ou=b(ce(),1);var Iu=b(W(),1),Ns="data-wp-hash";function Is(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&$b(document)),e.__wpStyleRuntime}function Jb(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Ns}]`))if(o.getAttribute(Ns)===t)return!0;return!1}function Nu(e,t,o){if(!e.head)return;let n=Is(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Jb(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Ns,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function $b(e){let t=Is();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Nu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function eh(e,t){let o=Is();o.styles.set(e,t);for(let n of o.documents.keys())Nu(n,e,t)}typeof process>"u",eh("42aad93a67","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#aac6e5);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1be80);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#936400)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#92d19d);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#007f2f)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dfafa8);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var th={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},Lu=(0,Ou.forwardRef)(function({className:t,...o},n){return(0,Iu.jsx)(We,{ref:n,variant:"heading-md",className:J(th.title,t),...o})});var Mu=b(ce(),1);var Hu=b(W(),1),Ls="data-wp-hash";function Ms(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&nh(document)),e.__wpStyleRuntime}function oh(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Ls}]`))if(o.getAttribute(Ls)===t)return!0;return!1}function Bu(e,t,o){if(!e.head)return;let n=Ms(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(oh(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Ls,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function nh(e){let t=Ms();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Bu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function rh(e,t){let o=Ms();o.styles.set(e,t);for(let n of o.documents.keys())Bu(n,e,t)}typeof process>"u",rh("42aad93a67","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#aac6e5);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1be80);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#936400)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#92d19d);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#007f2f)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dfafa8);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var ih={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},zu=(0,Mu.forwardRef)(function({className:t,...o},n){return(0,Hu.jsx)(We,{ref:n,variant:"body-md",className:J(ih.description,t),...o})});var Du=b(ce(),1);var Bs="data-wp-hash";function Hs(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&ah(document)),e.__wpStyleRuntime}function sh(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Bs}]`))if(o.getAttribute(Bs)===t)return!0;return!1}function ju(e,t,o){if(!e.head)return;let n=Hs(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(sh(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Bs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function ah(e){let t=Hs();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)ju(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function ch(e,t){let o=Hs();o.styles.set(e,t);for(let n of o.documents.keys())ju(n,e,t)}typeof process>"u",ch("42aad93a67","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#aac6e5);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1be80);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#936400)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#92d19d);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#007f2f)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dfafa8);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var lh={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},Fu=(0,Du.forwardRef)(function({render:t,...o},n){return ot({defaultTagName:"div",render:t,ref:n,props:ve({className:lh.actions},o)})});var Vu=b(ce(),1),Wu=b(st(),1);var Uu=b(W(),1),zs="data-wp-hash";function Ds(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&uh(document)),e.__wpStyleRuntime}function dh(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${zs}]`))if(o.getAttribute(zs)===t)return!0;return!1}function Yu(e,t,o){if(!e.head)return;let n=Ds(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(dh(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(zs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function uh(e){let t=Ds();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)Yu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function fh(e,t){let o=Ds();o.styles.set(e,t);for(let n of o.documents.keys())Yu(n,e,t)}typeof process>"u",fh("42aad93a67","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#aac6e5);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1be80);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#936400)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#92d19d);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#007f2f)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dfafa8);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var ph={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},Gu=(0,Vu.forwardRef)(function({className:t,icon:o=ds,label:n=(0,Wu.__)("Dismiss"),...r},i){return(0,Uu.jsx)(ks,{...r,ref:i,className:J(ph["close-icon"],t),variant:"minimal",size:"small",tone:"neutral",icon:o,label:n})});var Xu=b(ce(),1);var Zu=b(W(),1),js="data-wp-hash";function Fs(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&gh(document)),e.__wpStyleRuntime}function mh(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${js}]`))if(o.getAttribute(js)===t)return!0;return!1}function qu(e,t,o){if(!e.head)return;let n=Fs(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(mh(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(js,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function gh(e){let t=Fs();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)qu(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function bh(e,t){let o=Fs();o.styles.set(e,t);for(let n of o.documents.keys())qu(n,e,t)}typeof process>"u",bh("42aad93a67","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#aac6e5);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1be80);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#936400)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#92d19d);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#007f2f)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dfafa8);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var Ku={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},Qu=(0,Xu.forwardRef)(function({className:t,loading:o,loadingAnnouncement:n,variant:r,...i},s){return(0,Zu.jsx)(kr,{...i,...o!==void 0?{loading:o,loadingAnnouncement:n??""}:{},ref:s,size:"compact",tone:"neutral",variant:r,className:J(Ku["action-button"],Ku[`is-action-button-${r}`],t)})});var Ju=b(ce(),1);var Ws=b(W(),1),Vs="data-wp-hash";function Ys(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&wh(document)),e.__wpStyleRuntime}function hh(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Vs}]`))if(o.getAttribute(Vs)===t)return!0;return!1}function $u(e,t,o){if(!e.head)return;let n=Ys(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(hh(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Vs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function wh(e){let t=Ys();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)$u(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function vh(e,t){let o=Ys();o.styles.set(e,t);for(let n of o.documents.keys())$u(n,e,t)}typeof process>"u",vh("42aad93a67","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._4145abab73d17514__notice{--icon-height:var(--wpds-dimension-size-sm,24px);--text-vertical-padding:calc((var(--icon-height) - var(--wpds-typography-line-height-sm, 20px))/2);--wp-ui-notice-background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-neutral,#dbdbdb);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-neutral,#1e1e1e);align-items:start;background-color:var(--wp-ui-notice-background-color);border:1px solid var(--wp-ui-notice-border-color);border-radius:var(--wpds-border-radius-lg,8px);container-type:inline-size;display:grid;grid-template-columns:auto 1fr auto;padding:var(--wpds-dimension-padding-md,12px)}.d0a25570cb528528__icon{color:var(--wp-ui-notice-decorative-icon-color);grid-column:1;grid-row:1;margin-inline-end:var(--wpds-dimension-gap-xs,4px)}._1904b570a89bb815__description,.b5397fb9d05389e3__title{color:var(--wp-ui-notice-text-color);grid-column:2;padding-block:var(--text-vertical-padding)}._0a1270dcdd79c031__actions{display:flex;flex-wrap:wrap;gap:var(--wpds-dimension-gap-md,12px);grid-column:2}._4145abab73d17514__notice:has(._1904b570a89bb815__description) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions{margin-block-start:var(--wpds-dimension-gap-sm,8px)}._983740ab855c4e09__action-button{flex-shrink:0}.d329e7416d368d31__action-link{flex-shrink:0;&:not(:first-child){margin-inline-start:var(--wpds-dimension-gap-xs,4px)}&:not(:last-child){margin-inline-end:var(--wpds-dimension-gap-xs,4px)}}._487e6a5c1375f7dc__close-icon{grid-column:3;grid-row:1;margin-inline-start:var(--wpds-dimension-gap-xs,4px)}._531c140826094795__is-info{--wp-ui-notice-background-color:var(--wpds-color-background-surface-info-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-info,#aac6e5);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-info,#001b4f);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-info-weak,#006bd7)}.ae2e1004697cce95__is-warning{--wp-ui-notice-background-color:var(--wpds-color-background-surface-warning-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-warning,#e1be80);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-warning,#2e1900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-warning-weak,#936400)}._2e614a76af494837__is-success{--wp-ui-notice-background-color:var(--wpds-color-background-surface-success-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-success,#92d19d);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-success,#002900);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-success-weak,#007f2f)}.af00331ae17a0065__is-error{--wp-ui-notice-background-color:var(--wpds-color-background-surface-error-weak,#f8f8f8);--wp-ui-notice-border-color:var(--wpds-color-stroke-surface-error,#dfafa8);--wp-ui-notice-text-color:var(--wpds-color-foreground-content-error,#470000);--wp-ui-notice-decorative-icon-color:var(--wpds-color-foreground-content-error-weak,#cc1818)}@container (max-width: 320px){._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._0a1270dcdd79c031__actions,._4145abab73d17514__notice:has(.b5397fb9d05389e3__title) ._1904b570a89bb815__description{grid-column:1/3}}}@layer compositions{.d329e7416d368d31__action-link{margin-block:auto}._487e6a5c1375f7dc__close-icon,._983740ab855c4e09__action-button:is(._8ddb8fb33fbf3d38__is-action-button-outline,._77bbde495a8a0af3__is-action-button-minimal){--wp-ui-button-background-color-active:color-mix(in srgb,transparent 50%,var(--wpds-color-background-interactive-neutral-weak-active,#ededed))}}}");var _h={notice:"_4145abab73d17514__notice",icon:"d0a25570cb528528__icon",title:"b5397fb9d05389e3__title",description:"_1904b570a89bb815__description",actions:"_0a1270dcdd79c031__actions","action-button":"_983740ab855c4e09__action-button","action-link":"d329e7416d368d31__action-link","close-icon":"_487e6a5c1375f7dc__close-icon","is-info":"_531c140826094795__is-info","is-warning":"ae2e1004697cce95__is-warning","is-success":"_2e614a76af494837__is-success","is-error":"af00331ae17a0065__is-error","is-action-button-outline":"_8ddb8fb33fbf3d38__is-action-button-outline","is-action-button-minimal":"_77bbde495a8a0af3__is-action-button-minimal"},ef=(0,Ju.forwardRef)(function({className:t,render:o,...n},r){return(0,Ws.jsx)(We,{ref:r,className:J(_h["action-link"],t),...n,variant:"body-md",render:(0,Ws.jsx)(so,{tone:"neutral",variant:"default",render:o})})});var tf=b(ce(),1),of=b(W(),1),nf=(0,tf.forwardRef)(({children:e,className:t,ariaLabel:o,as:n="div",...r},i)=>(0,of.jsx)(n,{ref:i,className:J("admin-ui-navigable-region",t),"aria-label":o,role:"region",tabIndex:"-1",...r,children:e}));nf.displayName="NavigableRegion";var rf=nf;var sf=b(st(),1);var Gt=b(W(),1),Gs="data-wp-hash";function Ks(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&xh(document)),e.__wpStyleRuntime}function yh(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Gs}]`))if(o.getAttribute(Gs)===t)return!0;return!1}function af(e,t,o){if(!e.head)return;let n=Ks(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(yh(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Gs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function xh(e){let t=Ks();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)af(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Sh(e,t){let o=Ks();o.styles.set(e,t);for(let n of o.documents.keys())af(n,e,t)}typeof process>"u",Sh("72ef022400",".bfb5a2dd8cceebd3__list{--focus-ring-size:calc(var(--wpds-border-width-focus, var(--wp-admin-border-width-focus, 2px))*2);list-style:none;margin:calc(var(--focus-ring-size)*-1);overflow-x:auto;padding:var(--focus-ring-size);scroll-padding:var(--focus-ring-size)}.a4759b4cb2c8bd92__li{flex-shrink:0}._07da506d3f2d9afe__item{align-items:center;color:var(--wpds-color-foreground-interactive-neutral-weak,#707070);display:flex;font-weight:var(--wpds-typography-font-weight-default,400);min-block-size:44px;min-inline-size:44px;text-decoration:none}._07da506d3f2d9afe__item:hover,._07da506d3f2d9afe__item[aria-current=page]{color:var(--wpds-color-foreground-interactive-neutral-weak-active,#1e1e1e)}._07da506d3f2d9afe__item[aria-current=page]{font-weight:var(--wpds-typography-font-weight-emphasis,600)}");var Us={list:"bfb5a2dd8cceebd3__list",li:"a4759b4cb2c8bd92__li",item:"_07da506d3f2d9afe__item"},Rh=({items:e,currentHref:t,ariaLabel:o=(0,sf.__)("Sections"),linkComponent:n,className:r})=>{if(!e.length)return null;let i=n??"a";return(0,Gt.jsx)("nav",{"aria-label":o,className:r,children:(0,Gt.jsx)(Ut,{render:(0,Gt.jsx)("ul",{role:"list"}),direction:"row",align:"center",gap:"md",className:Us.list,children:e.map(s=>(0,Gt.jsx)("li",{className:Us.li,children:(0,Gt.jsx)(We,{variant:"body-md",className:Us.item,render:(0,Gt.jsx)(so,{variant:"unstyled","aria-current":s.href===t?"page":void 0,render:(0,Gt.jsx)(i,{href:s.href})}),children:s.label})},s.href))})})},cf=Rh;var df=b(an(),1),{Fill:uf,Slot:ff}=(0,df.createSlotFill)("SidebarToggle");var Ze=b(W(),1),Xs="data-wp-hash";function qs(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&kh(document)),e.__wpStyleRuntime}function Eh(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Xs}]`))if(o.getAttribute(Xs)===t)return!0;return!1}function pf(e,t,o){if(!e.head)return;let n=qs(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Eh(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Xs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function kh(e){let t=qs();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)pf(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Th(e,t){let o=qs();o.styles.set(e,t);for(let n of o.documents.keys())pf(n,e,t)}typeof process>"u",Th("1f3750277d","._956b6df0898efed0__page{text-wrap:pretty;background-color:var(--wpds-color-background-surface-neutral,#fcfcfc);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);display:flex;flex-flow:column;height:100%;position:relative;z-index:1}._0625b55e82a0d93d__header{background:var(--wpds-color-background-surface-neutral-strong,#fff);border-block-end:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral-weak,#f0f0f0);inset-block-start:0;padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px);position:sticky;z-index:1}.a43c44d5ae28b2e8__header-content{min-height:var(--wpds-dimension-size-md,32px)}.b7cb5b9daf3a3b25__header-actions{flex-shrink:0}._8bcd33103b451f30__header-lockup{min-width:0}._8113be94e7caf73c__header-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._9a776c7f70996f61__header-visual{display:grid;flex-shrink:0;grid-template-columns:1fr;grid-template-rows:1fr;height:var(--wpds-dimension-size-sm,24px);width:var(--wpds-dimension-size-sm,24px);>*{grid-column:1/-1;grid-row:1/-1;max-height:100%;max-width:100%}}.d5e0920cd15d35bc__sidebar-toggle-slot:empty{display:none}._60fea2f6bf5319cd__header-subtitle{color:var(--wpds-color-foreground-content-neutral-weak,#707070);padding-block-end:var(--wpds-dimension-padding-xs,4px)}._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation,._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation ._60fea2f6bf5319cd__header-subtitle{padding-block-end:0}._673c99dcbfb58211__header-navigation{margin-block-start:var(--wpds-dimension-gap-md,12px)}.be5e57d029ec4036__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;&._128806d0b26e3a50__has-padding{padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px)}}");var St={page:"_956b6df0898efed0__page",header:"_0625b55e82a0d93d__header","header-content":"a43c44d5ae28b2e8__header-content","header-actions":"b7cb5b9daf3a3b25__header-actions","header-lockup":"_8bcd33103b451f30__header-lockup","header-title":"_8113be94e7caf73c__header-title","header-visual":"_9a776c7f70996f61__header-visual","sidebar-toggle-slot":"d5e0920cd15d35bc__sidebar-toggle-slot","header-subtitle":"_60fea2f6bf5319cd__header-subtitle","has-navigation":"_4b0f17e503d11619__has-navigation","header-navigation":"_673c99dcbfb58211__header-navigation",content:"be5e57d029ec4036__content","has-padding":"_128806d0b26e3a50__has-padding"};function mf({headingLevel:e=1,breadcrumbs:t,badges:o,visual:n,title:r,subTitle:i,actions:s,navigation:a,components:l,showSidebarToggle:c=!0}){let d=`h${e}`,m=!!a?.items?.length;return(0,Ze.jsxs)(Ut,{direction:"column",className:J(St.header,m&&St["has-navigation"]),children:[(0,Ze.jsxs)(Ut,{className:St["header-content"],direction:"row",gap:"sm",justify:"space-between",children:[(0,Ze.jsxs)(Ut,{direction:"row",gap:"sm",align:"center",justify:"start",className:St["header-lockup"],children:[c&&(0,Ze.jsx)(ff,{bubblesVirtually:!0,className:St["sidebar-toggle-slot"]}),n&&(0,Ze.jsx)("div",{className:St["header-visual"],"aria-hidden":"true",children:n}),r&&(0,Ze.jsx)(We,{className:St["header-title"],render:(0,Ze.jsx)(d,{}),variant:"heading-lg",children:r}),t,o]}),s&&(0,Ze.jsx)(Ut,{align:"center",className:St["header-actions"],direction:"row",gap:"sm",children:s})]}),i&&(0,Ze.jsx)(We,{render:(0,Ze.jsx)("p",{}),variant:"body-md",className:St["header-subtitle"],children:i}),m&&(0,Ze.jsx)(cf,{...a,linkComponent:l?.link,className:St["header-navigation"]})]})}var cn=b(W(),1),Qs="data-wp-hash";function Js(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Ch(document)),e.__wpStyleRuntime}function Ph(e,t){if(!e.head)return!1;for(let o of e.head.querySelectorAll(`style[${Qs}]`))if(o.getAttribute(Qs)===t)return!0;return!1}function gf(e,t,o){if(!e.head)return;let n=Js(),r=n.injectedStyles.get(e);if(r||(r=new Set,n.injectedStyles.set(e,r)),r.has(t))return;if(Ph(e,t)){r.add(t);return}let i=e.createElement("style");i.setAttribute(Qs,t),i.appendChild(e.createTextNode(o)),e.head.appendChild(i),r.add(t)}function Ch(e){let t=Js();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[o,n]of t.styles)gf(e,o,n);return()=>{let o=t.documents.get(e);if(o!==void 0){if(o<=1){t.documents.delete(e);return}t.documents.set(e,o-1)}}}function Ah(e,t){let o=Js();o.styles.set(e,t);for(let n of o.documents.keys())gf(n,e,t)}typeof process>"u",Ah("1f3750277d","._956b6df0898efed0__page{text-wrap:pretty;background-color:var(--wpds-color-background-surface-neutral,#fcfcfc);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);display:flex;flex-flow:column;height:100%;position:relative;z-index:1}._0625b55e82a0d93d__header{background:var(--wpds-color-background-surface-neutral-strong,#fff);border-block-end:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral-weak,#f0f0f0);inset-block-start:0;padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px);position:sticky;z-index:1}.a43c44d5ae28b2e8__header-content{min-height:var(--wpds-dimension-size-md,32px)}.b7cb5b9daf3a3b25__header-actions{flex-shrink:0}._8bcd33103b451f30__header-lockup{min-width:0}._8113be94e7caf73c__header-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._9a776c7f70996f61__header-visual{display:grid;flex-shrink:0;grid-template-columns:1fr;grid-template-rows:1fr;height:var(--wpds-dimension-size-sm,24px);width:var(--wpds-dimension-size-sm,24px);>*{grid-column:1/-1;grid-row:1/-1;max-height:100%;max-width:100%}}.d5e0920cd15d35bc__sidebar-toggle-slot:empty{display:none}._60fea2f6bf5319cd__header-subtitle{color:var(--wpds-color-foreground-content-neutral-weak,#707070);padding-block-end:var(--wpds-dimension-padding-xs,4px)}._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation,._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation ._60fea2f6bf5319cd__header-subtitle{padding-block-end:0}._673c99dcbfb58211__header-navigation{margin-block-start:var(--wpds-dimension-gap-md,12px)}.be5e57d029ec4036__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;&._128806d0b26e3a50__has-padding{padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px)}}");var Zs={page:"_956b6df0898efed0__page",header:"_0625b55e82a0d93d__header","header-content":"a43c44d5ae28b2e8__header-content","header-actions":"b7cb5b9daf3a3b25__header-actions","header-lockup":"_8bcd33103b451f30__header-lockup","header-title":"_8113be94e7caf73c__header-title","header-visual":"_9a776c7f70996f61__header-visual","sidebar-toggle-slot":"d5e0920cd15d35bc__sidebar-toggle-slot","header-subtitle":"_60fea2f6bf5319cd__header-subtitle","has-navigation":"_4b0f17e503d11619__has-navigation","header-navigation":"_673c99dcbfb58211__header-navigation",content:"be5e57d029ec4036__content","has-padding":"_128806d0b26e3a50__has-padding"};function bf({headingLevel:e,breadcrumbs:t,badges:o,visual:n,title:r,subTitle:i,children:s,className:a,actions:l,navigation:c,components:d,ariaLabel:m,hasPadding:u=!1,showSidebarToggle:f=!0}){let p=J(Zs.page,a);return(0,cn.jsxs)(rf,{className:p,ariaLabel:m??(typeof r=="string"?r:""),children:[(r||t||o||l||n||!!c?.items?.length)&&(0,cn.jsx)(mf,{headingLevel:e,breadcrumbs:t,badges:o,visual:n,title:r,subTitle:i,actions:l,navigation:c,components:d,showSidebarToggle:f}),u?(0,cn.jsx)("div",{className:J(Zs.content,Zs["has-padding"]),children:s}):s]})}bf.SidebarToggleFill=uf;var $s=bf;var ut=b(an()),Ff=b(ln()),Vf=b(ce()),At=b(st()),Wf=b(Tr());import{privateApis as Kh}from"@wordpress/connectors";var vf=b(Ji()),{lock:a8,unlock:Lo}=(0,vf.__dangerousOptInToUnstableAPIsOnlyForCoreModules)("I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.","@wordpress/routes");if(typeof document<"u"&&!document.head.querySelector("style[data-wp-hash='3ac7d2cc0e']")){let e=document.createElement("style");e.setAttribute("data-wp-hash","3ac7d2cc0e"),e.appendChild(document.createTextNode(".connectors-page{box-sizing:border-box;margin:0 auto;max-width:680px;padding:24px;width:100%}.connectors-page .components-item{background:#fff;border:1px solid #ddd;border-radius:8px;overflow:hidden;padding:20px;scroll-margin-top:120px}.connectors-page .connector-settings__error{color:#cc1818}.connectors-page .connector-settings .components-text-control__input{font-family:monospace;scroll-margin-top:120px}.connectors-page__file-mods-notice{margin-bottom:16px}.connectors-page--empty{align-items:center;display:flex;flex-direction:column;flex-grow:1;gap:32px;justify-content:center;text-align:center}.connectors-page .ai-plugin-callout{background-color:#e7d4e4;background-image:radial-gradient(ellipse 70% 120% at 18% 115%,rgba(202,158,198,.75) 0,rgba(202,158,198,0) 60%),radial-gradient(ellipse 55% 110% at 92% -15%,rgba(208,175,217,.7) 0,rgba(208,175,217,0) 65%),radial-gradient(ellipse 40% 85% at 58% -10%,rgba(170,130,184,.45) 0,rgba(170,130,184,0) 70%);border-radius:8px;overflow:hidden;padding:24px;padding-inline-end:150px;position:relative}[dir=rtl] .connectors-page .ai-plugin-callout{background-image:radial-gradient(ellipse 70% 120% at 82% 115%,rgba(202,158,198,.75) 0,rgba(202,158,198,0) 60%),radial-gradient(ellipse 55% 110% at 8% -15%,rgba(208,175,217,.7) 0,rgba(208,175,217,0) 65%),radial-gradient(ellipse 40% 85% at 42% -10%,rgba(170,130,184,.45) 0,rgba(170,130,184,0) 70%)}.connectors-page .ai-plugin-callout__content{align-items:flex-start;display:flex;flex-direction:column;gap:12px;padding-top:2px}.connectors-page .ai-plugin-callout__content p{font-size:13px;line-height:20px;margin:0}.connectors-page .ai-plugin-callout__decoration{height:110px;inset-inline-end:16px;position:absolute;top:12px;width:110px}.connectors-page__help-text{color:#757575}@media (max-width:680px){.connectors-page .ai-plugin-callout{padding:12px;padding-inline-end:100px}.connectors-page .ai-plugin-callout__decoration{height:75px;inset-inline-end:8px;top:8px;width:75px}}@media (max-width:480px){.connectors-page{padding:8px}.connectors-page .ai-plugin-callout{padding-inline-end:130px}.connectors-page .components-item{padding:12px}.connectors-page .components-item>.components-v-stack>.components-h-stack:first-child svg{height:32px;width:32px}.connectors-page .components-item>.components-v-stack>.components-h-stack:first-child>.components-h-stack:last-child{align-items:flex-end;flex-direction:column}}")),document.head.appendChild(e)}var fn=b(an()),sa=b(Tr()),pn=b(ln()),Et=b(ce()),Qe=b(st()),Hf=b(ea()),zf=b(xf());var Pr=b(an()),na=b(ce()),Af=b(ln()),lo=b(st());import{__experimentalRegisterConnector as Oh,__experimentalConnectorItem as Cf,__experimentalDefaultConnectorSettings as Nh,__experimentalApplicationPasswordConnectorSettings as Ih,privateApis as Lh}from"@wordpress/connectors";var ta=b(Tr()),un=b(ln()),dn=b(ce()),pe=b(st()),Sf=b(ea());function oa({file:e,settingName:t,connectorName:o,isInstalled:n,isActivated:r,keySource:i="none",initialIsConnected:s=!1}){let[a,l]=(0,dn.useState)(!1),[c,d]=(0,dn.useState)(!1),[m,u]=(0,dn.useState)(s),[f,p]=(0,dn.useState)(null),g=e?.replace(/\.php$/,""),h=g?.includes("/")?g.split("/")[0]:g,{derivedPluginStatus:y,canManagePlugins:_,currentApiKey:v,currentUsername:w,hasStoredCredentials:R,hasResolvedSettings:x,canInstallPlugins:S}=(0,un.useSelect)(Q=>{let q=Q(ta.store),ne=q.getEntityRecord("root","site")?.[t],se=typeof ne=="string"?ne:"",ze=typeof ne=="object"&&ne!==null?ne:void 0,ae=ze!==void 0?!!ze.username&&!!ze.password:!!se,ge=q.hasFinishedResolution("getEntityRecord",["root","site"]),be=!!q.canUser("create",{kind:"root",name:"plugin"}),Ee={currentApiKey:se,currentUsername:ze?.username??"",hasStoredCredentials:ae,hasResolvedSettings:ge,canInstallPlugins:be};if(!e)return{...Ee,derivedPluginStatus:ge?"active":"checking",canManagePlugins:void 0};let ye=q.getEntityRecord("root","plugin",g);if(!q.hasFinishedResolution("getEntityRecord",["root","plugin",g]))return{...Ee,derivedPluginStatus:"checking",canManagePlugins:void 0};if(ye){let ft=ye.status==="active"||ye.status==="network-active";return{...Ee,derivedPluginStatus:ft?"active":"inactive",canManagePlugins:!0}}let rt="not-installed";return r?rt="active":n&&(rt="inactive"),{...Ee,derivedPluginStatus:rt,canManagePlugins:!1}},[e,g,t,n,r]),E=f??y,k=_,P=E==="active"&&m||f==="active"&&R,{saveEntityRecord:N,invalidateResolution:H}=(0,un.useDispatch)(ta.store),{createSuccessNotice:j,createErrorNotice:L}=(0,un.useDispatch)(Sf.store),T=Q=>N("root","site",{[t]:Q},{throwOnError:!0}),I=()=>{j((0,pe.sprintf)((0,pe.__)("%s connected successfully."),o),{id:"connector-connect-success",type:"snackbar"})},C=()=>{j((0,pe.sprintf)((0,pe.__)("%s disconnected."),o),{id:"connector-disconnect-success",type:"snackbar"})},A=()=>{L((0,pe.sprintf)((0,pe.__)("Failed to disconnect %s."),o),{id:"connector-disconnect-error",type:"snackbar"})},M=async()=>{if(h){d(!0);try{await N("root","plugin",{slug:h,status:"active"},{throwOnError:!0}),p("active"),H("getEntityRecord",["root","site"]),l(!0),j((0,pe.sprintf)((0,pe.__)("Plugin for %s installed and activated successfully."),o),{id:"connector-plugin-install-success",type:"snackbar"})}catch{L((0,pe.sprintf)((0,pe.__)("Failed to install plugin for %s."),o),{id:"connector-plugin-install-error",type:"snackbar"})}finally{d(!1)}}},X=async()=>{if(e){d(!0);try{await N("root","plugin",{plugin:g,status:"active"},{throwOnError:!0}),p("active"),H("getEntityRecord",["root","site"]),l(!0),j((0,pe.sprintf)((0,pe.__)("Plugin for %s activated successfully."),o),{id:"connector-plugin-activate-success",type:"snackbar"})}catch{L((0,pe.sprintf)((0,pe.__)("Failed to activate plugin for %s."),o),{id:"connector-plugin-activate-error",type:"snackbar"})}finally{d(!1)}}};return{pluginStatus:E,canInstallPlugins:S,canActivatePlugins:k,isExpanded:a,setIsExpanded:l,isBusy:c,isConnected:P,currentApiKey:v,currentUsername:w,hasResolvedSettings:x,keySource:i,handleButtonClick:()=>{if(E==="not-installed"){if(S===!1)return;M()}else if(E==="inactive"){if(k===!1)return;X()}else l(!a)},getButtonLabel:()=>{if(c)return E==="not-installed"?(0,pe.__)("Installing\u2026"):(0,pe.__)("Activating\u2026");if(a)return(0,pe.__)("Cancel");if(P)return(0,pe.__)("Edit");switch(E){case"checking":return(0,pe.__)("Checking\u2026");case"not-installed":return(0,pe.__)("Install");case"inactive":return(0,pe.__)("Activate");case"active":return(0,pe.__)("Set up")}},saveApiKey:async Q=>{let q=v;try{let se=(await T(Q))?.[t];if(Q&&(se===q||!se))throw new Error("It was not possible to connect to the provider using this key.");u(!0),I()}catch($){throw console.error("Failed to save API key:",$),$}},removeApiKey:async()=>{try{await T(""),u(!1),C()}catch(Q){console.error("Failed to remove API key:",Q),A()}},saveCredentials:async({username:Q,applicationPassword:q})=>{try{let se=(await T({username:Q,password:q}))?.[t];if(!se?.username||!se?.password)throw new Error((0,pe.__)("It was not possible to save these credentials."));u(!0),I()}catch($){throw console.error("Failed to save credentials:",$),$}},removeCredentials:async()=>{try{await T({username:"",password:""}),u(!1),C()}catch(Q){console.error("Failed to remove credentials:",Q),A()}}}}var ue=b(W()),Rf=()=>(0,ue.jsx)("svg",{width:"40",height:"40",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:(0,ue.jsx)("path",{d:"M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364l2.0201-1.1685a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.4043-.6813zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z",fill:"currentColor"})}),Ef=()=>(0,ue.jsx)("svg",{width:"40",height:"40",viewBox:"0 0 32 32",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:(0,ue.jsx)("path",{d:"M6.2 21.024L12.416 17.536L12.52 17.232L12.416 17.064H12.112L11.072 17L7.52 16.904L4.44 16.776L1.456 16.616L0.704 16.456L0 15.528L0.072 15.064L0.704 14.64L1.608 14.72L3.608 14.856L6.608 15.064L8.784 15.192L12.008 15.528H12.52L12.592 15.32L12.416 15.192L12.28 15.064L9.176 12.96L5.816 10.736L4.056 9.456L3.104 8.808L2.624 8.2L2.416 6.872L3.28 5.92L4.44 6L4.736 6.08L5.912 6.984L8.424 8.928L11.704 11.344L12.184 11.744L12.376 11.608L12.4 11.512L12.184 11.152L10.4 7.928L8.496 4.648L7.648 3.288L7.424 2.472C7.344 2.136 7.288 1.856 7.288 1.512L8.272 0.176L8.816 0L10.128 0.176L10.68 0.656L11.496 2.52L12.816 5.456L14.864 9.448L15.464 10.632L15.784 11.728L15.904 12.064H16.112V11.872L16.28 9.624L16.592 6.864L16.896 3.312L17 2.312L17.496 1.112L18.48 0.464L19.248 0.832L19.88 1.736L19.792 2.32L19.416 4.76L18.68 8.584L18.2 11.144H18.48L18.8 10.824L20.096 9.104L22.272 6.384L23.232 5.304L24.352 4.112L25.072 3.544H26.432L27.432 5.032L26.984 6.568L25.584 8.344L24.424 9.848L22.76 12.088L21.72 13.88L21.816 14.024L22.064 14L25.824 13.2L27.856 12.832L30.28 12.416L31.376 12.928L31.496 13.448L31.064 14.512L28.472 15.152L25.432 15.76L20.904 16.832L20.848 16.872L20.912 16.952L22.952 17.144L23.824 17.192H25.96L29.936 17.488L30.976 18.176L31.6 19.016L31.496 19.656L29.896 20.472L27.736 19.96L22.696 18.76L20.968 18.328H20.728V18.472L22.168 19.88L24.808 22.264L28.112 25.336L28.28 26.096L27.856 26.696L27.408 26.632L24.504 24.448L23.384 23.464L20.848 21.328H20.68V21.552L21.264 22.408L24.352 27.048L24.512 28.472L24.288 28.936L23.488 29.216L22.608 29.056L20.8 26.52L18.936 23.664L17.432 21.104L17.248 21.208L16.36 30.768L15.944 31.256L14.984 31.624L14.184 31.016L13.76 30.032L14.184 28.088L14.696 25.552L15.112 23.536L15.488 21.032L15.712 20.2L15.696 20.144L15.512 20.168L13.624 22.76L10.752 26.64L8.48 29.072L7.936 29.288L6.992 28.8L7.08 27.928L7.608 27.152L10.752 23.152L12.648 20.672L13.872 19.24L13.864 19.032H13.792L5.44 24.456L3.952 24.648L3.312 24.048L3.392 23.064L3.696 22.744L6.208 21.016L6.2 21.024Z",fill:"#D97757"})}),kf=()=>(0,ue.jsxs)("svg",{width:"40",height:"40",viewBox:"0 0 32 32",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[(0,ue.jsx)("path",{d:"M0 4C0 1.79086 1.79086 0 4 0H28C30.2091 0 32 1.79086 32 4V28C32 30.2091 30.2091 32 28 32H4C1.79086 32 0 30.2091 0 28V4Z",fill:"#F0F0F0"}),(0,ue.jsx)("path",{d:"M14.5 8V12H17.5V8H19V12H20.5C20.7652 12 21.0196 12.1054 21.2071 12.2929C21.3946 12.4804 21.5 12.7348 21.5 13V17L18.5 21V23C18.5 23.2652 18.3946 23.5196 18.2071 23.7071C18.0196 23.8946 17.7652 24 17.5 24H14.5C14.2348 24 13.9804 23.8946 13.7929 23.7071C13.6054 23.5196 13.5 23.2652 13.5 23V21L10.5 17V13C10.5 12.7348 10.6054 12.4804 10.7929 12.2929C10.9804 12.1054 11.2348 12 11.5 12H13V8H14.5ZM15 20.5V22.5H17V20.5L20 16.5V13.5H12V16.5L15 20.5Z",fill:"#949494"})]}),Tf=()=>(0,ue.jsxs)("svg",{width:"40",height:"40",viewBox:"0 0 44 44",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[(0,ue.jsx)("rect",{width:"44",height:"44",fill:"#357B49",rx:"6"}),(0,ue.jsx)("path",{fill:"#fff",fillRule:"evenodd",d:"m29.746 28.31-6.392-16.797c-.152-.397-.305-.672-.789-.675-.673 0-1.408.611-1.746 1.316l-7.378 16.154c-.072.16-.143.311-.214.454-.5.995-1.045 1.546-2.357 1.626a.399.399 0 0 0-.16.033l-.01.004a.399.399 0 0 0-.23.392v.01c0 .054.01.106.03.155l.004.01a.416.416 0 0 0 .394.252h6.212a.417.417 0 0 0 .307-.12.416.416 0 0 0 .124-.305.398.398 0 0 0-.105-.302.399.399 0 0 0-.294-.127c-.757 0-2.197-.062-2.197-1.164.02-.318.103-.63.245-.916l1.399-3.152c.52-1.163 1.654-1.163 2.572-1.163h5.843c.023 0 .044 0 .062.003.13.014.16.081.214.242l1.534 4.07a2.857 2.857 0 0 1 .216 1.04c0 .054-.003.104-.01.153-.09.726-.831.887-1.49.887a.4.4 0 0 0-.294.127l-.007.008-.007.008a.401.401 0 0 0-.092.286v.01c0 .054.01.106.03.155l.005.01a.42.42 0 0 0 .395.252h7.011a.413.413 0 0 0 .279-.13.412.412 0 0 0 .11-.297.387.387 0 0 0-.09-.294.388.388 0 0 0-.277-.135c-1.448-.122-2.295-.643-2.847-2.08Zm-11.985-5.844 2.847-6.304c.361-.728.659-1.486.889-2.265 0-.06.03-.092.06-.092s.061.032.061.091c.02.122.045.247.073.374.197.888.584 1.878.914 2.723l.176.453 1.684 4.529a.927.927 0 0 1 .092.4.473.473 0 0 1-.009.094c-.041.202-.228.272-.602.272h-6.063c-.122 0-.184-.03-.184-.092a.36.36 0 0 1 .062-.183Zm17.107-.721c0 .786-.446 1.231-1.25 1.231-.806 0-1.125-.409-1.125-1.034 0-.786.465-1.231 1.25-1.231.785 0 1.125.427 1.125 1.034ZM9.629 23.002c.803 0 1.25-.447 1.25-1.231 0-.607-.343-1.036-1.128-1.036-.785 0-1.25.447-1.25 1.231 0 .625.325 1.036 1.128 1.036Z",clipRule:"evenodd"})]}),Pf=()=>(0,ue.jsxs)("svg",{width:"40",height:"40",style:{flex:"none",lineHeight:1},viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[(0,ue.jsx)("path",{d:"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z",fill:"#3186FF"}),(0,ue.jsx)("path",{d:"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z",fill:"url(#lobe-icons-gemini-fill-0)"}),(0,ue.jsx)("path",{d:"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z",fill:"url(#lobe-icons-gemini-fill-1)"}),(0,ue.jsx)("path",{d:"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z",fill:"url(#lobe-icons-gemini-fill-2)"}),(0,ue.jsxs)("defs",{children:[(0,ue.jsxs)("linearGradient",{gradientUnits:"userSpaceOnUse",id:"lobe-icons-gemini-fill-0",x1:"7",x2:"11",y1:"15.5",y2:"12",children:[(0,ue.jsx)("stop",{stopColor:"#08B962"}),(0,ue.jsx)("stop",{offset:"1",stopColor:"#08B962",stopOpacity:"0"})]}),(0,ue.jsxs)("linearGradient",{gradientUnits:"userSpaceOnUse",id:"lobe-icons-gemini-fill-1",x1:"8",x2:"11.5",y1:"5.5",y2:"11",children:[(0,ue.jsx)("stop",{stopColor:"#F94543"}),(0,ue.jsx)("stop",{offset:"1",stopColor:"#F94543",stopOpacity:"0"})]}),(0,ue.jsxs)("linearGradient",{gradientUnits:"userSpaceOnUse",id:"lobe-icons-gemini-fill-2",x1:"3.5",x2:"17.5",y1:"13.5",y2:"12",children:[(0,ue.jsx)("stop",{stopColor:"#FABC12"}),(0,ue.jsx)("stop",{offset:".46",stopColor:"#FABC12",stopOpacity:"0"})]})]})]});var _e=b(W()),{store:Mh}=Lo(Lh);function Of(){try{return JSON.parse(document.getElementById("wp-script-module-data-options-connectors-wp-admin")?.textContent??"{}")}catch{return{}}}function ra(){return Of().connectors??{}}function Nf(){return!!Of().isFileModDisabled}var Bh={google:Pf,openai:Rf,anthropic:Ef,akismet:Tf};function Hh(e,t){if(t)return(0,_e.jsx)("img",{src:t,alt:"",width:40,height:40});let o=Bh[e];return o?(0,_e.jsx)(o,{}):(0,_e.jsx)(kf,{})}var zh=()=>(0,_e.jsx)("span",{style:{color:"#345b37",backgroundColor:"#eff8f0",padding:"4px 12px",borderRadius:"2px",fontSize:"13px",fontWeight:"var(--wpds-typography-font-weight-emphasis)",whiteSpace:"nowrap"},children:(0,lo.__)("Connected")}),Dh=({slug:e})=>(0,_e.jsx)(so,{href:(0,lo.sprintf)((0,lo.__)("https://wordpress.org/plugins/%s/"),e),openInNewTab:!0,children:(0,lo.__)("Learn more")}),jh=()=>(0,_e.jsx)(Ui,{children:(0,lo.__)("Not available")});function If({isConnected:e,showUnavailableBadge:t,pluginSlug:o,isExpanded:n,isBusy:r,pluginStatus:i,actionButtonRef:s,handleButtonClick:a,getButtonLabel:l}){return(0,_e.jsxs)(Pr.__experimentalHStack,{spacing:3,expanded:!1,children:[e&&(0,_e.jsx)(zh,{}),t&&(o?(0,_e.jsx)(Dh,{slug:o}):(0,_e.jsx)(jh,{})),!t&&(0,_e.jsx)(Pr.Button,{ref:s,variant:n||e?"tertiary":"secondary",size:"compact",onClick:a,disabled:i==="checking"||r,isBusy:r,accessibleWhenDisabled:!0,children:l()})]})}function Lf(e){let t=e?.replace(/\.php$/,"");return t?.includes("/")?t.split("/")[0]:t}function Fh({name:e,description:t,logo:o,authentication:n,plugin:r}){let i=n?.method==="api_key"?n:void 0,s=i?.settingName??"",a=i?.credentialsUrl??void 0,l=Lf(r?.file),{pluginStatus:c,canInstallPlugins:d,canActivatePlugins:m,isExpanded:u,setIsExpanded:f,isBusy:p,isConnected:g,currentApiKey:h,hasResolvedSettings:y,keySource:_,handleButtonClick:v,getButtonLabel:w,saveApiKey:R,removeApiKey:x}=oa({file:r?.file,settingName:s,connectorName:e,isInstalled:r?.isInstalled,isActivated:r?.isActivated,keySource:i?.keySource,initialIsConnected:i?.isConnected}),S=_==="env"||_==="constant",E=c==="not-installed"&&d===!1||c==="inactive"&&m===!1,k=(0,na.useRef)(null);return(0,_e.jsx)(Cf,{className:l?`connector-item--${l}`:void 0,logo:o,name:e,description:t,actionArea:(0,_e.jsx)(If,{isConnected:g,showUnavailableBadge:E,pluginSlug:l,isExpanded:u,isBusy:p,pluginStatus:c,actionButtonRef:k,handleButtonClick:v,getButtonLabel:w}),children:u&&c==="active"&&y&&(0,_e.jsx)(Nh,{initialValue:S?"\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022":h,helpUrl:a,readOnly:g||S,keySource:_,onRemove:S?void 0:async()=>{await x(),k.current?.focus()},onSave:async P=>{await R(P),f(!1),k.current?.focus()}},g?"connected":"setup")})}function Vh({name:e,description:t,logo:o,authentication:n,plugin:r}){let i=n?.method==="application_password"?n:void 0,s=i?.settingName??"",a=i?.credentialsUrl??void 0,l=Lf(r?.file),{pluginStatus:c,canInstallPlugins:d,canActivatePlugins:m,isExpanded:u,setIsExpanded:f,isBusy:p,isConnected:g,currentUsername:h,hasResolvedSettings:y,keySource:_,handleButtonClick:v,getButtonLabel:w,saveCredentials:R,removeCredentials:x}=oa({file:r?.file,settingName:s,connectorName:e,isInstalled:r?.isInstalled,isActivated:r?.isActivated,keySource:i?.keySource,initialIsConnected:i?.isConnected}),S=_==="env"||_==="constant",E=(0,na.useRef)(null),k=c==="not-installed"&&d===!1||c==="inactive"&&m===!1;return(0,_e.jsx)(Cf,{className:l?`connector-item--${l}`:void 0,logo:o,name:e,description:t,actionArea:(0,_e.jsx)(If,{isConnected:g,showUnavailableBadge:k,pluginSlug:l,isExpanded:u,isBusy:p,pluginStatus:c,actionButtonRef:E,handleButtonClick:v,getButtonLabel:w}),children:u&&c==="active"&&y&&(0,_e.jsx)(Ih,{initialUsername:S?"\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022":h,helpUrl:a,readOnly:g||S,keySource:_,onRemove:S?void 0:async()=>{await x(),E.current?.focus()},onSave:async P=>{await R(P),f(!1),E.current?.focus()}},g?"connected":"setup")})}function Mf(){let e=ra(),t=o=>o.replace(/[^a-z0-9-_]/gi,"-");for(let[o,n]of Object.entries(e)){if(o==="akismet"&&!n.plugin?.isInstalled)continue;let{authentication:r}=n,i=t(o),s={name:n.name,description:n.description,type:n.type,logo:Hh(o,n.logoUrl),authentication:r,plugin:n.plugin},a=Lo((0,Af.select)(Mh)).getConnector(i);r.method==="api_key"&&!a?.render?s.render=Fh:r.method==="application_password"&&!a?.render&&(s.render=Vh),Oh(i,s)}}var Cr=b(W());function Bf(){return(0,Cr.jsx)("div",{className:"ai-plugin-callout__decoration","aria-hidden":"true",children:(0,Cr.jsx)("svg",{viewBox:"0 0 248 248",xmlns:"http://www.w3.org/2000/svg",xmlnsXlink:"http://www.w3.org/1999/xlink",focusable:"false",style:{width:"100%",height:"100%"},children:(0,Cr.jsx)("image",{href:"data:image/png;base64,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",width:"248",height:"248",style:{mixBlendMode:"multiply"}})})})}var Rt=b(W()),Wh="ai",Yh="ai-wp-admin",ia="ai/ai",Uh="https://wordpress.org/plugins/ai/",aa=Object.values(ra()),Gh=aa.some(e=>e.type==="ai_provider"),Df=[];for(let e of aa)e.type==="ai_provider"&&e.authentication.method==="api_key"&&Df.push(e.authentication.settingName);function jf(){let[e,t]=(0,Et.useState)(!1),[o,n]=(0,Et.useState)(!1),r=(0,Et.useRef)(null);(0,Et.useEffect)(()=>{o&&r.current?.focus()},[o]);let i=(0,Et.useRef)(aa.some(R=>R.type==="ai_provider"&&R.authentication.method==="api_key"&&R.authentication.isConnected)).current,{pluginStatus:s,canInstallPlugins:a,canManagePlugins:l,hasConnectedProvider:c}=(0,pn.useSelect)(R=>{let x=R(sa.store),S=!!x.canUser("create",{kind:"root",name:"plugin"}),E=x.getEntityRecord("root","site"),k=i||Df.some(H=>!!E?.[H]),P=x.getEntityRecord("root","plugin",ia);return x.hasFinishedResolution("getEntityRecord",["root","plugin",ia])?P?{pluginStatus:P.status==="active"?"active":"inactive",canInstallPlugins:S,canManagePlugins:!0,hasConnectedProvider:k}:{pluginStatus:"not-installed",canInstallPlugins:S,canManagePlugins:S,hasConnectedProvider:k}:{pluginStatus:"checking",canInstallPlugins:S,canManagePlugins:void 0,hasConnectedProvider:k}},[]),{saveEntityRecord:d}=(0,pn.useDispatch)(sa.store),{createSuccessNotice:m,createErrorNotice:u}=(0,pn.useDispatch)(Hf.store),f=async()=>{t(!0);try{await d("root","plugin",{slug:Wh,status:"active"},{throwOnError:!0}),n(!0),m((0,Qe.__)("AI plugin installed and activated successfully."),{id:"ai-plugin-install-success",type:"snackbar"})}catch{u((0,Qe.__)("Failed to install the AI plugin."),{id:"ai-plugin-install-error",type:"snackbar"})}finally{t(!1)}},p=async()=>{t(!0);try{await d("root","plugin",{plugin:ia,status:"active"},{throwOnError:!0}),n(!0),m((0,Qe.__)("AI plugin activated successfully."),{id:"ai-plugin-activate-success",type:"snackbar"})}catch{u((0,Qe.__)("Failed to activate the AI plugin."),{id:"ai-plugin-activate-error",type:"snackbar"})}finally{t(!1)}};if(!Gh||s==="checking"||s==="active"&&i&&!o||s==="inactive"&&l===!1)return null;let g=s==="active"&&!c,h=s==="active"&&c&&(!i||o),y=s==="not-installed"||s==="inactive",_=s==="not-installed"&&a===!1,v=()=>h?(0,Qe.__)("The AI plugin is ready to use. You can use it to generate featured images, alt text, titles, excerpts and more. Learn more"):g?(0,Qe.__)("The AI plugin is installed. Connect an AI provider below to generate featured images, alt text, titles, excerpts, and more. Learn more"):(0,Qe.__)("The AI plugin can use your AI connectors to generate featured images, alt text, titles, excerpts and more. Learn more"),w=()=>s==="not-installed"?{label:e?(0,Qe.__)("Installing\u2026"):(0,Qe.__)("Install the AI plugin"),disabled:e,onClick:e?void 0:f}:{label:e?(0,Qe.__)("Activating\u2026"):(0,Qe.__)("Activate the AI plugin"),disabled:e,onClick:e?void 0:p};return(0,Rt.jsxs)("div",{className:"ai-plugin-callout",children:[(0,Rt.jsxs)("div",{className:"ai-plugin-callout__content",children:[(0,Rt.jsx)("p",{children:(0,Et.createInterpolateElement)(v(),{strong:(0,Rt.jsx)("strong",{}),a:(0,Rt.jsx)(fn.ExternalLink,{href:Uh})})}),!_&&(y?(0,Rt.jsx)(fn.Button,{variant:"primary",size:"compact",isBusy:e,disabled:w().disabled,accessibleWhenDisabled:!0,onClick:w().onClick,children:w().label}):(0,Rt.jsx)(fn.Button,{ref:r,variant:"secondary",size:"compact",href:(0,zf.addQueryArgs)("options-general.php",{page:Yh}),children:(0,Qe.__)("Control features in the AI plugin")}))]}),(0,Rt.jsx)(Bf,{})]})}var Re=b(W()),{store:Xh}=Lo(Kh);Mf();function qh(){let e=Nf(),{connectors:t,canInstallPlugins:o,isAiPluginInstalled:n}=(0,Ff.useSelect)(c=>{let d=c(Wf.store),m=d.getEntityRecord("root","plugin","ai/ai");return{connectors:Lo(c(Xh)).getConnectors(),canInstallPlugins:d.canUser("create",{kind:"root",name:"plugin"}),isAiPluginInstalled:!!m}},[]),r=t.filter(c=>c.render),i=Array.from(new Set(t.filter(c=>c.type==="ai_provider").map(c=>c.plugin?.file?.split("/")[0]).filter(c=>!!c))).sort(),s=new Set(t.filter(c=>c.plugin?.isInstalled).map(c=>c.plugin?.file?.split("/")[0]).filter(c=>!!c));n&&s.add("ai");let a=["ai",...i].filter(c=>!s.has(c)),l=r.length===0;return(0,Re.jsx)($s,{title:(0,At.__)("Connectors"),subTitle:(0,At.__)("All of your API keys and credentials are stored here and shared across plugins. Configure once and use everywhere."),children:(0,Re.jsxs)("div",{className:`connectors-page${l?" connectors-page--empty":""}`,children:[a.length>0&&(e||!o)&&(0,Re.jsx)(sn.Root,{intent:"info",className:"connectors-page__file-mods-notice",children:(0,Re.jsx)(sn.Description,{children:e?(0,At.__)("Plugins cannot be installed here due to your site configuration. Install them manually using your normal deployment workflow."):(0,At.__)("You do not have permission to install plugins. Please ask a site administrator to install them for you.")})}),l?(0,Re.jsxs)(ut.__experimentalVStack,{alignment:"center",spacing:3,style:{maxWidth:480},children:[(0,Re.jsxs)(ut.__experimentalVStack,{alignment:"center",spacing:2,children:[(0,Re.jsx)(ut.__experimentalHeading,{level:2,size:15,children:(0,At.__)("No connectors yet")}),(0,Re.jsx)(ut.__experimentalText,{size:12,children:(0,At.__)("Connectors appear here when you install plugins that use external services. Each plugin registers the API keys it needs, and you manage them all in one place.")})]}),(0,Re.jsx)(ut.Button,{variant:"secondary",href:"plugin-install.php",__next40pxDefaultSize:!0,children:(0,At.__)("Learn more")})]}):(0,Re.jsxs)(ut.__experimentalVStack,{spacing:3,children:[(0,Re.jsx)(jf,{}),(0,Re.jsx)(ut.__experimentalVStack,{spacing:3,role:"list",children:t.map(c=>c.render?(0,Re.jsx)(c.render,{slug:c.slug,name:c.name,description:c.description,type:c.type,logo:c.logo,authentication:c.authentication,plugin:c.plugin},c.slug):null)})]}),o&&!e&&(0,Re.jsx)("p",{className:"connectors-page__help-text",children:(0,Vf.createInterpolateElement)((0,At.__)("If the connector you need is not listed, search the plugin directory to see if a connector is available."),{a:(0,Re.jsx)("a",{href:"plugin-install.php?s=connector&tab=search&type=tag"})})})]})})}function Zh(){return(0,Re.jsx)(qh,{})}var Qh=Zh;export{Qh as stage}; /*! Bundled license information: use-sync-external-store/cjs/use-sync-external-store-shim.production.js: diff --git a/src/wp-includes/build/routes/font-list/content.js b/src/wp-includes/build/routes/font-list/content.js index 6f0404e093d80..42109fc02956a 100644 --- a/src/wp-includes/build/routes/font-list/content.js +++ b/src/wp-includes/build/routes/font-list/content.js @@ -224,13 +224,6 @@ var require_with_selector = __commonJS({ } }); -// package-external:@wordpress/primitives -var require_primitives = __commonJS({ - "package-external:@wordpress/primitives"(exports, module) { - module.exports = window.wp.primitives; - } -}); - // package-external:@wordpress/compose var require_compose = __commonJS({ "package-external:@wordpress/compose"(exports, module) { @@ -252,6 +245,13 @@ var require_private_apis = __commonJS({ } }); +// package-external:@wordpress/primitives +var require_primitives = __commonJS({ + "package-external:@wordpress/primitives"(exports, module) { + module.exports = window.wp.primitives; + } +}); + // package-external:@wordpress/components var require_components = __commonJS({ "package-external:@wordpress/components"(exports, module) { @@ -483,16 +483,16 @@ var require_date = __commonJS({ // node_modules/clsx/dist/clsx.mjs function r(e2) { - var t3, f2, n2 = ""; + var t2, f2, n2 = ""; if ("string" == typeof e2 || "number" == typeof e2) n2 += e2; else if ("object" == typeof e2) if (Array.isArray(e2)) { - var o3 = e2.length; - for (t3 = 0; t3 < o3; t3++) e2[t3] && (f2 = r(e2[t3])) && (n2 && (n2 += " "), n2 += f2); + var o2 = e2.length; + for (t2 = 0; t2 < o2; t2++) e2[t2] && (f2 = r(e2[t2])) && (n2 && (n2 += " "), n2 += f2); } else for (f2 in e2) e2[f2] && (n2 && (n2 += " "), n2 += f2); return n2; } function clsx() { - for (var e2, t3, f2 = 0, n2 = "", o3 = arguments.length; f2 < o3; f2++) (e2 = arguments[f2]) && (t3 = r(e2)) && (n2 && (n2 += " "), n2 += t3); + for (var e2, t2, f2 = 0, n2 = "", o2 = arguments.length; f2 < o2; f2++) (e2 = arguments[f2]) && (t2 = r(e2)) && (n2 && (n2 += " "), n2 += t2); return n2; } var clsx_default = clsx; @@ -8679,13 +8679,13 @@ function registerStyle(hash, css) { } } if (typeof process === "undefined" || true) { - registerStyle("a495f9d138", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._83ed8a8da5dd50ea__text{margin:0}._14437cfb77831647__heading-2xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-2xl,32px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-2xl,32px);--_gcd-p-line-height:var(--wpds-typography-line-height-2xl,40px);font-size:var(--wpds-typography-font-size-2xl,32px);line-height:var(--wpds-typography-line-height-2xl,40px)}._14437cfb77831647__heading-2xl,._3c78b7fa9b4072dd__heading-xl{font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-emphasis,600)}._3c78b7fa9b4072dd__heading-xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-p-line-height:var(--wpds-typography-line-height-md,24px);font-size:var(--wpds-typography-font-size-xl,20px);line-height:var(--wpds-typography-line-height-md,24px)}.aa58f227716bcde2__heading-lg{--_gcd-heading-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-lg,15px)}.aa58f227716bcde2__heading-lg,.fc4da56d8dfe52c4__heading-md{font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:var(--wpds-typography-line-height-sm,20px)}.fc4da56d8dfe52c4__heading-md{--_gcd-heading-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-md,13px)}.a9b78c7c82e8dff7__heading-sm{--_gcd-heading-font-size:var(--wpds-typography-font-size-xs,11px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-xs,11px);--_gcd-p-line-height:var(--wpds-typography-line-height-xs,16px);font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-xs,11px);font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:var(--wpds-typography-line-height-xs,16px);text-transform:uppercase}._305ff559e52180d5__body-xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-p-line-height:var(--wpds-typography-line-height-xl,32px);font-size:var(--wpds-typography-font-size-xl,20px);line-height:var(--wpds-typography-line-height-xl,32px)}._305ff559e52180d5__body-xl,.ca1aa3fc2029e958__body-lg{font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-default,400)}.ca1aa3fc2029e958__body-lg{--_gcd-heading-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-p-line-height:var(--wpds-typography-line-height-md,24px);font-size:var(--wpds-typography-font-size-lg,15px);line-height:var(--wpds-typography-line-height-md,24px)}._131101940be12424__body-md{--_gcd-heading-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-md,13px);line-height:var(--wpds-typography-line-height-sm,20px)}._0e8d87a42c1f75fa__body-sm,._131101940be12424__body-md{font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-default,400)}._0e8d87a42c1f75fa__body-sm{--_gcd-heading-font-size:var(--wpds-typography-font-size-sm,12px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-sm,12px);--_gcd-p-line-height:var(--wpds-typography-line-height-xs,16px);font-size:var(--wpds-typography-font-size-sm,12px);line-height:var(--wpds-typography-line-height-xs,16px)}}}'); + registerStyle("3167e7d116", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._83ed8a8da5dd50ea__text{text-wrap:pretty;margin:0}._14437cfb77831647__heading-2xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-2xl,32px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-2xl,32px);--_gcd-p-line-height:var(--wpds-typography-line-height-2xl,40px);font-size:var(--wpds-typography-font-size-2xl,32px);line-height:var(--wpds-typography-line-height-2xl,40px)}._14437cfb77831647__heading-2xl,._3c78b7fa9b4072dd__heading-xl{font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-emphasis,600)}._3c78b7fa9b4072dd__heading-xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-p-line-height:var(--wpds-typography-line-height-md,24px);font-size:var(--wpds-typography-font-size-xl,20px);line-height:var(--wpds-typography-line-height-md,24px)}.aa58f227716bcde2__heading-lg{--_gcd-heading-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-lg,15px)}.aa58f227716bcde2__heading-lg,.fc4da56d8dfe52c4__heading-md{font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:var(--wpds-typography-line-height-sm,20px)}.fc4da56d8dfe52c4__heading-md{--_gcd-heading-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-md,13px)}.a9b78c7c82e8dff7__heading-sm{--_gcd-heading-font-size:var(--wpds-typography-font-size-xs,11px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-xs,11px);--_gcd-p-line-height:var(--wpds-typography-line-height-xs,16px);font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-xs,11px);font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:var(--wpds-typography-line-height-xs,16px);text-transform:uppercase}._305ff559e52180d5__body-xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-p-line-height:var(--wpds-typography-line-height-xl,32px);font-size:var(--wpds-typography-font-size-xl,20px);line-height:var(--wpds-typography-line-height-xl,32px)}._305ff559e52180d5__body-xl,.ca1aa3fc2029e958__body-lg{font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-default,400)}.ca1aa3fc2029e958__body-lg{--_gcd-heading-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-p-line-height:var(--wpds-typography-line-height-md,24px);font-size:var(--wpds-typography-font-size-lg,15px);line-height:var(--wpds-typography-line-height-md,24px)}._131101940be12424__body-md{--_gcd-heading-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-md,13px);line-height:var(--wpds-typography-line-height-sm,20px)}._0e8d87a42c1f75fa__body-sm,._131101940be12424__body-md{font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-default,400)}._0e8d87a42c1f75fa__body-sm{--_gcd-heading-font-size:var(--wpds-typography-font-size-sm,12px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-sm,12px);--_gcd-p-line-height:var(--wpds-typography-line-height-xs,16px);font-size:var(--wpds-typography-font-size-sm,12px);line-height:var(--wpds-typography-line-height-xs,16px)}}}'); } var style_default = { "text": "_83ed8a8da5dd50ea__text", "heading-2xl": "_14437cfb77831647__heading-2xl", "heading-xl": "_3c78b7fa9b4072dd__heading-xl", "heading-lg": "aa58f227716bcde2__heading-lg", "heading-md": "fc4da56d8dfe52c4__heading-md", "heading-sm": "a9b78c7c82e8dff7__heading-sm", "body-xl": "_305ff559e52180d5__body-xl", "body-lg": "ca1aa3fc2029e958__body-lg", "body-md": "_131101940be12424__body-md", "body-sm": "_0e8d87a42c1f75fa__body-sm" }; if (typeof process === "undefined" || true) { - registerStyle("af6d9984a6", "._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}"); + registerStyle("e8e31009f5", "._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-weak,#707070))}&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}.c59a0ebebd71fa4a__ol{list-style:var(--_gcd-ol-list-style,none);margin:var(--_gcd-ol-margin,0);padding-block:var(--_gcd-ol-padding-block,0);padding-inline:var(--_gcd-ol-padding-inline,0)}._46b5cb0c8e24e8c9__li{margin:var(--_gcd-li-margin,0)}"); } -var global_css_defense_default = { "button": "_6defc79820e382c6__button", "input": "d2cff2e5dea83bd1__input", "textarea": "_547d86373d02e108__textarea", "div": "_8c15fd0ed9f28ba4__div", "p": "_43cec3e1eec1066d__p", "heading": "e97669c6d9a38497__heading", "a": "_2c0831b0499dbd6e__a" }; +var global_css_defense_default = { "button": "_6defc79820e382c6__button", "input": "d2cff2e5dea83bd1__input", "textarea": "_547d86373d02e108__textarea", "div": "_8c15fd0ed9f28ba4__div", "p": "_43cec3e1eec1066d__p", "heading": "e97669c6d9a38497__heading", "a": "_2c0831b0499dbd6e__a", "ol": "c59a0ebebd71fa4a__ol", "li": "_46b5cb0c8e24e8c9__li" }; var Text = (0, import_element10.forwardRef)(function Text2({ variant = "body-md", render, className, ...props }, ref) { const element = useRender({ render, @@ -8704,44 +8704,6 @@ var Text = (0, import_element10.forwardRef)(function Text2({ variant = "body-md" return element; }); -// packages/icons/build-module/icon/index.mjs -var import_element11 = __toESM(require_element(), 1); -var icon_default = (0, import_element11.forwardRef)( - ({ icon, size: size4 = 24, ...props }, ref) => { - return (0, import_element11.cloneElement)(icon, { - width: size4, - height: size4, - ...props, - ref - }); - } -); - -// packages/icons/build-module/library/chevron-left.mjs -var import_primitives = __toESM(require_primitives(), 1); -var import_jsx_runtime12 = __toESM(require_jsx_runtime(), 1); -var chevron_left_default = /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_primitives.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_primitives.Path, { d: "M14.6 7l-1.2-1L8 12l5.4 6 1.2-1-4.6-5z" }) }); - -// packages/icons/build-module/library/chevron-right.mjs -var import_primitives2 = __toESM(require_primitives(), 1); -var import_jsx_runtime13 = __toESM(require_jsx_runtime(), 1); -var chevron_right_default = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_primitives2.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_primitives2.Path, { d: "M10.6 6L9.4 7l4.6 5-4.6 5 1.2 1 5.4-6z" }) }); - -// packages/icons/build-module/library/more-vertical.mjs -var import_primitives3 = __toESM(require_primitives(), 1); -var import_jsx_runtime14 = __toESM(require_jsx_runtime(), 1); -var more_vertical_default = /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_primitives3.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_primitives3.Path, { d: "M13 19h-2v-2h2v2zm0-6h-2v-2h2v2zm0-6h-2V5h2v2z" }) }); - -// packages/icons/build-module/library/next.mjs -var import_primitives4 = __toESM(require_primitives(), 1); -var import_jsx_runtime15 = __toESM(require_jsx_runtime(), 1); -var next_default = /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_primitives4.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_primitives4.Path, { d: "M6.6 6L5.4 7l4.5 5-4.5 5 1.1 1 5.5-6-5.4-6zm6 0l-1.1 1 4.5 5-4.5 5 1.1 1 5.5-6-5.5-6z" }) }); - -// packages/icons/build-module/library/previous.mjs -var import_primitives5 = __toESM(require_primitives(), 1); -var import_jsx_runtime16 = __toESM(require_jsx_runtime(), 1); -var previous_default = /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_primitives5.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_primitives5.Path, { d: "M11.6 7l-1.1-1L5 12l5.5 6 1.1-1L7 12l4.6-5zm6 0l-1.1-1-5.5 6 5.5 6 1.1-1-4.6-5 4.6-5z" }) }); - // packages/ui/build-module/tooltip/index.mjs var tooltip_exports = {}; __export(tooltip_exports, { @@ -8754,10 +8716,10 @@ __export(tooltip_exports, { }); // packages/ui/build-module/tooltip/popup.mjs -var import_element15 = __toESM(require_element(), 1); +var import_element14 = __toESM(require_element(), 1); // packages/ui/build-module/tooltip/portal.mjs -var import_element12 = __toESM(require_element(), 1); +var import_element11 = __toESM(require_element(), 1); // packages/ui/build-module/utils/wp-compat-overlay-slot.mjs var STYLE_HASH_ATTRIBUTE2 = "data-wp-hash"; @@ -8900,10 +8862,10 @@ function getWpCompatOverlaySlot() { } // packages/ui/build-module/tooltip/portal.mjs -var import_jsx_runtime17 = __toESM(require_jsx_runtime(), 1); -var Portal = (0, import_element12.forwardRef)( +var import_jsx_runtime12 = __toESM(require_jsx_runtime(), 1); +var Portal = (0, import_element11.forwardRef)( function TooltipPortal3({ container, ...restProps }, ref) { - return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)( + return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)( index_parts_exports.Portal, { container: container ?? getWpCompatOverlaySlot(), @@ -8915,8 +8877,8 @@ var Portal = (0, import_element12.forwardRef)( ); // packages/ui/build-module/tooltip/positioner.mjs -var import_element13 = __toESM(require_element(), 1); -var import_jsx_runtime18 = __toESM(require_jsx_runtime(), 1); +var import_element12 = __toESM(require_element(), 1); +var import_jsx_runtime13 = __toESM(require_jsx_runtime(), 1); var STYLE_HASH_ATTRIBUTE3 = "data-wp-hash"; function getRuntime3() { const globalScope = globalThis; @@ -9005,9 +8967,9 @@ if (typeof process === "undefined" || true) { registerStyle3("19fcc06039", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}'); } var style_default2 = { "positioner": "_480b748dd3510e64__positioner", "popup": "_50096b232db7709d__popup" }; -var Positioner = (0, import_element13.forwardRef)( +var Positioner = (0, import_element12.forwardRef)( function TooltipPositioner3({ align = "center", className, side = "top", sideOffset = 4, ...props }, ref) { - return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)( + return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)( index_parts_exports.Positioner, { ref, @@ -9026,9 +8988,9 @@ var Positioner = (0, import_element13.forwardRef)( ); // packages/ui/build-module/utils/render-slot-with-children.mjs -var import_element14 = __toESM(require_element(), 1); +var import_element13 = __toESM(require_element(), 1); function renderSlotWithChildren(slot, defaultSlot, children) { - return (0, import_element14.cloneElement)(slot ?? defaultSlot, { children }); + return (0, import_element13.cloneElement)(slot ?? defaultSlot, { children }); } // packages/ui/build-module/utils/theme-provider.mjs @@ -9059,7 +9021,7 @@ function getThemeProvider() { var ThemeProvider = getThemeProvider(); // packages/ui/build-module/tooltip/popup.mjs -var import_jsx_runtime19 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime14 = __toESM(require_jsx_runtime(), 1); var STYLE_HASH_ATTRIBUTE4 = "data-wp-hash"; function getRuntime4() { const globalScope = globalThis; @@ -9145,8 +9107,8 @@ if (typeof process === "undefined" || true) { } var style_default3 = { "positioner": "_480b748dd3510e64__positioner", "popup": "_50096b232db7709d__popup" }; var POPUP_COLOR = { background: "#1e1e1e" }; -var Popup = (0, import_element15.forwardRef)(function TooltipPopup3({ portal, positioner, children, className, ...props }, ref) { - const popupContent = /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ThemeProvider, { color: POPUP_COLOR, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)( +var Popup = (0, import_element14.forwardRef)(function TooltipPopup3({ portal, positioner, children, className, ...props }, ref) { + const popupContent = /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ThemeProvider, { color: POPUP_COLOR, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)( index_parts_exports.Popup, { ref, @@ -9157,42 +9119,44 @@ var Popup = (0, import_element15.forwardRef)(function TooltipPopup3({ portal, po ) }); const positionedPopup = renderSlotWithChildren( positioner, - /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Positioner, {}), + /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Positioner, {}), popupContent ); - return renderSlotWithChildren(portal, /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Portal, {}), positionedPopup); + return renderSlotWithChildren(portal, /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Portal, {}), positionedPopup); }); // packages/ui/build-module/tooltip/trigger.mjs -var import_element16 = __toESM(require_element(), 1); -var import_jsx_runtime20 = __toESM(require_jsx_runtime(), 1); -var Trigger = (0, import_element16.forwardRef)( +var import_element15 = __toESM(require_element(), 1); +var import_jsx_runtime15 = __toESM(require_jsx_runtime(), 1); +var Trigger = (0, import_element15.forwardRef)( function TooltipTrigger3(props, ref) { - return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(index_parts_exports.Trigger, { ref, ...props }); + return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(index_parts_exports.Trigger, { ref, ...props }); } ); // packages/ui/build-module/utils/direction-provider.mjs var import_i18n = __toESM(require_i18n(), 1); -var import_jsx_runtime21 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime16 = __toESM(require_jsx_runtime(), 1); function DirectionProvider3({ children }) { - return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(DirectionProvider, { direction: (0, import_i18n.isRTL)() ? "rtl" : "ltr", children }); + return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DirectionProvider, { direction: (0, import_i18n.isRTL)() ? "rtl" : "ltr", children }); } // packages/ui/build-module/tooltip/root.mjs -var import_jsx_runtime22 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime17 = __toESM(require_jsx_runtime(), 1); function Root(props) { - return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(DirectionProvider3, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(index_parts_exports.Root, { ...props }) }); + return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DirectionProvider3, { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(index_parts_exports.Root, { ...props }) }); } // packages/ui/build-module/tooltip/provider.mjs -var import_jsx_runtime23 = __toESM(require_jsx_runtime(), 1); +var import_jsx_runtime18 = __toESM(require_jsx_runtime(), 1); function Provider({ ...props }) { - return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(index_parts_exports.Provider, { ...props }); + return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(index_parts_exports.Provider, { ...props }); } -// packages/ui/build-module/visually-hidden/visually-hidden.mjs -var import_element17 = __toESM(require_element(), 1); +// packages/ui/build-module/link/link.mjs +var import_element16 = __toESM(require_element(), 1); +var import_i18n2 = __toESM(require_i18n(), 1); +var import_jsx_runtime19 = __toESM(require_jsx_runtime(), 1); var STYLE_HASH_ATTRIBUTE5 = "data-wp-hash"; function getRuntime5() { const globalScope = globalThis; @@ -9274,28 +9238,111 @@ function registerStyle5(hash, css) { } } if (typeof process === "undefined" || true) { - registerStyle5("fa606a57ae", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.f37b9e2e191ebd66__visually-hidden{word-wrap:normal;border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-break:normal}}}"); + registerStyle5("10f3806643", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}"); } -var style_default4 = { "visually-hidden": "f37b9e2e191ebd66__visually-hidden" }; -var VisuallyHidden = (0, import_element17.forwardRef)( - function VisuallyHidden2({ render, ...restProps }, ref) { - const element = useRender({ - render, - ref, - props: mergeProps( - { className: style_default4["visually-hidden"] }, - restProps, - { - // @ts-expect-error Arbitrary data-* attributes aren't indexable on the typed div props. Kept hardcoded so consumers can't change or remove it. - "data-visually-hidden": "" - } - ) +var resets_default2 = { "box-sizing": "_336cd3e4e743482f__box-sizing" }; +if (typeof process === "undefined" || true) { + registerStyle5("08122b3d53", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{.af79fb116edb0dd7__outset-ring--focus:focus,.dfcfdc28396e5d98__outset-ring--focus-visible:focus-visible,.e5cd9ee879f6403a__outset-ring--focus-within:focus-within,:focus-visible ._81935a08e952f267__outset-ring--focus-parent-visible{--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within,.abc777e9713fa711__outset-ring--focus-except-active:focus{outline:none}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within:not(:has(:active)),.abc777e9713fa711__outset-ring--focus-except-active:focus:not(:active){--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}}}"); +} +var focus_module_default = { "outset-ring--focus": "af79fb116edb0dd7__outset-ring--focus", "outset-ring--focus-visible": "dfcfdc28396e5d98__outset-ring--focus-visible", "outset-ring--focus-within": "e5cd9ee879f6403a__outset-ring--focus-within", "outset-ring--focus-parent-visible": "_81935a08e952f267__outset-ring--focus-parent-visible", "outset-ring--focus-except-active": "abc777e9713fa711__outset-ring--focus-except-active", "outset-ring--focus-within-except-active": "_3c9f5ee9fc9c136d__outset-ring--focus-within-except-active" }; +if (typeof process === "undefined" || true) { + registerStyle5("e8e6a9be37", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.d4250949359b05ce__link{text-decoration-thickness:from-font;text-underline-offset:.2em}.c6055659b8e2cd2c__is-brand,.c6055659b8e2cd2c__is-brand:visited{--_gcd-a-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9))}.c6055659b8e2cd2c__is-brand:active,.c6055659b8e2cd2c__is-brand:hover{--_gcd-a-color:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));color:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000))}._92e0dfcaeee15b88__is-neutral,._92e0dfcaeee15b88__is-neutral:visited{--_gcd-a-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);text-decoration-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d)}._92e0dfcaeee15b88__is-neutral:active,._92e0dfcaeee15b88__is-neutral:hover{--_gcd-a-color:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);color:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e)}.cf122a9bf1035d42__is-unstyled{--_gcd-a-color:inherit;color:inherit;text-decoration:none}._0cb411afac4c86c7__link-icon{display:inline-block;font-weight:var(--wpds-typography-font-weight-default,400);line-height:1;margin-inline-start:var(--wpds-dimension-padding-xs,4px);text-decoration:none}._0cb411afac4c86c7__link-icon:after{content:"\\2197"}._0cb411afac4c86c7__link-icon:dir(rtl):after{content:"\\2196"}}}'); +} +var style_default4 = { "link": "d4250949359b05ce__link", "is-brand": "c6055659b8e2cd2c__is-brand", "is-neutral": "_92e0dfcaeee15b88__is-neutral", "is-unstyled": "cf122a9bf1035d42__is-unstyled", "link-icon": "_0cb411afac4c86c7__link-icon" }; +if (typeof process === "undefined" || true) { + registerStyle5("e8e31009f5", "._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-weak,#707070))}&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}.c59a0ebebd71fa4a__ol{list-style:var(--_gcd-ol-list-style,none);margin:var(--_gcd-ol-margin,0);padding-block:var(--_gcd-ol-padding-block,0);padding-inline:var(--_gcd-ol-padding-inline,0)}._46b5cb0c8e24e8c9__li{margin:var(--_gcd-li-margin,0)}"); +} +var global_css_defense_default2 = { "button": "_6defc79820e382c6__button", "input": "d2cff2e5dea83bd1__input", "textarea": "_547d86373d02e108__textarea", "div": "_8c15fd0ed9f28ba4__div", "p": "_43cec3e1eec1066d__p", "heading": "e97669c6d9a38497__heading", "a": "_2c0831b0499dbd6e__a", "ol": "c59a0ebebd71fa4a__ol", "li": "_46b5cb0c8e24e8c9__li" }; +var Link = (0, import_element16.forwardRef)(function Link2({ + children, + variant = "default", + tone = "brand", + openInNewTab = false, + target, + render, + className, + ...props +}, ref) { + const shouldShowNewTabIndicator = openInNewTab || /^_blank$/i.test(target ?? ""); + const element = useRender({ + render, + defaultTagName: "a", + ref, + props: mergeProps(props, { + className: clsx_default( + global_css_defense_default2.a, + resets_default2["box-sizing"], + focus_module_default["outset-ring--focus-except-active"], + variant !== "unstyled" && style_default4.link, + variant !== "unstyled" && style_default4[`is-${tone}`], + variant === "unstyled" && style_default4["is-unstyled"], + className + ), + target: target ?? (openInNewTab ? "_blank" : void 0), + children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [ + children, + shouldShowNewTabIndicator && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)( + "span", + { + className: style_default4["link-icon"], + role: "img", + "aria-label": ( + /* translators: accessibility text appended to link text */ + (0, import_i18n2.__)("(opens in a new tab)") + ) + } + ) + ] }) + }) + }); + return element; +}); + +// packages/icons/build-module/icon/index.mjs +var import_element17 = __toESM(require_element(), 1); +var icon_default = (0, import_element17.forwardRef)( + ({ icon, size: size4 = 24, style, ...props }, ref) => { + const intrinsicStyle = icon.props.style; + const mergedStyle = intrinsicStyle || style ? { ...intrinsicStyle, ...style } : void 0; + return (0, import_element17.cloneElement)(icon, { + width: size4, + height: size4, + ...props, + // Merge styles so the icon's intrinsic style (e.g. `fill: none` on + // stroke-based icons) is preserved unless the consumer overrides + // the same property explicitly. + ...mergedStyle ? { style: mergedStyle } : {}, + ref }); - return element; } ); -// packages/ui/build-module/stack/stack.mjs +// packages/icons/build-module/library/chevron-left.mjs +var import_primitives = __toESM(require_primitives(), 1); +var import_jsx_runtime20 = __toESM(require_jsx_runtime(), 1); +var chevron_left_default = /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_primitives.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", style: { fill: "none" }, stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_primitives.Path, { d: "M14 6.5L9 12L14 17.5", vectorEffect: "non-scaling-stroke" }) }); + +// packages/icons/build-module/library/chevron-right.mjs +var import_primitives2 = __toESM(require_primitives(), 1); +var import_jsx_runtime21 = __toESM(require_jsx_runtime(), 1); +var chevron_right_default = /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_primitives2.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", style: { fill: "none" }, stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_primitives2.Path, { d: "M10 6.5L15 12L10 17.5", vectorEffect: "non-scaling-stroke" }) }); + +// packages/icons/build-module/library/more-vertical.mjs +var import_primitives3 = __toESM(require_primitives(), 1); +var import_jsx_runtime22 = __toESM(require_jsx_runtime(), 1); +var more_vertical_default = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_primitives3.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_primitives3.Path, { d: "M13 19h-2v-2h2v2zm0-6h-2v-2h2v2zm0-6h-2V5h2v2z" }) }); + +// packages/icons/build-module/library/next.mjs +var import_primitives4 = __toESM(require_primitives(), 1); +var import_jsx_runtime23 = __toESM(require_jsx_runtime(), 1); +var next_default = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_primitives4.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", style: { fill: "none" }, stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_primitives4.Path, { d: "M7 17.5L12 12L7 6.5M13 17.5L18 12L13 6.5", vectorEffect: "non-scaling-stroke" }) }); + +// packages/icons/build-module/library/previous.mjs +var import_primitives5 = __toESM(require_primitives(), 1); +var import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1); +var previous_default = /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_primitives5.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", style: { fill: "none" }, stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_primitives5.Path, { d: "M17 6.5L12 12L17 17.5M11 6.5L6 12L11 17.5", vectorEffect: "non-scaling-stroke" }) }); + +// packages/ui/build-module/visually-hidden/visually-hidden.mjs var import_element18 = __toESM(require_element(), 1); var STYLE_HASH_ATTRIBUTE6 = "data-wp-hash"; function getRuntime6() { @@ -9378,38 +9425,29 @@ function registerStyle6(hash, css) { } } if (typeof process === "undefined" || true) { - registerStyle6("32aba35fe1", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._19ce0419607e1896__stack{display:flex}}}"); + registerStyle6("fa606a57ae", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.f37b9e2e191ebd66__visually-hidden{word-wrap:normal;border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-break:normal}}}"); } -var style_default5 = { "stack": "_19ce0419607e1896__stack" }; -var gapTokens = { - xs: "var(--wpds-dimension-gap-xs, 4px)", - sm: "var(--wpds-dimension-gap-sm, 8px)", - md: "var(--wpds-dimension-gap-md, 12px)", - lg: "var(--wpds-dimension-gap-lg, 16px)", - xl: "var(--wpds-dimension-gap-xl, 24px)", - "2xl": "var(--wpds-dimension-gap-2xl, 32px)", - "3xl": "var(--wpds-dimension-gap-3xl, 40px)" -}; -var Stack = (0, import_element18.forwardRef)(function Stack2({ direction, gap, align, justify, wrap, render, ...props }, ref) { - const style = { - gap: gap && gapTokens[gap], - alignItems: align, - justifyContent: justify, - flexDirection: direction, - flexWrap: wrap - }; - const element = useRender({ - render, - ref, - props: mergeProps(props, { style, className: style_default5.stack }) - }); - return element; -}); +var style_default5 = { "visually-hidden": "f37b9e2e191ebd66__visually-hidden" }; +var VisuallyHidden = (0, import_element18.forwardRef)( + function VisuallyHidden2({ render, ...restProps }, ref) { + const element = useRender({ + render, + ref, + props: mergeProps( + { className: style_default5["visually-hidden"] }, + restProps, + { + // @ts-expect-error Arbitrary data-* attributes aren't indexable on the typed div props. Kept hardcoded so consumers can't change or remove it. + "data-visually-hidden": "" + } + ) + }); + return element; + } +); -// packages/ui/build-module/link/link.mjs +// packages/ui/build-module/stack/stack.mjs var import_element19 = __toESM(require_element(), 1); -var import_i18n2 = __toESM(require_i18n(), 1); -var import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1); var STYLE_HASH_ATTRIBUTE7 = "data-wp-hash"; function getRuntime7() { const globalScope = globalThis; @@ -9491,60 +9529,30 @@ function registerStyle7(hash, css) { } } if (typeof process === "undefined" || true) { - registerStyle7("10f3806643", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}"); -} -var resets_default2 = { "box-sizing": "_336cd3e4e743482f__box-sizing" }; -if (typeof process === "undefined" || true) { - registerStyle7("96553466c8", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._64de9947bf305b7a__outset-ring--focus-within-visible:focus-within:has(:focus-visible),.af79fb116edb0dd7__outset-ring--focus:focus,.dfcfdc28396e5d98__outset-ring--focus-visible:focus-visible,.e5cd9ee879f6403a__outset-ring--focus-within:focus-within,:focus-visible ._81935a08e952f267__outset-ring--focus-parent-visible{--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within,.abc777e9713fa711__outset-ring--focus-except-active:focus{outline:none}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within:not(:has(:active)),.abc777e9713fa711__outset-ring--focus-except-active:focus:not(:active){--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}}}"); -} -var focus_module_default = { "outset-ring--focus": "af79fb116edb0dd7__outset-ring--focus", "outset-ring--focus-visible": "dfcfdc28396e5d98__outset-ring--focus-visible", "outset-ring--focus-within": "e5cd9ee879f6403a__outset-ring--focus-within", "outset-ring--focus-within-visible": "_64de9947bf305b7a__outset-ring--focus-within-visible", "outset-ring--focus-parent-visible": "_81935a08e952f267__outset-ring--focus-parent-visible", "outset-ring--focus-except-active": "abc777e9713fa711__outset-ring--focus-except-active", "outset-ring--focus-within-except-active": "_3c9f5ee9fc9c136d__outset-ring--focus-within-except-active" }; -if (typeof process === "undefined" || true) { - registerStyle7("e8e6a9be37", '@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.d4250949359b05ce__link{text-decoration-thickness:from-font;text-underline-offset:.2em}.c6055659b8e2cd2c__is-brand,.c6055659b8e2cd2c__is-brand:visited{--_gcd-a-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9))}.c6055659b8e2cd2c__is-brand:active,.c6055659b8e2cd2c__is-brand:hover{--_gcd-a-color:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));color:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000))}._92e0dfcaeee15b88__is-neutral,._92e0dfcaeee15b88__is-neutral:visited{--_gcd-a-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);text-decoration-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d)}._92e0dfcaeee15b88__is-neutral:active,._92e0dfcaeee15b88__is-neutral:hover{--_gcd-a-color:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);color:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e)}.cf122a9bf1035d42__is-unstyled{--_gcd-a-color:inherit;color:inherit;text-decoration:none}._0cb411afac4c86c7__link-icon{display:inline-block;font-weight:var(--wpds-typography-font-weight-default,400);line-height:1;margin-inline-start:var(--wpds-dimension-padding-xs,4px);text-decoration:none}._0cb411afac4c86c7__link-icon:after{content:"\\2197"}._0cb411afac4c86c7__link-icon:dir(rtl):after{content:"\\2196"}}}'); + registerStyle7("32aba35fe1", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._19ce0419607e1896__stack{display:flex}}}"); } -var style_default6 = { "link": "d4250949359b05ce__link", "is-brand": "c6055659b8e2cd2c__is-brand", "is-neutral": "_92e0dfcaeee15b88__is-neutral", "is-unstyled": "cf122a9bf1035d42__is-unstyled", "link-icon": "_0cb411afac4c86c7__link-icon" }; -if (typeof process === "undefined" || true) { - registerStyle7("af6d9984a6", "._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}"); -} -var global_css_defense_default2 = { "button": "_6defc79820e382c6__button", "input": "d2cff2e5dea83bd1__input", "textarea": "_547d86373d02e108__textarea", "div": "_8c15fd0ed9f28ba4__div", "p": "_43cec3e1eec1066d__p", "heading": "e97669c6d9a38497__heading", "a": "_2c0831b0499dbd6e__a" }; -var Link = (0, import_element19.forwardRef)(function Link2({ - children, - variant = "default", - tone = "brand", - openInNewTab = false, - render, - className, - ...props -}, ref) { +var style_default6 = { "stack": "_19ce0419607e1896__stack" }; +var gapTokens = { + xs: "var(--wpds-dimension-gap-xs, 4px)", + sm: "var(--wpds-dimension-gap-sm, 8px)", + md: "var(--wpds-dimension-gap-md, 12px)", + lg: "var(--wpds-dimension-gap-lg, 16px)", + xl: "var(--wpds-dimension-gap-xl, 24px)", + "2xl": "var(--wpds-dimension-gap-2xl, 32px)", + "3xl": "var(--wpds-dimension-gap-3xl, 40px)" +}; +var Stack = (0, import_element19.forwardRef)(function Stack2({ direction, gap, align, justify, wrap, render, ...props }, ref) { + const style = { + gap: gap && gapTokens[gap], + alignItems: align, + justifyContent: justify, + flexDirection: direction, + flexWrap: wrap + }; const element = useRender({ render, - defaultTagName: "a", ref, - props: mergeProps(props, { - className: clsx_default( - global_css_defense_default2.a, - resets_default2["box-sizing"], - focus_module_default["outset-ring--focus-except-active"], - variant !== "unstyled" && style_default6.link, - variant !== "unstyled" && style_default6[`is-${tone}`], - variant === "unstyled" && style_default6["is-unstyled"], - className - ), - target: openInNewTab ? "_blank" : void 0, - children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [ - children, - openInNewTab && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)( - "span", - { - className: style_default6["link-icon"], - role: "img", - "aria-label": ( - /* translators: accessibility text appended to link text */ - (0, import_i18n2.__)("(opens in a new tab)") - ) - } - ) - ] }) - }) + props: mergeProps(props, { style, className: style_default6.stack }) }); return element; }); @@ -10602,10 +10610,13 @@ function getResolvedValue(ruleValue, tree) { } const resolvedValue = getResolvedRefValue(ruleValue, tree); if (typeof resolvedValue === "object" && resolvedValue !== null && "url" in resolvedValue && resolvedValue?.url) { - resolvedValue.url = getResolvedThemeFilePath( - resolvedValue.url, - tree?._links?.["wp:theme-file"] - ); + return { + ...resolvedValue, + url: getResolvedThemeFilePath( + resolvedValue.url, + tree?._links?.["wp:theme-file"] + ) + }; } return resolvedValue; } @@ -10845,13 +10856,13 @@ function areGlobalStylesEqual(original, variation) { var import_deepmerge = __toESM(require_cjs(), 1); // node_modules/is-plain-object/dist/is-plain-object.mjs -function isObject(o3) { - return Object.prototype.toString.call(o3) === "[object Object]"; +function isObject(o2) { + return Object.prototype.toString.call(o2) === "[object Object]"; } -function isPlainObject(o3) { +function isPlainObject(o2) { var ctor, prot; - if (isObject(o3) === false) return false; - ctor = o3.constructor; + if (isObject(o2) === false) return false; + ctor = o2.constructor; if (ctor === void 0) return true; prot = ctor.prototype; if (isObject(prot) === false) return false; @@ -10893,11 +10904,11 @@ var r2 = { grad: 0.9, turn: 360, rad: 360 / (2 * Math.PI) }; var t = function(r3) { return "string" == typeof r3 ? r3.length > 0 : "number" == typeof r3; }; -var n = function(r3, t3, n2) { - return void 0 === t3 && (t3 = 0), void 0 === n2 && (n2 = Math.pow(10, t3)), Math.round(n2 * r3) / n2 + 0; +var n = function(r3, t2, n2) { + return void 0 === t2 && (t2 = 0), void 0 === n2 && (n2 = Math.pow(10, t2)), Math.round(n2 * r3) / n2 + 0; }; -var e = function(r3, t3, n2) { - return void 0 === t3 && (t3 = 0), void 0 === n2 && (n2 = 1), r3 > n2 ? n2 : r3 > t3 ? r3 : t3; +var e = function(r3, t2, n2) { + return void 0 === t2 && (t2 = 0), void 0 === n2 && (n2 = 1), r3 > n2 ? n2 : r3 > t2 ? r3 : t2; }; var u = function(r3) { return (r3 = isFinite(r3) ? r3 % 360 : 0) > 0 ? r3 : r3 + 360; @@ -10910,18 +10921,18 @@ var o = function(r3) { }; var i = /^#([0-9a-f]{3,8})$/i; var s = function(r3) { - var t3 = r3.toString(16); - return t3.length < 2 ? "0" + t3 : t3; + var t2 = r3.toString(16); + return t2.length < 2 ? "0" + t2 : t2; }; var h = function(r3) { - var t3 = r3.r, n2 = r3.g, e2 = r3.b, u2 = r3.a, a2 = Math.max(t3, n2, e2), o3 = a2 - Math.min(t3, n2, e2), i2 = o3 ? a2 === t3 ? (n2 - e2) / o3 : a2 === n2 ? 2 + (e2 - t3) / o3 : 4 + (t3 - n2) / o3 : 0; - return { h: 60 * (i2 < 0 ? i2 + 6 : i2), s: a2 ? o3 / a2 * 100 : 0, v: a2 / 255 * 100, a: u2 }; + var t2 = r3.r, n2 = r3.g, e2 = r3.b, u2 = r3.a, a2 = Math.max(t2, n2, e2), o2 = a2 - Math.min(t2, n2, e2), i2 = o2 ? a2 === t2 ? (n2 - e2) / o2 : a2 === n2 ? 2 + (e2 - t2) / o2 : 4 + (t2 - n2) / o2 : 0; + return { h: 60 * (i2 < 0 ? i2 + 6 : i2), s: a2 ? o2 / a2 * 100 : 0, v: a2 / 255 * 100, a: u2 }; }; var b = function(r3) { - var t3 = r3.h, n2 = r3.s, e2 = r3.v, u2 = r3.a; - t3 = t3 / 360 * 6, n2 /= 100, e2 /= 100; - var a2 = Math.floor(t3), o3 = e2 * (1 - n2), i2 = e2 * (1 - (t3 - a2) * n2), s2 = e2 * (1 - (1 - t3 + a2) * n2), h2 = a2 % 6; - return { r: 255 * [e2, i2, o3, o3, s2, e2][h2], g: 255 * [s2, e2, e2, i2, o3, o3][h2], b: 255 * [o3, o3, s2, e2, e2, i2][h2], a: u2 }; + var t2 = r3.h, n2 = r3.s, e2 = r3.v, u2 = r3.a; + t2 = t2 / 360 * 6, n2 /= 100, e2 /= 100; + var a2 = Math.floor(t2), o2 = e2 * (1 - n2), i2 = e2 * (1 - (t2 - a2) * n2), s2 = e2 * (1 - (1 - t2 + a2) * n2), h2 = a2 % 6; + return { r: 255 * [e2, i2, o2, o2, s2, e2][h2], g: 255 * [s2, e2, e2, i2, o2, o2][h2], b: 255 * [o2, o2, s2, e2, e2, i2][h2], a: u2 }; }; var g = function(r3) { return { h: u(r3.h), s: e(r3.s, 0, 100), l: e(r3.l, 0, 100), a: e(r3.a) }; @@ -10930,64 +10941,64 @@ var d = function(r3) { return { h: n(r3.h), s: n(r3.s), l: n(r3.l), a: n(r3.a, 3) }; }; var f = function(r3) { - return b((n2 = (t3 = r3).s, { h: t3.h, s: (n2 *= ((e2 = t3.l) < 50 ? e2 : 100 - e2) / 100) > 0 ? 2 * n2 / (e2 + n2) * 100 : 0, v: e2 + n2, a: t3.a })); - var t3, n2, e2; + return b((n2 = (t2 = r3).s, { h: t2.h, s: (n2 *= ((e2 = t2.l) < 50 ? e2 : 100 - e2) / 100) > 0 ? 2 * n2 / (e2 + n2) * 100 : 0, v: e2 + n2, a: t2.a })); + var t2, n2, e2; }; var c = function(r3) { - return { h: (t3 = h(r3)).h, s: (u2 = (200 - (n2 = t3.s)) * (e2 = t3.v) / 100) > 0 && u2 < 200 ? n2 * e2 / 100 / (u2 <= 100 ? u2 : 200 - u2) * 100 : 0, l: u2 / 2, a: t3.a }; - var t3, n2, e2, u2; + return { h: (t2 = h(r3)).h, s: (u2 = (200 - (n2 = t2.s)) * (e2 = t2.v) / 100) > 0 && u2 < 200 ? n2 * e2 / 100 / (u2 <= 100 ? u2 : 200 - u2) * 100 : 0, l: u2 / 2, a: t2.a }; + var t2, n2, e2, u2; }; var l = /^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s*,\s*([+-]?\d*\.?\d+)%\s*,\s*([+-]?\d*\.?\d+)%\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i; var p2 = /^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s+([+-]?\d*\.?\d+)%\s+([+-]?\d*\.?\d+)%\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i; var v = /^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i; var m = /^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i; var y = { string: [[function(r3) { - var t3 = i.exec(r3); - return t3 ? (r3 = t3[1]).length <= 4 ? { r: parseInt(r3[0] + r3[0], 16), g: parseInt(r3[1] + r3[1], 16), b: parseInt(r3[2] + r3[2], 16), a: 4 === r3.length ? n(parseInt(r3[3] + r3[3], 16) / 255, 2) : 1 } : 6 === r3.length || 8 === r3.length ? { r: parseInt(r3.substr(0, 2), 16), g: parseInt(r3.substr(2, 2), 16), b: parseInt(r3.substr(4, 2), 16), a: 8 === r3.length ? n(parseInt(r3.substr(6, 2), 16) / 255, 2) : 1 } : null : null; + var t2 = i.exec(r3); + return t2 ? (r3 = t2[1]).length <= 4 ? { r: parseInt(r3[0] + r3[0], 16), g: parseInt(r3[1] + r3[1], 16), b: parseInt(r3[2] + r3[2], 16), a: 4 === r3.length ? n(parseInt(r3[3] + r3[3], 16) / 255, 2) : 1 } : 6 === r3.length || 8 === r3.length ? { r: parseInt(r3.substr(0, 2), 16), g: parseInt(r3.substr(2, 2), 16), b: parseInt(r3.substr(4, 2), 16), a: 8 === r3.length ? n(parseInt(r3.substr(6, 2), 16) / 255, 2) : 1 } : null : null; }, "hex"], [function(r3) { - var t3 = v.exec(r3) || m.exec(r3); - return t3 ? t3[2] !== t3[4] || t3[4] !== t3[6] ? null : a({ r: Number(t3[1]) / (t3[2] ? 100 / 255 : 1), g: Number(t3[3]) / (t3[4] ? 100 / 255 : 1), b: Number(t3[5]) / (t3[6] ? 100 / 255 : 1), a: void 0 === t3[7] ? 1 : Number(t3[7]) / (t3[8] ? 100 : 1) }) : null; -}, "rgb"], [function(t3) { - var n2 = l.exec(t3) || p2.exec(t3); + var t2 = v.exec(r3) || m.exec(r3); + return t2 ? t2[2] !== t2[4] || t2[4] !== t2[6] ? null : a({ r: Number(t2[1]) / (t2[2] ? 100 / 255 : 1), g: Number(t2[3]) / (t2[4] ? 100 / 255 : 1), b: Number(t2[5]) / (t2[6] ? 100 / 255 : 1), a: void 0 === t2[7] ? 1 : Number(t2[7]) / (t2[8] ? 100 : 1) }) : null; +}, "rgb"], [function(t2) { + var n2 = l.exec(t2) || p2.exec(t2); if (!n2) return null; var e2, u2, a2 = g({ h: (e2 = n2[1], u2 = n2[2], void 0 === u2 && (u2 = "deg"), Number(e2) * (r2[u2] || 1)), s: Number(n2[3]), l: Number(n2[4]), a: void 0 === n2[5] ? 1 : Number(n2[5]) / (n2[6] ? 100 : 1) }); return f(a2); }, "hsl"]], object: [[function(r3) { - var n2 = r3.r, e2 = r3.g, u2 = r3.b, o3 = r3.a, i2 = void 0 === o3 ? 1 : o3; + var n2 = r3.r, e2 = r3.g, u2 = r3.b, o2 = r3.a, i2 = void 0 === o2 ? 1 : o2; return t(n2) && t(e2) && t(u2) ? a({ r: Number(n2), g: Number(e2), b: Number(u2), a: Number(i2) }) : null; }, "rgb"], [function(r3) { - var n2 = r3.h, e2 = r3.s, u2 = r3.l, a2 = r3.a, o3 = void 0 === a2 ? 1 : a2; + var n2 = r3.h, e2 = r3.s, u2 = r3.l, a2 = r3.a, o2 = void 0 === a2 ? 1 : a2; if (!t(n2) || !t(e2) || !t(u2)) return null; - var i2 = g({ h: Number(n2), s: Number(e2), l: Number(u2), a: Number(o3) }); + var i2 = g({ h: Number(n2), s: Number(e2), l: Number(u2), a: Number(o2) }); return f(i2); }, "hsl"], [function(r3) { - var n2 = r3.h, a2 = r3.s, o3 = r3.v, i2 = r3.a, s2 = void 0 === i2 ? 1 : i2; - if (!t(n2) || !t(a2) || !t(o3)) return null; + var n2 = r3.h, a2 = r3.s, o2 = r3.v, i2 = r3.a, s2 = void 0 === i2 ? 1 : i2; + if (!t(n2) || !t(a2) || !t(o2)) return null; var h2 = (function(r4) { return { h: u(r4.h), s: e(r4.s, 0, 100), v: e(r4.v, 0, 100), a: e(r4.a) }; - })({ h: Number(n2), s: Number(a2), v: Number(o3), a: Number(s2) }); + })({ h: Number(n2), s: Number(a2), v: Number(o2), a: Number(s2) }); return b(h2); }, "hsv"]] }; -var N = function(r3, t3) { - for (var n2 = 0; n2 < t3.length; n2++) { - var e2 = t3[n2][0](r3); - if (e2) return [e2, t3[n2][1]]; +var N = function(r3, t2) { + for (var n2 = 0; n2 < t2.length; n2++) { + var e2 = t2[n2][0](r3); + if (e2) return [e2, t2[n2][1]]; } return [null, void 0]; }; var x = function(r3) { return "string" == typeof r3 ? N(r3.trim(), y.string) : "object" == typeof r3 && null !== r3 ? N(r3, y.object) : [null, void 0]; }; -var M = function(r3, t3) { +var M = function(r3, t2) { var n2 = c(r3); - return { h: n2.h, s: e(n2.s + 100 * t3, 0, 100), l: n2.l, a: n2.a }; + return { h: n2.h, s: e(n2.s + 100 * t2, 0, 100), l: n2.l, a: n2.a }; }; var H = function(r3) { return (299 * r3.r + 587 * r3.g + 114 * r3.b) / 1e3 / 255; }; -var $ = function(r3, t3) { +var $ = function(r3, t2) { var n2 = c(r3); - return { h: n2.h, s: n2.s, l: e(n2.l + 100 * t3, 0, 100), a: n2.a }; + return { h: n2.h, s: n2.s, l: e(n2.l + 100 * t2, 0, 100), a: n2.a }; }; var j = (function() { function r3(r4) { @@ -11002,18 +11013,18 @@ var j = (function() { }, r3.prototype.isLight = function() { return H(this.rgba) >= 0.5; }, r3.prototype.toHex = function() { - return r4 = o(this.rgba), t3 = r4.r, e2 = r4.g, u2 = r4.b, i2 = (a2 = r4.a) < 1 ? s(n(255 * a2)) : "", "#" + s(t3) + s(e2) + s(u2) + i2; - var r4, t3, e2, u2, a2, i2; + return r4 = o(this.rgba), t2 = r4.r, e2 = r4.g, u2 = r4.b, i2 = (a2 = r4.a) < 1 ? s(n(255 * a2)) : "", "#" + s(t2) + s(e2) + s(u2) + i2; + var r4, t2, e2, u2, a2, i2; }, r3.prototype.toRgb = function() { return o(this.rgba); }, r3.prototype.toRgbString = function() { - return r4 = o(this.rgba), t3 = r4.r, n2 = r4.g, e2 = r4.b, (u2 = r4.a) < 1 ? "rgba(" + t3 + ", " + n2 + ", " + e2 + ", " + u2 + ")" : "rgb(" + t3 + ", " + n2 + ", " + e2 + ")"; - var r4, t3, n2, e2, u2; + return r4 = o(this.rgba), t2 = r4.r, n2 = r4.g, e2 = r4.b, (u2 = r4.a) < 1 ? "rgba(" + t2 + ", " + n2 + ", " + e2 + ", " + u2 + ")" : "rgb(" + t2 + ", " + n2 + ", " + e2 + ")"; + var r4, t2, n2, e2, u2; }, r3.prototype.toHsl = function() { return d(c(this.rgba)); }, r3.prototype.toHslString = function() { - return r4 = d(c(this.rgba)), t3 = r4.h, n2 = r4.s, e2 = r4.l, (u2 = r4.a) < 1 ? "hsla(" + t3 + ", " + n2 + "%, " + e2 + "%, " + u2 + ")" : "hsl(" + t3 + ", " + n2 + "%, " + e2 + "%)"; - var r4, t3, n2, e2, u2; + return r4 = d(c(this.rgba)), t2 = r4.h, n2 = r4.s, e2 = r4.l, (u2 = r4.a) < 1 ? "hsla(" + t2 + ", " + n2 + "%, " + e2 + "%, " + u2 + ")" : "hsl(" + t2 + ", " + n2 + "%, " + e2 + "%)"; + var r4, t2, n2, e2, u2; }, r3.prototype.toHsv = function() { return r4 = h(this.rgba), { h: n(r4.h), s: n(r4.s), v: n(r4.v), a: n(r4.a, 3) }; var r4; @@ -11033,11 +11044,11 @@ var j = (function() { }, r3.prototype.rotate = function(r4) { return void 0 === r4 && (r4 = 15), this.hue(this.hue() + r4); }, r3.prototype.alpha = function(r4) { - return "number" == typeof r4 ? w({ r: (t3 = this.rgba).r, g: t3.g, b: t3.b, a: r4 }) : n(this.rgba.a, 3); - var t3; + return "number" == typeof r4 ? w({ r: (t2 = this.rgba).r, g: t2.g, b: t2.b, a: r4 }) : n(this.rgba.a, 3); + var t2; }, r3.prototype.hue = function(r4) { - var t3 = c(this.rgba); - return "number" == typeof r4 ? w({ h: r4, s: t3.s, l: t3.l, a: t3.a }) : n(t3.h); + var t2 = c(this.rgba); + return "number" == typeof r4 ? w({ h: r4, s: t2.s, l: t2.l, a: t2.a }) : n(t2.h); }, r3.prototype.isEqual = function(r4) { return this.toHex() === w(r4).toHex(); }, r3; @@ -11045,12 +11056,6 @@ var j = (function() { var w = function(r3) { return r3 instanceof j ? r3 : new j(r3); }; -var S = []; -var k = function(r3) { - r3.forEach(function(r4) { - S.indexOf(r4) < 0 && (r4(j, y), S.push(r4)); - }); -}; // packages/global-styles-engine/build-module/utils/duotone.mjs function getValuesFromColors(colors = []) { @@ -11650,28 +11655,6 @@ var import_components3 = __toESM(require_components(), 1); var import_i18n6 = __toESM(require_i18n(), 1); var import_block_editor = __toESM(require_block_editor(), 1); -// node_modules/colord/plugins/a11y.mjs -var o2 = function(o3) { - var t3 = o3 / 255; - return t3 < 0.04045 ? t3 / 12.92 : Math.pow((t3 + 0.055) / 1.055, 2.4); -}; -var t2 = function(t3) { - return 0.2126 * o2(t3.r) + 0.7152 * o2(t3.g) + 0.0722 * o2(t3.b); -}; -function a11y_default(o3) { - o3.prototype.luminance = function() { - return o4 = t2(this.rgba), void 0 === (r3 = 2) && (r3 = 0), void 0 === n2 && (n2 = Math.pow(10, r3)), Math.round(n2 * o4) / n2 + 0; - var o4, r3, n2; - }, o3.prototype.contrast = function(r3) { - void 0 === r3 && (r3 = "#FFF"); - var n2, a2, i2, e2, v2, u2, d2, c2 = r3 instanceof o3 ? r3 : new o3(r3); - return e2 = this.rgba, v2 = c2.toRgb(), u2 = t2(e2), d2 = t2(v2), n2 = u2 > d2 ? (u2 + 0.05) / (d2 + 0.05) : (d2 + 0.05) / (u2 + 0.05), void 0 === (a2 = 2) && (a2 = 0), void 0 === i2 && (i2 = Math.pow(10, a2)), Math.floor(i2 * n2) / i2 + 0; - }, o3.prototype.isReadable = function(o4, t3) { - return void 0 === o4 && (o4 = "#FFF"), void 0 === t3 && (t3 = {}), this.contrast(o4) >= (e2 = void 0 === (i2 = (r3 = t3).size) ? "normal" : i2, "AAA" === (a2 = void 0 === (n2 = r3.level) ? "AA" : n2) && "normal" === e2 ? 7 : "AA" === a2 && "large" === e2 ? 3 : 4.5); - var r3, n2, a2, i2, e2; - }; -} - // packages/global-styles-ui/build-module/hooks.mjs var import_element24 = __toESM(require_element(), 1); var import_data = __toESM(require_data(), 1); @@ -11805,7 +11788,6 @@ function getFontFamilies(themeJson) { } // packages/global-styles-ui/build-module/hooks.mjs -k([a11y_default]); function useStyle(path, blockName, readFrom = "merged", shouldDecodeEncode = true, state) { const { user, base, merged, onChange } = (0, import_element24.useContext)(GlobalStylesContext); const statePathParts = state?.split(".").filter(Boolean) ?? []; @@ -12010,7 +11992,7 @@ function resolveFontWeight(fontWeight) { return String(Math.min(Math.max(400, start), end)); } function formatFontFamily(input) { - const regex = /^(?!generic\([ a-zA-Z\-]+\)$)(?!^[a-zA-Z\-]+$).+/; + const regex = /^(?!generic\([ a-zA-Z\-]+\)$)(?!var\(\s*--[\w-]+\s*\)$)(?!^[a-zA-Z\-]+$).+/; const output = input.trim(); const formatItem = (item) => { item = item.trim(); @@ -12922,12 +12904,12 @@ async function fetchInstallFontFace(fontFamilyId, data, registry) { // node_modules/tslib/tslib.es6.mjs var __assign = function() { - __assign = Object.assign || function __assign2(t3) { + __assign = Object.assign || function __assign2(t2) { for (var s2, i2 = 1, n2 = arguments.length; i2 < n2; i2++) { s2 = arguments[i2]; - for (var p3 in s2) if (Object.prototype.hasOwnProperty.call(s2, p3)) t3[p3] = s2[p3]; + for (var p3 in s2) if (Object.prototype.hasOwnProperty.call(s2, p3)) t2[p3] = s2[p3]; } - return t3; + return t2; }; return __assign.apply(this, arguments); }; @@ -13305,7 +13287,8 @@ function FontLibraryProvider({ children }) { const globalStyles = (0, import_core_data5.useEntityRecord)( "root", "globalStyles", - globalStylesId + globalStylesId ?? 0, + { enabled: globalStylesId !== void 0 } ); const [isInstalling, setIsInstalling] = (0, import_element31.useState)(false); const { records: libraryPosts = [], isResolving: isResolvingLibrary } = (0, import_core_data5.useEntityRecords)( @@ -13934,7 +13917,8 @@ function InstalledFonts() { const globalStyles = (0, import_core_data6.useEntityRecord)( "root", "globalStyles", - globalStylesId + globalStylesId ?? 0, + { enabled: globalStylesId !== void 0 } ); const editedFontFamilies = globalStyles?.edits?.settings?.typography?.fontFamilies; const savedFontFamilies = globalStyles?.record?.settings?.typography?.fontFamilies; @@ -14903,8 +14887,8 @@ var __require2 = /* @__PURE__ */ ((x2) => typeof __require !== "undefined" ? __r var unbrotli_default = (function() { var define, module, exports; return (/* @__PURE__ */ (function() { - function r3(e2, n2, t3) { - function o3(i22, f2) { + function r3(e2, n2, t2) { + function o2(i22, f2) { if (!n2[i22]) { if (!e2[i22]) { var c2 = "function" == typeof __require2 && __require2; @@ -14918,21 +14902,21 @@ var unbrotli_default = (function() { p3.exports, function(r22) { var n22 = e2[i22][1][r22]; - return o3(n22 || r22); + return o2(n22 || r22); }, p3, p3.exports, r3, e2, n2, - t3 + t2 ); } return n2[i22].exports; } - for (var u2 = "function" == typeof __require2 && __require2, i2 = 0; i2 < t3.length; i2++) - o3(t3[i2]); - return o3; + for (var u2 = "function" == typeof __require2 && __require2, i2 = 0; i2 < t2.length; i2++) + o2(t2[i2]); + return o2; } return r3; })())( @@ -18508,8 +18492,8 @@ var unbrotli_default = (function() { exports2.transformDictionaryWord = function(dst, idx, word, len, transform) { var prefix = kTransforms[transform].prefix; var suffix = kTransforms[transform].suffix; - var t3 = kTransforms[transform].transform; - var skip = t3 < kOmitFirst1 ? 0 : t3 - (kOmitFirst1 - 1); + var t2 = kTransforms[transform].transform; + var skip = t2 < kOmitFirst1 ? 0 : t2 - (kOmitFirst1 - 1); var i2 = 0; var start_idx = idx; var uppercase; @@ -18522,16 +18506,16 @@ var unbrotli_default = (function() { } word += skip; len -= skip; - if (t3 <= kOmitLast9) { - len -= t3; + if (t2 <= kOmitLast9) { + len -= t2; } for (i2 = 0; i2 < len; i2++) { dst[idx++] = BrotliDictionary.dictionary[word + i2]; } uppercase = idx - len; - if (t3 === kUppercaseFirst) { + if (t2 === kUppercaseFirst) { ToUpperCase(dst, uppercase); - } else if (t3 === kUppercaseAll) { + } else if (t2 === kUppercaseAll) { while (len > 0) { var step = ToUpperCase(dst, uppercase); uppercase += step; @@ -18569,8 +18553,8 @@ var __require3 = /* @__PURE__ */ ((x2) => typeof __require !== "undefined" ? __r var inflate_default = (function() { var define, module, exports; return (/* @__PURE__ */ (function() { - function r3(e2, n2, t3) { - function o3(i22, f2) { + function r3(e2, n2, t2) { + function o2(i22, f2) { if (!n2[i22]) { if (!e2[i22]) { var c2 = "function" == typeof __require3 && __require3; @@ -18584,21 +18568,21 @@ var inflate_default = (function() { p3.exports, function(r22) { var n22 = e2[i22][1][r22]; - return o3(n22 || r22); + return o2(n22 || r22); }, p3, p3.exports, r3, e2, n2, - t3 + t2 ); } return n2[i22].exports; } - for (var u2 = "function" == typeof __require3 && __require3, i2 = 0; i2 < t3.length; i2++) - o3(t3[i2]); - return o3; + for (var u2 = "function" == typeof __require3 && __require3, i2 = 0; i2 < t2.length; i2++) + o2(t2[i2]); + return o2; } return r3; })())( @@ -18918,7 +18902,7 @@ var inflate_default = (function() { var c2, table = []; for (var n2 = 0; n2 < 256; n2++) { c2 = n2; - for (var k2 = 0; k2 < 8; k2++) { + for (var k = 0; k < 8; k++) { c2 = c2 & 1 ? 3988292384 ^ c2 >>> 1 : c2 >>> 1; } table[n2] = c2; @@ -18927,10 +18911,10 @@ var inflate_default = (function() { } var crcTable = makeTable(); function crc32(crc, buf, len, pos) { - var t3 = crcTable, end = pos + len; + var t2 = crcTable, end = pos + len; crc ^= -1; for (var i2 = pos; i2 < end; i2++) { - crc = crc >>> 8 ^ t3[(crc ^ buf[i2]) & 255]; + crc = crc >>> 8 ^ t2[(crc ^ buf[i2]) & 255]; } return crc ^ -1; } @@ -21287,12 +21271,12 @@ var Parser = class { console.trace(); } get tag() { - const t3 = this.uint32; + const t2 = this.uint32; return asText([ - t3 >> 24 & 255, - t3 >> 16 & 255, - t3 >> 8 & 255, - t3 & 255 + t2 >> 24 & 255, + t2 >> 16 & 255, + t2 >> 8 & 255, + t2 & 255 ]); } get fixed() { @@ -22493,23 +22477,23 @@ var cmap = class extends SimpleTable { getGlyphId(char) { let last = 0; this.encodingRecords.some((_, tableID) => { - let t3 = this.getSubTable(tableID); - if (!t3.getGlyphId) return false; - last = t3.getGlyphId(char); + let t2 = this.getSubTable(tableID); + if (!t2.getGlyphId) return false; + last = t2.getGlyphId(char); return last !== 0; }); return last; } supports(char) { return this.encodingRecords.some((_, tableID) => { - const t3 = this.getSubTable(tableID); - return t3.supports && t3.supports(char) !== false; + const t2 = this.getSubTable(tableID); + return t2.supports && t2.supports(char) !== false; }); } supportsVariation(variation) { return this.encodingRecords.some((_, tableID) => { - const t3 = this.getSubTable(tableID); - return t3.supportsVariation && t3.supportsVariation(variation) !== false; + const t2 = this.getSubTable(tableID); + return t2.supportsVariation && t2.supportsVariation(variation) !== false; }); } }; @@ -25558,7 +25542,6 @@ var import_core_data11 = __toESM(require_core_data(), 1); var import_data11 = __toESM(require_data(), 1); var import_keycodes2 = __toESM(require_keycodes(), 1); var import_jsx_runtime92 = __toESM(require_jsx_runtime(), 1); -var { Badge: WCBadge } = unlock3(import_components51.privateApis); var DAY_IN_MILLISECONDS = 60 * 60 * 1e3 * 24; // packages/global-styles-ui/build-module/pagination/index.mjs @@ -25662,10 +25645,10 @@ var { unlock: unlock4 } = (0, import_private_apis5.__dangerousOptInToUnstableAPI ); // routes/font-list/style.scss -if (typeof document !== "undefined" && true && !document.head.querySelector("style[data-wp-hash='8316bac515']")) { +if (typeof document !== "undefined" && true && !document.head.querySelector("style[data-wp-hash='cb0e994672']")) { const style = document.createElement("style"); - style.setAttribute("data-wp-hash", "8316bac515"); - style.appendChild(document.createTextNode('@media (min-width:782px){.font-library-modal.font-library-modal{width:65vw}}.font-library-modal .components-modal__header{border-bottom:none}.font-library-modal .components-modal__content{margin-bottom:90px;padding:0}.font-library-modal .font-library__subtitle{font-size:11px;font-weight:var(--wpds-typography-font-weight-emphasis,600);text-transform:uppercase}.font-library-modal__tab-panel{height:calc(100% - 50px)}.font-library__tabpanel-layout{display:flex;flex-direction:column;height:100%}.font-library__tabpanel-layout>div{flex-grow:1}.font-library__tabpanel-layout .font-library__loading{align-items:center;box-sizing:border-box;display:flex;height:100%;justify-content:center;left:0;padding-top:124px;position:absolute;top:0;width:100%}.font-library__footer,.font-library__tabpanel-layout .components-navigator-screen{padding:24px;width:100%}.font-library__footer{background-color:#fff;border-top:1px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);bottom:0;box-sizing:border-box;flex-grow:0!important;flex-shrink:0;height:90px;position:absolute}.font-library__page-selection{font-size:11px;font-weight:var(--wpds-typography-font-weight-emphasis,600);text-transform:uppercase}@media (min-width:600px){.font-library__page-selection .components-select-control__input{font-size:11px!important;font-weight:var(--wpds-typography-font-weight-emphasis,600)}}.font-library__search{width:240px}.font-library__fonts-title{font-size:11px;font-weight:var(--wpds-typography-font-weight-emphasis,600);margin-bottom:0;margin-top:0;text-transform:uppercase}.font-library__fonts-list{list-style:none;margin-bottom:0;margin-top:0;padding:0}.font-library__fonts-list-item{margin-bottom:0}.font-library__font-demo{position:relative}.font-library__font-card{border:1px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);box-sizing:border-box;height:auto!important;margin-top:-1px;padding:16px;width:100%}.font-library__font-card:hover{background-color:#f0f0f0}.font-library__font-card:focus{position:relative}.font-library__font-card .font-library__font-card__name{font-weight:700}.font-library__font-card .font-library__font-card__count{color:#757575}.font-library__font-card .font-library__font-variant_demo-image{display:block;height:24px;width:auto}@media not (prefers-reduced-motion){.font-library__font-card .font-library__font-variant_demo-image{transition:opacity var(--wpds-motion-duration-lg,.3s) var(--wpds-motion-easing-subtle,cubic-bezier(.15,0,.15,1))}}.font-library__font-card .font-library__font-variant_demo-image.is-loading{left:0;opacity:0;position:absolute;top:0}.font-library__font-card .font-library__font-variant-demo-skeleton{border-radius:var(--wpds-border-radius-sm,2px);height:24px}.font-library__font-card .font-library__font-variant_demo-text{flex-shrink:0;white-space:nowrap}@media not (prefers-reduced-motion){.font-library__font-card .font-library__font-variant_demo-text{transition:opacity .3s ease-in-out}}.font-library-modal__tablist-container{background:#fff;border-bottom:1px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);position:sticky;top:0;z-index:1}.font-library__upload-area{align-items:center;display:flex;height:256px!important;justify-content:center;width:100%}button.font-library__upload-area{background-color:#f0f0f0}.font-library__local-fonts{margin:24px auto;width:80%}.font-library__local-fonts .font-library__upload-area__text{color:#757575}.font-library__google-fonts-confirm{align-items:center;display:flex;justify-content:center;margin-top:64px}.font-library__google-fonts-confirm p{line-height:1.4}.font-library__google-fonts-confirm h2{font-size:1.2rem;font-weight:400}.font-library__google-fonts-confirm .components-card{padding:16px;width:400px}.font-library__google-fonts-confirm .components-button{justify-content:center;width:100%}.font-library__select-all{padding:16px 16px 16px 17px}.font-library__select-all .components-checkbox-control__label{padding-left:16px}.global-styles-ui-pagination .components-button.is-tertiary{height:32px;justify-content:center;width:32px}.global-styles-ui-screen-revisions__revisions-list{flex-grow:1;list-style:none;margin:0 16px 16px}.global-styles-ui-screen-revisions__revisions-list li{margin-bottom:0}.global-styles-ui-screen-revisions__revision-item{cursor:var(--wpds-cursor-control,pointer);display:flex;flex-direction:column;position:relative}.global-styles-ui-screen-revisions__revision-item[role=option]:active,.global-styles-ui-screen-revisions__revision-item[role=option]:focus{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid transparent}.global-styles-ui-screen-revisions__revision-item:hover{background:rgba(var(--wp-admin-theme-color--rgb),.04)}.global-styles-ui-screen-revisions__revision-item:hover .global-styles-ui-screen-revisions__date{color:var(--wp-admin-theme-color)}.global-styles-ui-screen-revisions__revision-item:after,.global-styles-ui-screen-revisions__revision-item:before{content:"\\a";display:block;position:absolute}.global-styles-ui-screen-revisions__revision-item:before{background:#ddd;border:4px solid transparent;border-radius:50%;height:8px;left:17px;top:18px;transform:translate(-50%,-50%);width:8px;z-index:1}.global-styles-ui-screen-revisions__revision-item[aria-selected=true]{background:rgba(var(--wp-admin-theme-color--rgb),.04);border-radius:2px;color:var(--wp-admin-theme-color);outline:3px solid transparent;outline-offset:-2px}.global-styles-ui-screen-revisions__revision-item[aria-selected=true] .global-styles-ui-screen-revisions__date{color:var(--wp-admin-theme-color)}.global-styles-ui-screen-revisions__revision-item[aria-selected=true]:before{background:var(--wp-admin-theme-color)}.global-styles-ui-screen-revisions__revision-item[aria-selected=true] .global-styles-ui-screen-revisions__changes>li,.global-styles-ui-screen-revisions__revision-item[aria-selected=true] .global-styles-ui-screen-revisions__meta{color:#1e1e1e}.global-styles-ui-screen-revisions__revision-item:after{border:.5px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);height:100%;left:16px;top:0;width:0}.global-styles-ui-screen-revisions__revision-item:first-child:after{top:18px}.global-styles-ui-screen-revisions__revision-item:last-child:after{height:18px}.global-styles-ui-screen-revisions__revision-item-wrapper{display:block;padding:12px 12px 4px 40px}.global-styles-ui-screen-revisions__active-badge,.global-styles-ui-screen-revisions__apply-button.is-primary{align-self:flex-start;margin:0 12px 12px 40px}.global-styles-ui-screen-revisions__changes,.global-styles-ui-screen-revisions__meta{color:#757575;font-size:12px}.global-styles-ui-screen-revisions__description{align-items:flex-start;display:flex;flex-direction:column;gap:8px}.global-styles-ui-screen-revisions__description .global-styles-ui-screen-revisions__date{font-size:12px;font-weight:var(--wpds-typography-font-weight-emphasis,600);text-transform:uppercase}.global-styles-ui-screen-revisions__meta{align-items:flex-start;display:flex;justify-content:start;margin-bottom:4px;text-align:left;width:100%}.global-styles-ui-screen-revisions__meta img{border-radius:100%;height:16px;margin-right:8px;width:16px}.global-styles-ui-screen-revisions__loading{margin:24px auto!important}.global-styles-ui-screen-revisions__changes{line-height:1.4;list-style:disc;margin-left:12px;text-align:left}.global-styles-ui-screen-revisions__changes li{margin-bottom:4px}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination{gap:2px;justify-content:space-between}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .edit-site-pagination__total{height:1px;left:-1000px;margin:-1px;overflow:hidden;position:absolute}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-text{font-size:12px;will-change:opacity}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-button.is-tertiary{color:#1e1e1e}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-button.is-tertiary:disabled,.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-button.is-tertiary[aria-disabled=true]{color:#949494}.global-styles-ui-screen-revisions__footer{background:#fff;border-top:1px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);bottom:0;box-sizing:border-box;height:56px;min-width:100%;padding:12px;position:sticky;z-index:1}.global-styles-ui-variations_item{box-sizing:border-box;cursor:var(--wpds-cursor-control,pointer)}.global-styles-ui-variations_item .global-styles-ui-variations_item-preview{border-radius:2px;outline:1px solid rgba(0,0,0,.1);outline-offset:-1px;overflow:hidden;position:relative}@media not (prefers-reduced-motion){.global-styles-ui-variations_item .global-styles-ui-variations_item-preview{transition:outline .1s linear}}.global-styles-ui-variations_item .global-styles-ui-variations_item-preview.is-pill{height:32px}.global-styles-ui-variations_item .global-styles-ui-variations_item-preview.is-pill .block-editor-iframe__scale-container{overflow:hidden}.global-styles-ui-variations_item:not(.is-active):hover .global-styles-ui-variations_item-preview{outline-color:rgba(0,0,0,.3)}.global-styles-ui-variations_item.is-active .global-styles-ui-variations_item-preview,.global-styles-ui-variations_item:focus-visible .global-styles-ui-variations_item-preview{outline-color:#1e1e1e;outline-offset:1px;outline-width:var(--wp-admin-border-width-focus)}.global-styles-ui-variations_item:focus-visible .global-styles-ui-variations_item-preview{outline-color:var(--wp-admin-theme-color)}.global-styles-ui-preview__wrapper{display:block;max-width:100%;width:100%}.global-styles-ui-preview__wrapper.is-hoverable{cursor:var(--wpds-cursor-control,pointer)}.global-styles-ui-typography-preview{align-items:center;background:#f0f0f0;border-radius:2px;display:flex;justify-content:center;margin-bottom:20px;min-height:100px;overflow:hidden}.global-styles-ui-font-size__item{line-break:anywhere;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.global-styles-ui-font-size__item-value{color:#757575}.global-styles-ui-screen-typography__indicator{align-items:center;border-radius:2px;display:flex!important;font-size:14px;height:24px;justify-content:center;width:24px}.global-styles-ui-block-types-filter{margin-bottom:12px;padding:0 16px}.global-styles-ui-block-types-search{flex-grow:1}.global-styles-ui-block-types-item-list .global-styles-ui-block-types-item__icon{min-width:24px}.global-styles-ui-block-types-item-list__no-results{padding-top:16px}.global-styles-ui-block-types-item__indicator{background:var(--wp-admin-theme-color);border-radius:50%;flex:none;height:6px;margin-left:auto;width:6px}.global-styles-ui-screen-typography__font-variants-count{color:#757575}.global-styles-ui-font-families__manage-fonts{justify-content:center}.global-styles-ui-screen .color-block-support-panel{border-top:none;padding-left:0;padding-right:0;padding-top:0;row-gap:12px}.global-styles-ui-header{line-height:1.9!important;margin-bottom:0!important}.global-styles-ui-subtitle{font-size:11px!important;font-weight:var(--wpds-typography-font-weight-emphasis,600)!important;margin-bottom:0!important;text-transform:uppercase}.global-styles-ui-section-title{color:#2f2f2f;font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:1.2;margin:0;padding:16px 16px 0}.global-styles-ui-icon-with-current-color{fill:currentColor}.global-styles-ui__color-indicator-wrapper{flex-shrink:0;height:24px}.global-styles-ui__shadows-panel__options-container,.global-styles-ui__typography-panel__options-container{height:24px}.global-styles-ui__block-preview-panel{border:1px solid #ddd;border-radius:2px;overflow:hidden;position:relative;width:100%}.global-styles-ui__shadow-preview-panel{background-image:repeating-linear-gradient(45deg,#e0e0e0 25%,transparent 0,transparent 75%,#e0e0e0 0,#e0e0e0),repeating-linear-gradient(45deg,#e0e0e0 25%,transparent 0,transparent 75%,#e0e0e0 0,#e0e0e0);background-position:0 0,8px 8px;background-size:16px 16px;border:1px solid #ddd;border-radius:2px;height:144px;overflow:auto}.global-styles-ui__shadow-preview-panel .global-styles-ui__shadow-preview-block{background-color:#fff;border:1px solid #ddd;border-radius:2px;height:60px;width:60%}.global-styles-ui__shadow-editor__dropdown-content{width:280px}.global-styles-ui__shadow-editor-panel{margin-bottom:4px}.global-styles-ui__shadow-editor__dropdown{position:relative;width:100%}.global-styles-ui__shadow-editor__dropdown-toggle{border-radius:inherit;height:auto;padding-bottom:8px;padding-top:8px;text-align:left;width:100%}.global-styles-ui__shadow-editor__dropdown-toggle.is-open{background:#f0f0f0;color:var(--wp-admin-theme-color)}.global-styles-ui__shadow-editor__remove-button{opacity:0;position:absolute;right:8px;top:8px}.global-styles-ui__shadow-editor__dropdown-toggle:hover+.global-styles-ui__shadow-editor__remove-button,.global-styles-ui__shadow-editor__remove-button:focus,.global-styles-ui__shadow-editor__remove-button:hover{opacity:1}@media (hover:none){.global-styles-ui__shadow-editor__remove-button{opacity:1}}.global-styles-ui-screen-css{display:flex;flex:1 1 auto;flex-direction:column;margin:16px}.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel{flex:1 1 auto}.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel__custom-css-input,.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel__custom-css-input .components-base-control__field{display:flex;flex:1 1 auto;flex-direction:column}.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel__custom-css-input textarea{flex:1 1 auto}.global-styles-ui-screen-css-help-link{display:inline-block;margin-top:8px}.global-styles-ui-screen-variations{border-top:1px solid #ddd;margin-top:16px}.global-styles-ui-screen-variations>*{margin:24px 16px}.global-styles-ui-sidebar__navigator-provider{height:100%}.global-styles-ui-sidebar__navigator-screen{display:flex;flex-direction:column;height:100%}.global-styles-ui-color-palette__tablist-container{border-bottom:1px solid #ddd}.global-styles-ui-color-palette__tablist{margin-bottom:-1px}.global-styles-ui-sidebar__navigator-screen .single-column{grid-column:span 1}.global-styles-ui-screen-root.global-styles-ui-screen-root,.global-styles-ui-screen-style-variations.global-styles-ui-screen-style-variations{background:unset;color:inherit}.global-styles-ui-sidebar__panel .block-editor-block-icon svg{fill:currentColor}.global-styles-ui-screen-root__active-style-tile.global-styles-ui-screen-root__active-style-tile,.global-styles-ui-screen-root__active-style-tile.global-styles-ui-screen-root__active-style-tile .global-styles-ui-screen-root__active-style-tile-preview{border-radius:2px}.global-styles-ui-screen-root__active-style-tile-preview{clip-path:border-box}.global-styles-ui-color-palette-panel,.global-styles-ui-duotone-palette-panel,.global-styles-ui-gradient-palette-panel{padding:16px}.font-library-page__tablist{border-bottom:1px solid #f0f0f0;padding:0 24px}.font-library-page__tab-panel{flex-grow:1;max-height:calc(100% - 110px);overflow:auto}.font-library-page:has(.font-library__footer) .font-library-page__tab-panel{max-height:calc(100% - 198px)}')); + style.setAttribute("data-wp-hash", "cb0e994672"); + style.appendChild(document.createTextNode('@media (min-width:782px){.font-library-modal.font-library-modal{width:65vw}}.font-library-modal .components-modal__header{border-bottom:none}.font-library-modal .components-modal__content{margin-bottom:90px;padding:0}.font-library-modal .font-library__subtitle{font-size:11px;font-weight:var(--wpds-typography-font-weight-emphasis,600);text-transform:uppercase}.font-library-modal__tab-panel{height:calc(100% - 50px)}.font-library__tabpanel-layout{display:flex;flex-direction:column;height:100%}.font-library__tabpanel-layout>div{flex-grow:1}.font-library__tabpanel-layout .font-library__loading{align-items:center;box-sizing:border-box;display:flex;height:100%;justify-content:center;left:0;padding-top:124px;position:absolute;top:0;width:100%}.font-library__footer,.font-library__tabpanel-layout .components-navigator-screen{padding:24px;width:100%}.font-library__footer{background-color:#fff;border-top:1px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);bottom:0;box-sizing:border-box;flex-grow:0!important;flex-shrink:0;height:90px;position:absolute}.font-library__page-selection{font-size:11px;font-weight:var(--wpds-typography-font-weight-emphasis,600);text-transform:uppercase}@media (min-width:600px){.font-library__page-selection .components-select-control__input{font-size:11px!important;font-weight:var(--wpds-typography-font-weight-emphasis,600)}}.font-library__search{width:240px}.font-library__fonts-title{font-size:11px;font-weight:var(--wpds-typography-font-weight-emphasis,600);margin-bottom:0;margin-top:0;text-transform:uppercase}.font-library__fonts-list{list-style:none;margin-bottom:0;margin-top:0;padding:0}.font-library__fonts-list-item{margin-bottom:0}.font-library__font-demo{position:relative}.font-library__font-card{border:1px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);box-sizing:border-box;height:auto!important;margin-top:-1px;padding:16px;width:100%}.font-library__font-card:hover{background-color:#f0f0f0}.font-library__font-card:focus{position:relative}.font-library__font-card .font-library__font-card__name{font-weight:700}.font-library__font-card .font-library__font-card__count{color:#757575}.font-library__font-card .font-library__font-variant_demo-image{display:block;height:24px;width:auto}@media not (prefers-reduced-motion){.font-library__font-card .font-library__font-variant_demo-image{transition:opacity var(--wpds-motion-duration-lg,.3s) var(--wpds-motion-easing-subtle,cubic-bezier(.15,0,.15,1))}}.font-library__font-card .font-library__font-variant_demo-image.is-loading{left:0;opacity:0;position:absolute;top:0}.font-library__font-card .font-library__font-variant-demo-skeleton{border-radius:var(--wpds-border-radius-sm,2px);height:24px}.font-library__font-card .font-library__font-variant_demo-text{flex-shrink:0;white-space:nowrap}@media not (prefers-reduced-motion){.font-library__font-card .font-library__font-variant_demo-text{transition:opacity .3s ease-in-out}}.font-library-modal__tablist-container{background:#fff;border-bottom:1px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);position:sticky;top:0;z-index:1}.font-library__upload-area{align-items:center;display:flex;height:256px!important;justify-content:center;width:100%}button.font-library__upload-area{background-color:#f0f0f0}.font-library__local-fonts{margin:24px auto;width:80%}.font-library__local-fonts .font-library__upload-area__text{color:#757575}.font-library__google-fonts-confirm{align-items:center;display:flex;justify-content:center;margin-top:64px}.font-library__google-fonts-confirm p{line-height:1.4}.font-library__google-fonts-confirm h2{font-size:1.2rem;font-weight:400}.font-library__google-fonts-confirm .components-card{padding:16px;width:400px}.font-library__google-fonts-confirm .components-button{justify-content:center;width:100%}.font-library__select-all{padding:16px 16px 16px 17px}.font-library__select-all .components-checkbox-control__label{padding-left:16px}.global-styles-ui-pagination .components-button.is-tertiary{height:32px;justify-content:center;width:32px}.global-styles-ui-screen-revisions__revisions-list{flex-grow:1;list-style:none;margin:0 16px 16px}.global-styles-ui-screen-revisions__revisions-list li{margin-bottom:0}.global-styles-ui-screen-revisions__revision-item{cursor:var(--wpds-cursor-control,pointer);display:flex;flex-direction:column;position:relative}.global-styles-ui-screen-revisions__revision-item[role=option]:active,.global-styles-ui-screen-revisions__revision-item[role=option]:focus{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid transparent}.global-styles-ui-screen-revisions__revision-item:hover{background:rgba(var(--wp-admin-theme-color--rgb),.04)}.global-styles-ui-screen-revisions__revision-item:hover .global-styles-ui-screen-revisions__date{color:var(--wp-admin-theme-color)}.global-styles-ui-screen-revisions__revision-item:after,.global-styles-ui-screen-revisions__revision-item:before{content:"\\a";display:block;position:absolute}.global-styles-ui-screen-revisions__revision-item:before{background:#ddd;border:4px solid transparent;border-radius:50%;height:8px;left:17px;top:18px;transform:translate(-50%,-50%);width:8px;z-index:1}.global-styles-ui-screen-revisions__revision-item[aria-selected=true]{background:rgba(var(--wp-admin-theme-color--rgb),.04);border-radius:2px;color:var(--wp-admin-theme-color);outline:3px solid transparent;outline-offset:-2px}.global-styles-ui-screen-revisions__revision-item[aria-selected=true] .global-styles-ui-screen-revisions__date{color:var(--wp-admin-theme-color)}.global-styles-ui-screen-revisions__revision-item[aria-selected=true]:before{background:var(--wp-admin-theme-color)}.global-styles-ui-screen-revisions__revision-item[aria-selected=true] .global-styles-ui-screen-revisions__changes>li,.global-styles-ui-screen-revisions__revision-item[aria-selected=true] .global-styles-ui-screen-revisions__meta{color:#1e1e1e}.global-styles-ui-screen-revisions__revision-item:after{border:.5px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);height:100%;left:16px;top:0;width:0}.global-styles-ui-screen-revisions__revision-item:first-child:after{top:18px}.global-styles-ui-screen-revisions__revision-item:last-child:after{height:18px}.global-styles-ui-screen-revisions__revision-item-wrapper{display:block;padding:12px 12px 4px 40px}.global-styles-ui-screen-revisions__active-badge,.global-styles-ui-screen-revisions__apply-button.is-primary{align-self:flex-start;margin:0 12px 12px 40px}.global-styles-ui-screen-revisions__changes,.global-styles-ui-screen-revisions__meta{color:#757575;font-size:12px}.global-styles-ui-screen-revisions__description{align-items:flex-start;display:flex;flex-direction:column;gap:8px}.global-styles-ui-screen-revisions__description .global-styles-ui-screen-revisions__date{font-size:12px;font-weight:var(--wpds-typography-font-weight-emphasis,600);text-transform:uppercase}.global-styles-ui-screen-revisions__meta{align-items:flex-start;display:flex;justify-content:start;margin-bottom:4px;text-align:left;width:100%}.global-styles-ui-screen-revisions__meta img{border-radius:100%;height:16px;margin-right:8px;width:16px}.global-styles-ui-screen-revisions__loading{margin:24px auto!important}.global-styles-ui-screen-revisions__changes{line-height:1.4;list-style:disc;margin-left:12px;text-align:left}.global-styles-ui-screen-revisions__changes li{margin-bottom:4px}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination{gap:2px;justify-content:space-between}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .edit-site-pagination__total{height:1px;left:-1000px;margin:-1px;overflow:hidden;position:absolute}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-text{font-size:12px;will-change:opacity}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-button.is-tertiary{color:#1e1e1e}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-button.is-tertiary:disabled,.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-button.is-tertiary[aria-disabled=true]{color:#949494}.global-styles-ui-screen-revisions__footer{background:#fff;border-top:1px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);bottom:0;box-sizing:border-box;height:56px;min-width:100%;padding:12px;position:sticky;z-index:1}.global-styles-ui-variations_item{box-sizing:border-box;cursor:var(--wpds-cursor-control,pointer)}.global-styles-ui-variations_item .global-styles-ui-variations_item-preview{border-radius:2px;outline:1px solid rgba(0,0,0,.1);outline-offset:-1px;overflow:hidden;position:relative}@media not (prefers-reduced-motion){.global-styles-ui-variations_item .global-styles-ui-variations_item-preview{transition:outline .1s linear}}.global-styles-ui-variations_item .global-styles-ui-variations_item-preview.is-pill{height:32px}.global-styles-ui-variations_item .global-styles-ui-variations_item-preview.is-pill .block-editor-iframe__scale-container{overflow:hidden}.global-styles-ui-variations_item:not(.is-active):hover .global-styles-ui-variations_item-preview{outline-color:rgba(0,0,0,.3)}.global-styles-ui-variations_item.is-active .global-styles-ui-variations_item-preview,.global-styles-ui-variations_item:focus-visible .global-styles-ui-variations_item-preview{outline-color:#1e1e1e;outline-offset:1px;outline-width:var(--wp-admin-border-width-focus)}.global-styles-ui-variations_item:focus-visible .global-styles-ui-variations_item-preview{outline-color:var(--wp-admin-theme-color)}.global-styles-ui-preview__wrapper{display:block;max-width:100%;width:100%}.global-styles-ui-preview__wrapper.is-hoverable{cursor:var(--wpds-cursor-control,pointer)}.global-styles-ui-typography-preview{align-items:center;background:#f0f0f0;border-radius:2px;display:flex;justify-content:center;margin-bottom:20px;min-height:100px;overflow:hidden}.global-styles-ui-font-size__item{line-break:anywhere;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.global-styles-ui-font-size__item-value{color:#757575}.global-styles-ui-screen-typography__indicator{align-items:center;border-radius:2px;display:flex!important;font-size:14px;height:24px;justify-content:center;width:24px}.global-styles-ui-block-types-filter{margin-bottom:12px;padding:0 16px}.global-styles-ui-block-types-search{flex-grow:1}.global-styles-ui-block-types-item-list .global-styles-ui-block-types-item__icon{min-width:24px}.global-styles-ui-block-types-item-list__no-results{padding-top:16px}.global-styles-ui-block-types-item__indicator{background:var(--wp-admin-theme-color);border-radius:50%;flex:none;height:6px;margin-left:auto;width:6px}.global-styles-ui-screen-typography__font-variants-count{color:#757575}.global-styles-ui-font-families__manage-fonts{justify-content:center}.global-styles-ui-screen .color-block-support-panel{border-top:none;padding-left:0;padding-right:0;padding-top:0;row-gap:12px}.global-styles-ui-header{line-height:1.9!important;margin-bottom:0!important}.global-styles-ui-subtitle{font-size:11px!important;font-weight:var(--wpds-typography-font-weight-emphasis,600)!important;margin-bottom:0!important;text-transform:uppercase}.global-styles-ui-section-title{color:#2f2f2f;font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:1.2;margin:0;padding:16px 16px 0}.global-styles-ui-icon-with-current-color{fill:currentColor}.global-styles-ui__color-indicator-wrapper{flex-shrink:0;height:24px}.global-styles-ui__shadows-panel__options-container,.global-styles-ui__typography-panel__options-container{height:24px}.global-styles-ui__block-preview-panel{border:1px solid #ddd;border-radius:2px;overflow:hidden;position:relative;width:100%}.global-styles-ui__shadow-preview-panel{background-image:repeating-linear-gradient(45deg,#e0e0e0 25%,transparent 0,transparent 75%,#e0e0e0 0,#e0e0e0),repeating-linear-gradient(45deg,#e0e0e0 25%,transparent 0,transparent 75%,#e0e0e0 0,#e0e0e0);background-position:0 0,8px 8px;background-size:16px 16px;border:1px solid #ddd;border-radius:2px;height:144px;overflow:auto}.global-styles-ui__shadow-preview-panel .global-styles-ui__shadow-preview-block{background-color:#fff;border:1px solid #ddd;border-radius:2px;height:60px;width:60%}.global-styles-ui__shadow-editor__dropdown-content{width:280px}.global-styles-ui__shadow-editor-panel{margin-bottom:4px}.global-styles-ui__shadow-editor__dropdown{position:relative;width:100%}.global-styles-ui__shadow-editor__dropdown-toggle{border-radius:inherit;height:auto;padding-bottom:8px;padding-top:8px;text-align:left;width:100%}.global-styles-ui__shadow-editor__dropdown-toggle.is-open{background:#f0f0f0;color:var(--wp-admin-theme-color)}.global-styles-ui__shadow-editor__remove-button{opacity:0;position:absolute;right:8px;top:8px}.global-styles-ui__shadow-editor__dropdown-toggle:hover+.global-styles-ui__shadow-editor__remove-button,.global-styles-ui__shadow-editor__remove-button:focus,.global-styles-ui__shadow-editor__remove-button:hover{opacity:1}@media (hover:none){.global-styles-ui__shadow-editor__remove-button{opacity:1}}.global-styles-ui-screen-css{display:flex;flex:1 1 auto;flex-direction:column;margin:16px}.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel{flex:1 1 auto}.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel__custom-css-input,.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel__custom-css-input .components-base-control__field{display:flex;flex:1 1 auto;flex-direction:column}.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel__custom-css-input textarea{flex:1 1 auto}.global-styles-ui-screen-css-help-link{display:inline-block;margin-top:8px}.global-styles-ui-screen-variations{border-top:1px solid #ddd;margin-top:16px}.global-styles-ui-screen-variations>*{margin:24px 16px}.global-styles-ui-sidebar__navigator-provider{height:100%}.global-styles-ui-sidebar__navigator-screen{display:flex;flex-direction:column;height:100%}.global-styles-ui-color-palette__tablist-container{border-bottom:1px solid #ddd}.global-styles-ui-color-palette__tablist{margin-bottom:-1px}.global-styles-ui-sidebar__navigator-screen .single-column{grid-column:span 1}.global-styles-ui-screen-root.global-styles-ui-screen-root,.global-styles-ui-screen-style-variations.global-styles-ui-screen-style-variations{background:unset;color:inherit}.global-styles-ui-sidebar__panel .block-editor-block-icon svg{fill:currentColor}.global-styles-ui-screen-root__active-style-tile.global-styles-ui-screen-root__active-style-tile,.global-styles-ui-screen-root__active-style-tile.global-styles-ui-screen-root__active-style-tile .global-styles-ui-screen-root__active-style-tile-preview{border-radius:2px}.global-styles-ui-screen-root__active-style-tile-preview{clip-path:border-box}.global-styles-ui-color-palette-panel,.global-styles-ui-duotone-palette-panel,.global-styles-ui-gradient-palette-panel{padding:16px}.font-library-page__content{background-color:var(--wpds-color-background-surface-neutral-strong,#fff);display:flex;flex-direction:column;flex-grow:1;min-height:0}.font-library-page:has(.font-library__footer) .font-library-page__content{padding-bottom:90px}.font-library-page__tablist{border-bottom:1px solid #f0f0f0;flex-shrink:0;padding:0 24px}.font-library-page__tab-panel{flex-grow:1;min-height:0;overflow:auto}')); document.head.appendChild(style); } @@ -25706,7 +25689,7 @@ function FontLibraryPage() { })) ); } - return /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(page_default, { title: (0, import_i18n51.__)("Fonts"), className: "font-library-page", children: /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)( + return /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(page_default, { title: (0, import_i18n51.__)("Fonts"), className: "font-library-page", children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("div", { className: "font-library-page__content", children: /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)( Tabs2, { selectedTabId: activeTab, @@ -25733,7 +25716,7 @@ function FontLibraryPage() { )) ] } - ) }); + ) }) }); } function Stage() { return /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(FontLibraryPage, {}); diff --git a/src/wp-includes/build/routes/font-list/content.min.asset.php b/src/wp-includes/build/routes/font-list/content.min.asset.php index a14c8d81d4ff1..52c94b60391d7 100644 --- a/src/wp-includes/build/routes/font-list/content.min.asset.php +++ b/src/wp-includes/build/routes/font-list/content.min.asset.php @@ -1 +1 @@ - array('react', 'react-dom', 'react-jsx-runtime', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-date', 'wp-editor', 'wp-element', 'wp-i18n', 'wp-keycodes', 'wp-primitives', 'wp-private-apis', 'wp-style-engine', 'wp-theme', 'wp-warning'), 'module_dependencies' => array(array('id' => '@wordpress/a11y', 'import' => 'static'), array('id' => '@wordpress/route', 'import' => 'static')), 'version' => '104b97a0cdd454e16bdd'); \ No newline at end of file + array('react', 'react-dom', 'react-jsx-runtime', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-date', 'wp-editor', 'wp-element', 'wp-i18n', 'wp-keycodes', 'wp-primitives', 'wp-private-apis', 'wp-style-engine', 'wp-theme', 'wp-warning'), 'module_dependencies' => array(array('id' => '@wordpress/a11y', 'import' => 'static'), array('id' => '@wordpress/route', 'import' => 'static')), 'version' => '2f4e31ce4772e1e3bc39'); \ No newline at end of file diff --git a/src/wp-includes/build/routes/font-list/content.min.js b/src/wp-includes/build/routes/font-list/content.min.js index 9b907e95bf431..9d11c3c25f435 100644 --- a/src/wp-includes/build/routes/font-list/content.min.js +++ b/src/wp-includes/build/routes/font-list/content.min.js @@ -1,4 +1,4 @@ -var Uv=Object.create;var ka=Object.defineProperty;var Wv=Object.getOwnPropertyDescriptor;var Gv=Object.getOwnPropertyNames;var Yv=Object.getPrototypeOf,qv=Object.prototype.hasOwnProperty;var Wt=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof require<"u"?require:t)[r]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var tt=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),so=(e,t)=>{for(var r in t)ka(e,r,{get:t[r],enumerable:!0})},Zv=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Gv(t))!qv.call(e,n)&&n!==r&&ka(e,n,{get:()=>t[n],enumerable:!(o=Wv(t,n))||o.enumerable});return e};var f=(e,t,r)=>(r=e!=null?Uv(Yv(e)):{},Zv(t||!e||!e.__esModule?ka(r,"default",{value:e,enumerable:!0}):r,e));var ge=tt((ME,zu)=>{zu.exports=window.wp.i18n});var Te=tt((DE,Uu)=>{Uu.exports=window.wp.element});var ve=tt((BE,Wu)=>{Wu.exports=window.React});var Z=tt((YE,Zu)=>{Zu.exports=window.ReactJSXRuntime});var lo=tt((jT,wf)=>{wf.exports=window.ReactDOM});var xd=tt(wd=>{"use strict";var fn=ve();function Z0(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var X0=typeof Object.is=="function"?Object.is:Z0,K0=fn.useState,J0=fn.useEffect,Q0=fn.useLayoutEffect,$0=fn.useDebugValue;function ew(e,t){var r=t(),o=K0({inst:{value:r,getSnapshot:t}}),n=o[0].inst,i=o[1];return Q0(function(){n.value=r,n.getSnapshot=t,dl(n)&&i({inst:n})},[e,r,t]),J0(function(){return dl(n)&&i({inst:n}),e(function(){dl(n)&&i({inst:n})})},[e]),$0(r),r}function dl(e){var t=e.getSnapshot;e=e.value;try{var r=t();return!X0(e,r)}catch{return!0}}function tw(e,t){return t()}var rw=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?tw:ew;wd.useSyncExternalStore=fn.useSyncExternalStore!==void 0?fn.useSyncExternalStore:rw});var ts=tt((FO,Sd)=>{"use strict";Sd.exports=xd()});var _d=tt(Cd=>{"use strict";var rs=ve(),ow=ts();function nw(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var iw=typeof Object.is=="function"?Object.is:nw,sw=ow.useSyncExternalStore,aw=rs.useRef,lw=rs.useEffect,cw=rs.useMemo,uw=rs.useDebugValue;Cd.useSyncExternalStoreWithSelector=function(e,t,r,o,n){var i=aw(null);if(i.current===null){var s={hasValue:!1,value:null};i.current=s}else s=i.current;i=cw(function(){function u(h){if(!l){if(l=!0,c=h,h=o(h),n!==void 0&&s.hasValue){var g=s.value;if(n(g,h))return m=g}return m=h}if(g=m,iw(c,h))return g;var b=o(h);return n!==void 0&&n(g,b)?(c=h,g):(c=h,m=b)}var l=!1,c,m,d=r===void 0?null:r;return[function(){return u(t())},d===null?void 0:function(){return u(d())}]},[t,r,o,n]);var a=sw(e,i[0],i[1]);return lw(function(){s.hasValue=!0,s.value=a},[a]),uw(a),a}});var Ed=tt((IO,Rd)=>{"use strict";Rd.exports=_d()});var xn=tt((B5,rm)=>{rm.exports=window.wp.primitives});var yo=tt((j5,om)=>{om.exports=window.wp.compose});var gm=tt((uA,hm)=>{hm.exports=window.wp.theme});var li=tt((fA,ym)=>{ym.exports=window.wp.privateApis});var ue=tt((w4,Jm)=>{Jm.exports=window.wp.components});var sh=tt((L4,ih)=>{ih.exports=window.wp.editor});var sr=tt((N4,ah)=>{ah.exports=window.wp.coreData});var Kt=tt((M4,lh)=>{lh.exports=window.wp.data});var _n=tt((V4,ch)=>{ch.exports=window.wp.blocks});var Dt=tt((D4,uh)=>{uh.exports=window.wp.blockEditor});var dh=tt((W4,fh)=>{fh.exports=window.wp.styleEngine});var bh=tt((rI,vh)=>{"use strict";vh.exports=function e(t,r){if(t===r)return!0;if(t&&r&&typeof t=="object"&&typeof r=="object"){if(t.constructor!==r.constructor)return!1;var o,n,i;if(Array.isArray(t)){if(o=t.length,o!=r.length)return!1;for(n=o;n--!==0;)if(!e(t[n],r[n]))return!1;return!0}if(t instanceof Map&&r instanceof Map){if(t.size!==r.size)return!1;for(n of t.entries())if(!r.has(n[0]))return!1;for(n of t.entries())if(!e(n[1],r.get(n[0])))return!1;return!0}if(t instanceof Set&&r instanceof Set){if(t.size!==r.size)return!1;for(n of t.entries())if(!r.has(n[0]))return!1;return!0}if(ArrayBuffer.isView(t)&&ArrayBuffer.isView(r)){if(o=t.length,o!=r.length)return!1;for(n=o;n--!==0;)if(t[n]!==r[n])return!1;return!0}if(t.constructor===RegExp)return t.source===r.source&&t.flags===r.flags;if(t.valueOf!==Object.prototype.valueOf)return t.valueOf()===r.valueOf();if(t.toString!==Object.prototype.toString)return t.toString()===r.toString();if(i=Object.keys(t),o=i.length,o!==Object.keys(r).length)return!1;for(n=o;n--!==0;)if(!Object.prototype.hasOwnProperty.call(r,i[n]))return!1;for(n=o;n--!==0;){var s=i[n];if(!e(t[s],r[s]))return!1}return!0}return t!==t&&r!==r}});var Ch=tt((nI,Sh)=>{"use strict";var W1=function(t){return G1(t)&&!Y1(t)};function G1(e){return!!e&&typeof e=="object"}function Y1(e){var t=Object.prototype.toString.call(e);return t==="[object RegExp]"||t==="[object Date]"||X1(e)}var q1=typeof Symbol=="function"&&Symbol.for,Z1=q1?Symbol.for("react.element"):60103;function X1(e){return e.$$typeof===Z1}function K1(e){return Array.isArray(e)?[]:{}}function mi(e,t){return t.clone!==!1&&t.isMergeableObject(e)?En(K1(e),e,t):e}function J1(e,t,r){return e.concat(t).map(function(o){return mi(o,r)})}function Q1(e,t){if(!t.customMerge)return En;var r=t.customMerge(e);return typeof r=="function"?r:En}function $1(e){return Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(e).filter(function(t){return Object.propertyIsEnumerable.call(e,t)}):[]}function wh(e){return Object.keys(e).concat($1(e))}function xh(e,t){try{return t in e}catch{return!1}}function ex(e,t){return xh(e,t)&&!(Object.hasOwnProperty.call(e,t)&&Object.propertyIsEnumerable.call(e,t))}function tx(e,t,r){var o={};return r.isMergeableObject(e)&&wh(e).forEach(function(n){o[n]=mi(e[n],r)}),wh(t).forEach(function(n){ex(e,n)||(xh(e,n)&&r.isMergeableObject(t[n])?o[n]=Q1(n,r)(e[n],t[n],r):o[n]=mi(t[n],r))}),o}function En(e,t,r){r=r||{},r.arrayMerge=r.arrayMerge||J1,r.isMergeableObject=r.isMergeableObject||W1,r.cloneUnlessOtherwiseSpecified=mi;var o=Array.isArray(t),n=Array.isArray(e),i=o===n;return i?o?r.arrayMerge(e,t,r):tx(e,t,r):mi(t,r)}En.all=function(t,r){if(!Array.isArray(t))throw new Error("first argument should be an array");return t.reduce(function(o,n){return En(o,n,r)},{})};var rx=En;Sh.exports=rx});var Qc=tt((JN,Ng)=>{Ng.exports=window.wp.keycodes});var Bg=tt((c8,Dg)=>{Dg.exports=window.wp.apiFetch});var Sv=tt((o7,xv)=>{xv.exports=window.wp.date});function Hu(e){var t,r,o="";if(typeof e=="string"||typeof e=="number")o+=e;else if(typeof e=="object")if(Array.isArray(e)){var n=e.length;for(t=0;te();function Pe(e){let t=Ct(Qv).current;return t.next=e,Jv(t.effect),t.trampoline}function Qv(){let e={next:void 0,callback:$v,trampoline:(...t)=>e.callback?.(...t),effect:()=>{e.callback=e.next}};return e}function $v(){}var qu=f(ve(),1),eb=()=>{},we=typeof document<"u"?qu.useLayoutEffect:eb;function tb(e,t){return function(o,...n){let i=new URL(e);return i.searchParams.set("code",o.toString()),n.forEach(s=>i.searchParams.append("args[]",s)),`${t} error #${o}; visit ${i} for the full message.`}}var rb=tb("https://base-ui.com/production-error","Base UI"),lr=rb;var Ao=f(ve(),1);function Aa(e,t,r,o){let n=Ct(Ku).current;return ob(n,e,t,r,o)&&Ju(n,[e,t,r,o]),n.callback}function Xu(e){let t=Ct(Ku).current;return nb(t,e)&&Ju(t,e),t.callback}function Ku(){return{callback:null,cleanup:null,refs:[]}}function ob(e,t,r,o,n){return e.refs[0]!==t||e.refs[1]!==r||e.refs[2]!==o||e.refs[3]!==n}function nb(e,t){return e.refs.length!==t.length||e.refs.some((r,o)=>r!==t[o])}function Ju(e,t){if(e.refs=t,t.every(r=>r==null)){e.callback=null;return}e.callback=r=>{if(e.cleanup&&(e.cleanup(),e.cleanup=null),r!=null){let o=Array(t.length).fill(null);for(let n=0;n{for(let n=0;n=e}function Ia(e){if(!$u.isValidElement(e))return null;let t=e,r=t.props;return(rn(19)?r?.ref:t.ref)??null}function Yn(e,t){if(e&&!t)return e;if(!e&&t)return t;if(e||t)return{...e,...t}}function tr(){}var ef=Object.freeze([]),nt=Object.freeze({});function tf(e,t){let r={};for(let o in e){let n=e[o];if(t?.hasOwnProperty(o)){let i=t[o](n);i!=null&&Object.assign(r,i);continue}n===!0?r[`data-${o.toLowerCase()}`]="":n&&(r[`data-${o.toLowerCase()}`]=n.toString())}return r}function rf(e,t){return typeof e=="function"?e(t):e}function of(e,t){return typeof e=="function"?e(t):e}var La={};function It(e,t,r,o,n){if(!r&&!o&&!n&&!e)return Ai(t);let i=Ai(e);return t&&(i=qn(i,t)),r&&(i=qn(i,r)),o&&(i=qn(i,o)),n&&(i=qn(i,n)),i}function nf(e){if(e.length===0)return La;if(e.length===1)return Ai(e[0]);let t=Ai(e[0]);for(let r=1;r=65&&n<=90&&(typeof t=="function"||typeof t>"u")}function Na(e){return typeof e=="function"}function af(e,t){return Na(e)?e(t):e??La}function lb(e,t){return t?e?(...r)=>{let o=r[0];if(uf(o)){let i=o;cf(i);let s=t(...r);return i.baseUIHandlerPrevented||e?.(...r),s}let n=t(...r);return e?.(...r),n}:lf(t):e}function lf(e){return e&&((...t)=>{let r=t[0];return uf(r)&&cf(r),e(...t)})}function cf(e){return e.preventBaseUIHandler=()=>{e.baseUIHandlerPrevented=!0},e}function Ma(e,t){return t?e?t+" "+e:t:e}function uf(e){return e!=null&&typeof e=="object"&&"nativeEvent"in e}var Va=f(ve(),1);function Gt(e,t,r={}){let o=t.render,n=cb(t,r);if(r.enabled===!1)return null;let i=r.state??nt;return db(e,o,n,i)}function cb(e,t={}){let{className:r,style:o,render:n}=e,{state:i=nt,ref:s,props:a,stateAttributesMapping:u,enabled:l=!0}=t,c=l?rf(r,i):void 0,m=l?of(o,i):void 0,d=l?tf(i,u):nt,h=l&&a?ub(a):void 0,g=l?Yn(d,h)??{}:nt;return typeof document<"u"&&(l?Array.isArray(s)?g.ref=Xu([g.ref,Ia(n),...s]):g.ref=Aa(g.ref,Ia(n),s):Aa(null,null)),l?(c!==void 0&&(g.className=Ma(g.className,c)),m!==void 0&&(g.style=Yn(g.style,m)),g):nt}function ub(e){return Array.isArray(e)?nf(e):It(void 0,e)}var fb=Symbol.for("react.lazy");function db(e,t,r,o){if(t){if(typeof t=="function")return t(r,o);let n=It(r,t.props);n.ref=r.ref;let i=t;return i?.$$typeof===fb&&(i=Ao.Children.toArray(t)[0]),Ao.cloneElement(i,n)}if(e&&typeof e=="string")return pb(e,r);throw new Error(lr(8))}function pb(e,t){return e==="button"?(0,Va.createElement)("button",{type:"button",...t,key:t.key}):e==="img"?(0,Va.createElement)("img",{alt:"",...t,key:t.key}):Ao.createElement(e,t)}var Ii=f(ve(),1);var ff=0;function mb(e,t="mui"){let[r,o]=Ii.useState(e),n=e||r;return Ii.useEffect(()=>{r==null&&(ff+=1,o(`${t}-${ff}`))},[r,t]),n}var df=Gn.useId;function on(e,t){if(df!==void 0){let r=df();return e??(t?`${t}-${r}`:r)}return mb(e,t)}function pf(e){return on(e,"base-ui")}var Oe={};so(Oe,{cancelOpen:()=>Hb,chipRemovePress:()=>_b,clearPress:()=>Cb,closePress:()=>xb,closeWatcher:()=>Nb,decrementPress:()=>Tb,disabled:()=>Wb,drag:()=>Bb,escapeKey:()=>Lb,focusOut:()=>Ib,imperativeAction:()=>qb,incrementPress:()=>Eb,initial:()=>Yb,inputBlur:()=>kb,inputChange:()=>Pb,inputClear:()=>Ob,inputPaste:()=>Fb,inputPress:()=>Ab,itemPress:()=>wb,keyboard:()=>Vb,linkPress:()=>Sb,listNavigation:()=>Mb,missing:()=>Gb,none:()=>hb,outsidePress:()=>bb,pointer:()=>Db,scrub:()=>zb,siblingOpen:()=>Ub,swipe:()=>Zb,trackPress:()=>Rb,triggerFocus:()=>vb,triggerHover:()=>yb,triggerPress:()=>gb,wheel:()=>jb,windowResize:()=>Xb});var hb="none",gb="trigger-press",yb="trigger-hover",vb="trigger-focus",bb="outside-press",wb="item-press",xb="close-press",Sb="link-press",Cb="clear-press",_b="chip-remove-press",Rb="track-press",Eb="increment-press",Tb="decrement-press",Pb="input-change",Ob="input-clear",kb="input-blur",Fb="input-paste",Ab="input-press",Ib="focus-out",Lb="escape-key",Nb="close-watcher",Mb="list-navigation",Vb="keyboard",Db="pointer",Bb="drag",jb="wheel",zb="scrub",Hb="cancel-open",Ub="sibling-open",Wb="disabled",Gb="missing",Yb="initial",qb="imperative-action",Zb="swipe",Xb="window-resize";function De(e,t,r,o){let n=!1,i=!1,s=o??nt;return{reason:e,event:t??new Event("base-ui"),cancel(){n=!0},allowPropagation(){i=!0},get isCanceled(){return n},get isPropagationAllowed(){return i},trigger:r,...s}}var Ba=f(ve(),1);var mf=f(ve(),1);function nn(e){mf.useEffect(e,ef)}var Li=null,TT=globalThis.requestAnimationFrame,Da=class{callbacks=[];callbacksCount=0;nextId=1;startId=1;isScheduled=!1;tick=t=>{this.isScheduled=!1;let r=this.callbacks,o=this.callbacksCount;if(this.callbacks=[],this.callbacksCount=0,this.startId=this.nextId,o>0)for(let n=0;n=this.callbacks.length||(this.callbacks[r]=null,this.callbacksCount-=1)}},Ni=new Da;var kr=class e{static create(){return new e}static request(t){return Ni.request(t)}static cancel(t){return Ni.cancel(t)}currentId=Li;request(t){this.cancel(),this.currentId=Ni.request(()=>{this.currentId=Li,t()})}cancel=()=>{this.currentId!==Li&&(Ni.cancel(this.currentId),this.currentId=Li)};disposeEffect=()=>this.cancel};function sn(){let e=Ct(kr.create).current;return nn(e.disposeEffect),e}function hf(e,t=!1,r=!1){let[o,n]=Ba.useState(e&&t?"idle":void 0),[i,s]=Ba.useState(e);return e&&!i&&(s(!0),n("starting")),!e&&i&&o!=="ending"&&!r&&n("ending"),!e&&!i&&o==="ending"&&n(void 0),we(()=>{if(!e&&i&&o!=="ending"&&r){let a=kr.request(()=>{n("ending")});return()=>{kr.cancel(a)}}},[e,i,o,r]),we(()=>{if(!e||t)return;let a=kr.request(()=>{n(void 0)});return()=>{kr.cancel(a)}},[t,e]),we(()=>{if(!e||!t)return;e&&i&&o!=="idle"&&n("starting");let a=kr.request(()=>{n("idle")});return()=>{kr.cancel(a)}},[t,e,i,o]),{mounted:i,setMounted:s,transitionStatus:o}}var ja=(function(e){return e.startingStyle="data-starting-style",e.endingStyle="data-ending-style",e})({}),Kb={"data-starting-style":""},Jb={"data-ending-style":""},gf={transitionStatus(e){return e==="starting"?Kb:e==="ending"?Jb:null}};function Mi(){return typeof window<"u"}function Lo(e){return Vi(e)?(e.nodeName||"").toLowerCase():"#document"}function it(e){var t;return(e==null||(t=e.ownerDocument)==null?void 0:t.defaultView)||window}function Ar(e){var t;return(t=(Vi(e)?e.ownerDocument:e.document)||window.document)==null?void 0:t.documentElement}function Vi(e){return Mi()?e instanceof Node||e instanceof it(e).Node:!1}function Re(e){return Mi()?e instanceof Element||e instanceof it(e).Element:!1}function _t(e){return Mi()?e instanceof HTMLElement||e instanceof it(e).HTMLElement:!1}function an(e){return!Mi()||typeof ShadowRoot>"u"?!1:e instanceof ShadowRoot||e instanceof it(e).ShadowRoot}function Zn(e){let{overflow:t,overflowX:r,overflowY:o,display:n}=Lt(e);return/auto|scroll|overlay|hidden|clip/.test(t+o+r)&&n!=="inline"&&n!=="contents"}function yf(e){return/^(table|td|th)$/.test(Lo(e))}function Xn(e){try{if(e.matches(":popover-open"))return!0}catch{}try{return e.matches(":modal")}catch{return!1}}var Qb=/transform|translate|scale|rotate|perspective|filter/,$b=/paint|layout|strict|content/,Io=e=>!!e&&e!=="none",za;function Di(e){let t=Re(e)?Lt(e):e;return Io(t.transform)||Io(t.translate)||Io(t.scale)||Io(t.rotate)||Io(t.perspective)||!Bi()&&(Io(t.backdropFilter)||Io(t.filter))||Qb.test(t.willChange||"")||$b.test(t.contain||"")}function vf(e){let t=Fr(e);for(;_t(t)&&!Ir(t);){if(Di(t))return t;if(Xn(t))return null;t=Fr(t)}return null}function Bi(){return za==null&&(za=typeof CSS<"u"&&CSS.supports&&CSS.supports("-webkit-backdrop-filter","none")),za}function Ir(e){return/^(html|body|#document)$/.test(Lo(e))}function Lt(e){return it(e).getComputedStyle(e)}function Kn(e){return Re(e)?{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}:{scrollLeft:e.scrollX,scrollTop:e.scrollY}}function Fr(e){if(Lo(e)==="html")return e;let t=e.assignedSlot||e.parentNode||an(e)&&e.host||Ar(e);return an(t)?t.host:t}function bf(e){let t=Fr(e);return Ir(t)?(e.ownerDocument||e).body:_t(t)&&Zn(t)?t:bf(t)}function ao(e,t,r){var o;t===void 0&&(t=[]),r===void 0&&(r=!0);let n=bf(e),i=n===((o=e.ownerDocument)==null?void 0:o.body),s=it(n);if(i){let a=ji(s);return t.concat(s,s.visualViewport||[],Zn(n)?n:[],a&&r?ao(a):[])}else return t.concat(n,ao(n,[],r))}function ji(e){return e.parent&&Object.getPrototypeOf(e.parent)?e.frameElement:null}function Rt(e){return e?.ownerDocument||document}function ze(e,t,r,o){return e.addEventListener(t,r,o),()=>{e.removeEventListener(t,r,o)}}function Yt(e){let t=Ct(e0,e).current;return t.next=e,we(t.effect),t}function e0(e){let t={current:e,next:e,effect:()=>{t.current=t.next}};return t}var Cf=f(ve(),1);var Sf=f(lo(),1);function xf(e){return e==null?e:"current"in e?e.current:e}function ln(e,t=!1){let r=sn();return Pe((o,n=null)=>{r.cancel();let i=xf(e);if(i==null)return;let s=i,a=()=>{Sf.flushSync(o)};if(typeof s.getAnimations!="function"||globalThis.BASE_UI_ANIMATIONS_DISABLED){o();return}function u(){Promise.all(s.getAnimations().map(l=>l.finished)).then(()=>{n?.aborted||a()},()=>{if(n?.aborted)return;if(s.getAnimations().some(c=>c.pending||c.playState!=="finished")){u();return}a()})}if(t){let l="data-starting-style";if(!s.hasAttribute(l)){r.request(u);return}let c=new MutationObserver(()=>{s.hasAttribute(l)||(c.disconnect(),u())});c.observe(s,{attributes:!0,attributeFilter:[l]}),n?.addEventListener("abort",()=>c.disconnect(),{once:!0});return}r.request(u)})}function zi(e){let{enabled:t=!0,open:r,ref:o,onComplete:n}=e,i=Pe(n),s=ln(o,r);Cf.useEffect(()=>{if(!t)return;let a=new AbortController;return s(i,a.signal),()=>{a.abort()}},[t,r,i,s])}var Zr={};so(Zr,{engine:()=>Ya,env:()=>Za,os:()=>Wa,screenReader:()=>qa});var Wa={};so(Wa,{android:()=>Ef,apple:()=>Ua,ios:()=>Ha,linux:()=>i0,mac:()=>Tf,windows:()=>n0});function t0(){return typeof navigator>"u"?{userAgent:"",platform:"",maxTouchPoints:0}:{userAgent:navigator.userAgent,platform:navigator.platform??"",maxTouchPoints:navigator.maxTouchPoints??0}}var{userAgent:r0,platform:o0,maxTouchPoints:_f}=t0(),No=r0.toLowerCase(),Mo=o0.toLowerCase();var Ha=/^i(os$|p)/.test(Mo)||Mo==="macintel"&&_f>1,Rf="android",Ef=Mo===Rf||No.includes(Rf),Tf=!Ha&&Mo.startsWith("mac"),n0=Mo.startsWith("win"),i0=!Ef&&/^(linux|chrome os)/.test(Mo),Ua=Tf||Ha;var Ya={};so(Ya,{blink:()=>a0,gecko:()=>s0,webkit:()=>Ga});var Ga=typeof CSS<"u"&&!!CSS.supports?.("-webkit-backdrop-filter:none"),s0=!Ga&&No.includes("firefox"),a0=!Ga&&No.includes("chrom");var qa={};so(qa,{voiceOver:()=>l0});var l0=Ua;var Za={};so(Za,{jsdom:()=>c0});var c0=/jsdom|happydom/.test(No);var Jn=0,rr=class e{static create(){return new e}currentId=Jn;start(t,r){this.clear(),this.currentId=setTimeout(()=>{this.currentId=Jn,r()},t)}isStarted(){return this.currentId!==Jn}clear=()=>{this.currentId!==Jn&&(clearTimeout(this.currentId),this.currentId=Jn)};disposeEffect=()=>this.clear};function xr(){let e=Ct(rr.create).current;return nn(e.disposeEffect),e}var Mt=f(ve(),1);function Pf(e){return"nativeEvent"in e}function Xr(e,t){let r=["mouse","pen"];return t||r.push("",void 0),r.includes(e)}function Of(e){let t=e.type;return t==="click"||t==="mousedown"||t==="keydown"||t==="keyup"}var Xa="data-base-ui-focusable";var Ka="input:not([type='hidden']):not([disabled]),[contenteditable]:not([contenteditable='false']),textarea:not([disabled])";function Hi(e){let t=e.activeElement;for(;t?.shadowRoot?.activeElement!=null;)t=t.shadowRoot.activeElement;return t}function Ge(e,t){if(!e||!t)return!1;let r=t.getRootNode?.();if(e.contains(t))return!0;if(r&&an(r)){let o=t;for(;o;){if(e===o)return!0;o=o.parentNode||o.host}}return!1}function Nt(e){return"composedPath"in e?e.composedPath()[0]:e.target}function co(e,t){if(!Re(e))return!1;let r=e;if(t.hasElement(r))return!r.hasAttribute("data-trigger-disabled");for(let[,o]of t.entries())if(Ge(o,r))return!o.hasAttribute("data-trigger-disabled");return!1}function Ui(e,t){if(t==null)return!1;if("composedPath"in e)return e.composedPath().includes(t);let r=e;return r.target!=null&&t.contains(r.target)}function kf(e){return e.matches("html,body")}function Ff(e){return _t(e)&&e.matches(Ka)}function Ja(e){return e?.closest(`button,a[href],[role="button"],select,[tabindex]:not([tabindex="-1"]),${Ka}`)!=null}function Af(e){if(!e||Zr.env.jsdom)return!0;try{return e.matches(":focus-visible")}catch{return!0}}function u0(e,t){return t!=null&&!Xr(t)?0:typeof e=="function"?e():e}function cr(e,t,r){let o=u0(e,r);return typeof o=="number"?o:o?.[t]}function Qa(e){return typeof e=="function"?e():e}function Wi(e,t){return t||e==="click"||e==="mousedown"}function If(e){return e?.includes("mouse")&&e!=="mousedown"}var Lf=f(Z(),1),Nf=Mt.createContext({hasProvider:!1,timeoutMs:0,delayRef:{current:0},initialDelayRef:{current:0},timeout:new rr,currentIdRef:{current:null},currentContextRef:{current:null}});function f0(e,t){e.current=t.current}function $a(e){let{children:t,delay:r,timeoutMs:o=0}=e,n=Mt.useRef(r),i=Mt.useRef(r),s=Mt.useRef(null),a=Mt.useRef(null),u=xr();return we(()=>{if(i.current=r,!s.current){n.current=r;return}n.current={open:cr(n.current,"open"),close:cr(r,"close")}},[r,s,n,i]),(0,Lf.jsx)(Nf.Provider,{value:Mt.useMemo(()=>({hasProvider:!0,delayRef:n,initialDelayRef:i,currentIdRef:s,timeoutMs:o,currentContextRef:a,timeout:u}),[o,u]),children:t})}function el(e,t={open:!1}){let{open:r}=t,o="rootStore"in e?e.rootStore:e,n=o.useState("floatingId"),i=Mt.useContext(Nf),{currentIdRef:s,delayRef:a,timeoutMs:u,initialDelayRef:l,currentContextRef:c,hasProvider:m,timeout:d}=i,[h,g]=Mt.useState(!1),b=Mt.useRef(r);return we(()=>{b.current=r},[r]),we(()=>{function w(){c.current?.setIsInstantPhase(!1),s.current=null,c.current=null,a.current=l.current,d.clear()}if(s.current&&!r&&s.current===n){if(g(!1),u){let C=n;return d.start(u,()=>{o.select("open")||s.current&&s.current!==C||w()}),()=>{(b.current||s.current!==C)&&d.clear()}}w()}},[r,n,s,a,u,l,c,d,o]),we(()=>{if(!r)return;let w=c.current,C=s.current;d.clear(),c.current={onOpenChange:o.setOpen,setIsInstantPhase:g},s.current=n,a.current={open:0,close:cr(l.current,"close")},C!==null&&C!==n?(g(!0),w?.setIsInstantPhase(!0),w?.onOpenChange(!1,De(Oe.none))):(g(!1),w?.setIsInstantPhase(!1))},[r,n,o,s,a,l,c,d]),we(()=>()=>{if(s.current===n){if(c.current=null,!b.current)return;s.current=null,f0(a,l),d.clear()}},[c,s,a,n,l,d]),Mt.useMemo(()=>({hasProvider:m,delayRef:a,isInstantPhase:h}),[m,a,h])}function Sr(...e){return()=>{for(let t=0;t({x:e,y:e}),d0={left:"right",right:"left",bottom:"top",top:"bottom"};function Yi(e,t,r){return Cr(e,uo(t,r))}function Nr(e,t){return typeof e=="function"?e(t):e}function Tt(e){return e.split("-")[0]}function _r(e){return e.split("-")[1]}function qi(e){return e==="x"?"y":"x"}function ei(e){return e==="y"?"height":"width"}function qt(e){let t=e[0];return t==="t"||t==="b"?"y":"x"}function ti(e){return qi(qt(e))}function Df(e,t,r){r===void 0&&(r=!1);let o=_r(e),n=ti(e),i=ei(n),s=n==="x"?o===(r?"end":"start")?"right":"left":o==="start"?"bottom":"top";return t.reference[i]>t.floating[i]&&(s=Qn(s)),[s,Qn(s)]}function Bf(e){let t=Qn(e);return[Gi(e),t,Gi(t)]}function Gi(e){return e.includes("start")?e.replace("start","end"):e.replace("end","start")}var Mf=["left","right"],Vf=["right","left"],p0=["top","bottom"],m0=["bottom","top"];function h0(e,t,r){switch(e){case"top":case"bottom":return r?t?Vf:Mf:t?Mf:Vf;case"left":case"right":return t?p0:m0;default:return[]}}function jf(e,t,r,o){let n=_r(e),i=h0(Tt(e),r==="start",o);return n&&(i=i.map(s=>s+"-"+n),t&&(i=i.concat(i.map(Gi)))),i}function Qn(e){let t=Tt(e);return d0[t]+e.slice(t.length)}function g0(e){var t,r,o,n;return{top:(t=e.top)!=null?t:0,right:(r=e.right)!=null?r:0,bottom:(o=e.bottom)!=null?o:0,left:(n=e.left)!=null?n:0}}function Zi(e){return typeof e!="number"?g0(e):{top:e,right:e,bottom:e,left:e}}function Vo(e){let{x:t,y:r,width:o,height:n}=e;return{width:o,height:n,top:r,left:t,right:t+o,bottom:r+n,x:t,y:r}}function Kr(e,t,r=!0){return e.filter(n=>n.parentId===t).flatMap(n=>[...!r||n.context?.open?[n]:[],...Kr(e,n.id,r)])}function cn(e){return`data-base-ui-${e}`}var Vt=f(ve(),1),Uf=f(lo(),1);var zf={style:{transition:"none"}};var y0="data-base-ui-swipe-ignore",v0="data-swipe-ignore",EP=`[${y0}]`,TP=`[${v0}]`;var Hf={fallbackAxisSide:"end"};var Wf=f(Z(),1),b0=Vt.createContext(null),w0=()=>Vt.useContext(b0),x0=cn("portal");function Gf(e={}){let{ref:t,container:r,componentProps:o=nt,elementProps:n}=e,i=on(),a=w0()?.portalNode,[u,l]=Vt.useState(null),[c,m]=Vt.useState(null),d=Pe(w=>{w!==null&&m(w)}),h=Vt.useRef(null);we(()=>{if(r===null){h.current&&(h.current=null,m(null),l(null));return}let w=(r&&(Vi(r)?r:r.current))??a??document.body;if(w==null){h.current&&(h.current=null,m(null),l(null));return}h.current!==w&&(h.current=w,m(null),l(w))},[r,a]);let g=Gt("div",o,{ref:[t,d],props:[{id:i,[x0]:""},n]}),b=u&&g?Uf.createPortal(g,u):null;return{node:c,nodeId:Vt.isValidElement(g)?g.props.id:void 0,subtree:b}}var Do=f(ve(),1);function Yf(){let e=new Map;return{emit(t,r){e.get(t)?.forEach(o=>o(r))},on(t,r){e.has(t)||e.set(t,new Set),e.get(t).add(r)},off(t,r){e.get(t)?.delete(r)}}}var S0=f(Z(),1),C0=Do.createContext(null),_0=Do.createContext(null),Xi=()=>Do.useContext(C0)?.id||null,po=e=>{let t=Do.useContext(_0);return e??t};var Zt=f(ve(),1);function R0(e,t){let r=null,o=null,n=!1;return{contextElement:e||void 0,getBoundingClientRect(){let i=e?.getBoundingClientRect()||{width:0,height:0,x:0,y:0},s=t.axis==="x"||t.axis==="both",a=t.axis==="y"||t.axis==="both",u=["mouseenter","mousemove"].includes(t.dataRef.current.openEvent?.type||"")&&t.pointerType!=="touch",l=i.width,c=i.height,m=i.x,d=i.y;return r==null&&t.x&&s&&(r=i.x-t.x),o==null&&t.y&&a&&(o=i.y-t.y),m-=r||0,d-=o||0,l=0,c=0,!n||u?(l=t.axis==="y"?i.width:0,c=t.axis==="x"?i.height:0,m=s&&t.x!=null?t.x:m,d=a&&t.y!=null?t.y:d):n&&!u&&(c=t.axis==="x"?i.height:c,l=t.axis==="y"?i.width:l),n=!0,{width:l,height:c,x:m,y:d,top:d,right:m+l,bottom:d+c,left:m}}}}function qf(e){return e!=null&&e.clientX!=null}function tl(e,t={}){let{enabled:r=!0,axis:o="both"}=t,n="rootStore"in e?e.rootStore:e,i=n.useState("open"),s=n.useState("floatingElement"),a=n.useState("domReferenceElement"),u=n.context.dataRef,l=Zt.useRef(!1),c=Zt.useRef(null),[m,d]=Zt.useState(),[h,g]=Zt.useState([]),b=Pe(_=>{n.set("positionReference",_)}),w=Pe((_,k,E)=>{l.current||u.current.openEvent&&!qf(u.current.openEvent)||n.set("positionReference",R0(E??a,{x:_,y:k,axis:o,dataRef:u,pointerType:m}))}),C=Pe(_=>{i?c.current||(w(_.clientX,_.clientY,_.currentTarget),g([])):w(_.clientX,_.clientY,_.currentTarget)}),x=Xr(m)?s:i;Zt.useEffect(()=>{if(!r){b(a);return}if(!x)return;function _(){c.current?.(),c.current=null}let k=it(s);function E(T){let O=Nt(T);Ge(s,O)?_():w(T.clientX,T.clientY)}return!u.current.openEvent||qf(u.current.openEvent)?c.current=ze(k,"mousemove",E):b(a),_},[x,r,s,u,a,n,w,b,h]),Zt.useEffect(()=>()=>{n.set("positionReference",null)},[n]),Zt.useEffect(()=>{r&&!s&&(l.current=!1)},[r,s]),Zt.useEffect(()=>{!r&&i&&(l.current=!0)},[r,i]);let v=Zt.useMemo(()=>{function _(k){d(k.pointerType)}return{onPointerDown:_,onPointerEnter:_,onMouseMove:C,onMouseEnter:C}},[C]);return Zt.useMemo(()=>r?{reference:v,trigger:v}:{},[r,v])}var or=f(ve(),1);function E0(){return!1}function T0(e){return{escapeKey:typeof e=="boolean"?e:e?.escapeKey??!1,outsidePress:typeof e=="boolean"?e:e?.outsidePress??!0}}function rl(e,t={}){let{enabled:r=!0,escapeKey:o=!0,outsidePress:n=!0,outsidePressEvent:i="sloppy",referencePress:s=E0,bubbles:a,externalTree:u}=t,l="rootStore"in e?e.rootStore:e,c=l.useState("open"),m=l.useState("floatingElement"),{dataRef:d}=l.context,h=po(u),g=Pe(typeof n=="function"?n:()=>!1),b=typeof n=="function"?g:n,w=b!==!1,C=Pe(()=>i),{escapeKey:x,outsidePress:v}=T0(a),_=or.useRef(!1),k=or.useRef(!1),E=or.useRef(!1),T=or.useRef(!1),O=or.useRef(""),I=or.useRef(null),J=xr(),D=xr(),S=Pe(()=>{D.clear(),d.current.insideReactTree=!1}),L=Pe(P=>{let W=d.current.floatingContext?.nodeId;return(h?Kr(h.nodesRef.current,W):[]).some(xe=>xe.context?.open&&!xe.context.dataRef.current[P])}),Y=Pe(P=>Ui(P,l.select("floatingElement"))||Ui(P,l.select("domReferenceElement"))),A=Pe(P=>{s()&&l.setOpen(!1,De(Oe.triggerPress,P.nativeEvent))}),N=Pe(P=>{if(!c||!r||!o||P.key!=="Escape"||T.current||!x&&L("__escapeKeyBubbles"))return;let W=Pf(P)?P.nativeEvent:P,ne=De(Oe.escapeKey,W);l.setOpen(!1,ne),ne.isCanceled||P.preventDefault(),!x&&!ne.isPropagationAllowed&&P.stopPropagation()}),q=Pe(()=>{d.current.insideReactTree=!0,D.start(0,S)}),U=Pe(P=>{if(!c||!r||P.button!==0)return;let W=Nt(P.nativeEvent);Ge(l.select("floatingElement"),W)&&(_.current||(_.current=!0,k.current=!1))}),R=Pe(P=>{!c||!r||(P.defaultPrevented||P.nativeEvent.defaultPrevented)&&_.current&&(k.current=!0)});or.useEffect(()=>{if(!c||!r)return S;d.current.__escapeKeyBubbles=x,d.current.__outsidePressBubbles=v;let P=new rr,W=new rr;function ne(){P.clear(),T.current=!0}function xe(){P.start(Zr.engine.webkit?5:0,()=>{T.current=!1})}function se(){E.current=!0,W.start(0,()=>{E.current=!1})}function be(){_.current=!1,k.current=!1}function ye(){let V=O.current,te=V==="pen"||!V?"mouse":V,Ne=C(),He=typeof Ne=="function"?Ne():Ne;return typeof He=="string"?He:He[te]}function $(V){let te=ye();return te==="intentional"&&V.type!=="click"||te==="sloppy"&&V.type==="click"}function _e(V){let te=d.current.floatingContext?.nodeId,Ne=h&&Kr(h.nodesRef.current,te).some(He=>Ui(V,He.context?.elements.floating));return Y(V)||Ne}function Fe(V){if($(V)){V.type!=="click"&&!Y(V)&&(W.clear(),E.current=!1),S();return}if(d.current.insideReactTree){S();return}let te=Nt(V),Ne=`[${cn("inert")}]`,He=Re(te)?te.getRootNode():null,ot=Array.from((an(He)?He:Rt(l.select("floatingElement"))).querySelectorAll(Ne)),Ze=l.context.triggerElements;if(te&&(Ze.hasElement(te)||Ze.hasMatchingElement(Ue=>Ge(Ue,te))))return;let Be=Re(te)?te:null;for(;Be&&!Ir(Be);){let Ue=Fr(Be);if(Ir(Ue)||!Re(Ue))break;Be=Ue}if(!(ot.length&&Re(te)&&!kf(te)&&!Ge(te,l.select("floatingElement"))&&ot.every(Ue=>!Ge(Be,Ue)))){if(_t(te)&&!("touches"in V)){let Ue=Ir(te),ct=Lt(te),Se=/auto|scroll/,Pr=Ue||Se.test(ct.overflowX),$t=Ue||Se.test(ct.overflowY),Ye=Pr&&te.clientWidth>0&&te.scrollWidth>te.clientWidth,Yr=$t&&te.clientHeight>0&&te.scrollHeight>te.clientHeight,St=ct.direction==="rtl",kt=Yr&&(St?V.offsetX<=te.offsetWidth-te.clientWidth:V.offsetX>te.clientWidth),vt=Ye&&V.offsetY>te.clientHeight;if(kt||vt)return}if(!_e(V)){if(ye()==="intentional"&&E.current){W.clear(),E.current=!1;return}typeof b=="function"&&!b(V)||L("__outsidePressBubbles")||(l.setOpen(!1,De(Oe.outsidePress,V)),S())}}}function xt(V){ye()!=="sloppy"||V.pointerType==="touch"||!l.select("open")||!r||Y(V)||Fe(V)}function Le(V){if(ye()!=="sloppy"||!l.select("open")||!r||Y(V))return;let te=V.touches[0];te&&(I.current={startTime:Date.now(),startX:te.clientX,startY:te.clientY,dismissOnTouchEnd:!1,dismissOnMouseDown:!0},J.start(1e3,()=>{I.current&&(I.current.dismissOnTouchEnd=!1,I.current.dismissOnMouseDown=!1)}))}function X(V,te){let Ne=Nt(V);if(!Ne)return;let He=ze(Ne,V.type,()=>{te(V),He()})}function M(V){O.current="touch",X(V,Le)}function K(V){J.clear(),V.type==="pointerdown"&&(O.current=V.pointerType),!(V.type==="mousedown"&&I.current&&!I.current.dismissOnMouseDown)&&X(V,te=>{te.type==="pointerdown"?xt(te):Fe(te)})}function H(V){if(!_.current)return;let te=k.current;if(be(),ye()==="intentional"){if(V.type==="pointercancel"){te&&se();return}if(!_e(V)){if(te){se();return}typeof b=="function"&&!b(V)||(W.clear(),E.current=!0,S())}}}function Q(V){if(ye()!=="sloppy"||!I.current||Y(V))return;let te=V.touches[0];if(!te)return;let Ne=Math.abs(te.clientX-I.current.startX),He=Math.abs(te.clientY-I.current.startY),ot=Math.sqrt(Ne*Ne+He*He);ot>5&&(I.current.dismissOnTouchEnd=!0),ot>10&&(Fe(V),J.clear(),I.current=null)}function pe(V){X(V,Q)}function le(V){ye()!=="sloppy"||!I.current||Y(V)||(I.current.dismissOnTouchEnd&&Fe(V),J.clear(),I.current=null)}function fe(V){X(V,le)}let me=Rt(m),he=Sr(o&&Sr(ze(me,"keydown",N),ze(me,"compositionstart",ne),ze(me,"compositionend",xe)),w&&Sr(ze(me,"click",K,!0),ze(me,"pointerdown",K,!0),ze(me,"pointerup",H,!0),ze(me,"pointercancel",H,!0),ze(me,"mousedown",K,!0),ze(me,"mouseup",H,!0),ze(me,"touchstart",M,!0),ze(me,"touchmove",pe,!0),ze(me,"touchend",fe,!0)));return()=>{he(),P.clear(),W.clear(),be(),E.current=!1,S()}},[d,m,o,w,b,c,r,x,v,N,S,C,L,Y,h,l,J]);let B=or.useMemo(()=>({onKeyDown:N,onPointerDown:A,onClick:A}),[N,A]),re=or.useMemo(()=>({onKeyDown:N,onPointerDown:R,onMouseDown:R,onClickCapture:q,onMouseDownCapture(P){q(),U(P)},onPointerDownCapture(P){q(),U(P)},onMouseUpCapture:q,onTouchEndCapture:q,onTouchMoveCapture:q}),[N,q,U,R]);return or.useMemo(()=>r?{reference:B,floating:re,trigger:B}:{},[r,B,re])}var Pt=f(ve(),1);function Zf(e,t,r){let{reference:o,floating:n}=e,i=qt(t),s=ti(t),a=ei(s),u=Tt(t),l=i==="y",c=o.x+o.width/2-n.width/2,m=o.y+o.height/2-n.height/2,d=o[a]/2-n[a]/2,h;switch(u){case"top":h={x:c,y:o.y-n.height};break;case"bottom":h={x:c,y:o.y+o.height};break;case"right":h={x:o.x+o.width,y:m};break;case"left":h={x:o.x-n.width,y:m};break;default:h={x:o.x,y:o.y}}let g=_r(t);return g&&(h[s]+=d*(g==="end"?1:-1)*(r&&l?-1:1)),h}async function Xf(e,t){var r;t===void 0&&(t={});let{x:o,y:n,platform:i,rects:s,elements:a,strategy:u}=e,{boundary:l="clippingAncestors",rootBoundary:c="viewport",elementContext:m="floating",altBoundary:d=!1,padding:h=0}=Nr(t,e),g=Zi(h),w=a[d?m==="floating"?"reference":"floating":m],C=Vo(await i.getClippingRect({element:(r=await(i.isElement==null?void 0:i.isElement(w)))==null||r?w:w.contextElement||await(i.getDocumentElement==null?void 0:i.getDocumentElement(a.floating)),boundary:l,rootBoundary:c,strategy:u})),x=m==="floating"?{x:o,y:n,width:s.floating.width,height:s.floating.height}:s.reference,v=await(i.getOffsetParent==null?void 0:i.getOffsetParent(a.floating)),_=await(i.isElement==null?void 0:i.isElement(v))&&await(i.getScale==null?void 0:i.getScale(v))||{x:1,y:1},k=Vo(i.convertOffsetParentRelativeRectToViewportRelativeRect?await i.convertOffsetParentRelativeRectToViewportRelativeRect({elements:a,rect:x,offsetParent:v,strategy:u}):x);return{top:(C.top-k.top+g.top)/_.y,bottom:(k.bottom-C.bottom+g.bottom)/_.y,left:(C.left-k.left+g.left)/_.x,right:(k.right-C.right+g.right)/_.x}}var P0=50,Kf=async(e,t,r)=>{let{placement:o="bottom",strategy:n="absolute",middleware:i=[],platform:s}=r,a=s.detectOverflow?s:{...s,detectOverflow:Xf},u=await(s.isRTL==null?void 0:s.isRTL(t)),l=await s.getElementRects({reference:e,floating:t,strategy:n}),{x:c,y:m}=Zf(l,o,u),d=o,h=0,g={};for(let b=0;bY<=0)){var D,S;let Y=(((D=i.flip)==null?void 0:D.index)||0)+1,A=T[Y];if(A&&(!(m==="alignment"?x!==qt(A):!1)||J.every(U=>qt(U.placement)===x?U.overflows[0]>0:!0)))return{data:{index:Y,overflows:J},reset:{placement:A}};let N=(S=J.filter(q=>q.overflows[0]<=0).sort((q,U)=>q.overflows[1]-U.overflows[1])[0])==null?void 0:S.placement;if(!N)switch(h){case"bestFit":{var L;let q=(L=J.filter(U=>{if(E){let R=qt(U.placement);return R===x||R==="y"}return!0}).map(U=>[U.placement,U.overflows.filter(R=>R>0).reduce((R,B)=>R+B,0)]).sort((U,R)=>U[1]-R[1])[0])==null?void 0:L[0];q&&(N=q);break}case"initialPlacement":N=a;break}if(n!==N)return{reset:{placement:N}}}return{}}}};var Qf=new Set(["left","top"]);async function O0(e,t){let{placement:r,platform:o,elements:n}=e,i=await(o.isRTL==null?void 0:o.isRTL(n.floating)),s=Tt(r),a=_r(r),u=qt(r)==="y",l=Qf.has(s)?-1:1,c=i&&u?-1:1,m=Nr(t,e),{mainAxis:d,crossAxis:h,alignmentAxis:g}=typeof m=="number"?{mainAxis:m,crossAxis:0,alignmentAxis:null}:{mainAxis:m.mainAxis||0,crossAxis:m.crossAxis||0,alignmentAxis:m.alignmentAxis};return a&&typeof g=="number"&&(h=a==="end"?g*-1:g),u?{x:h*c,y:d*l}:{x:d*l,y:h*c}}var $f=function(e){return e===void 0&&(e=0),{name:"offset",options:e,async fn(t){var r,o;let{x:n,y:i,placement:s,middlewareData:a}=t,u=await O0(t,e);return s===((r=a.offset)==null?void 0:r.placement)&&(o=a.arrow)!=null&&o.alignmentOffset?{}:{x:n+u.x,y:i+u.y,data:{...u,placement:s}}}}},ed=function(e){return e===void 0&&(e={}),{name:"shift",options:e,async fn(t){let{x:r,y:o,placement:n,platform:i}=t,{mainAxis:s=!0,crossAxis:a=!1,limiter:u={fn:x=>{let{x:v,y:_}=x;return{x:v,y:_}}},...l}=Nr(e,t),c={x:r,y:o},m=await i.detectOverflow(t,l),d=qt(n),h=qi(d),g=c[h],b=c[d],w=(x,v)=>Yi(v+m[x==="y"?"top":"left"],v,v-m[x==="y"?"bottom":"right"]);s&&(g=w(h,g)),a&&(b=w(d,b));let C=u.fn({...t,[h]:g,[d]:b});return{...C,data:{x:C.x-r,y:C.y-o,enabled:{[h]:s,[d]:a}}}}}},td=function(e){return e===void 0&&(e={}),{options:e,fn(t){var r,o;let{x:n,y:i,placement:s,rects:a,middlewareData:u}=t,{offset:l=0,mainAxis:c=!0,crossAxis:m=!0}=Nr(e,t),d={x:n,y:i},h=qt(s),g=qi(h),b=d[g],w=d[h],C=Nr(l,t),x=typeof C=="number"?{mainAxis:C,crossAxis:0}:{mainAxis:(r=C.mainAxis)!=null?r:0,crossAxis:(o=C.crossAxis)!=null?o:0};if(c){let k=g==="y"?"height":"width",E=a.reference[g]-a.floating[k]+x.mainAxis,T=a.reference[g]+a.reference[k]-x.mainAxis;bT&&(b=T)}if(m){var v,_;let k=g==="y"?"width":"height",E=Qf.has(Tt(s)),T=a.reference[h]-a.floating[k]+(E&&((v=u.offset)==null?void 0:v[h])||0)+(E?0:x.crossAxis),O=a.reference[h]+a.reference[k]+(E?0:((_=u.offset)==null?void 0:_[h])||0)-(E?x.crossAxis:0);wO&&(w=O)}return{[g]:b,[h]:w}}}},rd=function(e){return e===void 0&&(e={}),{name:"size",options:e,async fn(t){let{placement:r,rects:o,platform:n,elements:i}=t,{apply:s=()=>{},...a}=Nr(e,t),u=await n.detectOverflow(t,a),l=Tt(r),c=_r(r),m=qt(r)==="y",{width:d,height:h}=o.floating,g,b;l==="top"||l==="bottom"?(g=l,b=c===(await(n.isRTL==null?void 0:n.isRTL(i.floating))?"start":"end")?"left":"right"):(b=l,g=c==="end"?"top":"bottom");let w=h-u.top-u.bottom,C=d-u.left-u.right,x=uo(h-u[g],w),v=uo(d-u[b],C),_=t.middlewareData.shift,k=!_,E=x,T=v;_!=null&&_.enabled.x&&(T=C),_!=null&&_.enabled.y&&(E=w),k&&!c&&(m?T=d-2*Cr(u.left,u.right):E=h-2*Cr(u.top,u.bottom)),await s({...t,availableWidth:T,availableHeight:E});let O=await n.getDimensions(i.floating);return d!==O.width||h!==O.height?{reset:{rects:!0}}:{}}}};function id(e){let t=Lt(e),r=parseFloat(t.width)||0,o=parseFloat(t.height)||0,n=_t(e),i=n?e.offsetWidth:r,s=n?e.offsetHeight:o,a=fo(r)!==i||fo(o)!==s;return a&&(r=i,o=s),{width:r,height:o,$:a}}function nl(e){return Re(e)?e:e.contextElement}function un(e){let t=nl(e);if(!_t(t))return Lr(1);let r=t.getBoundingClientRect(),{width:o,height:n,$:i}=id(t),s=(i?fo(r.width):r.width)/o,a=(i?fo(r.height):r.height)/n;return(!s||!Number.isFinite(s))&&(s=1),(!a||!Number.isFinite(a))&&(a=1),{x:s,y:a}}var k0=Lr(0);function sd(e){let t=it(e);return!Bi()||!t.visualViewport?k0:{x:t.visualViewport.offsetLeft,y:t.visualViewport.offsetTop}}function F0(e,t,r){return t===void 0&&(t=!1),!!r&&t&&r===it(e)}function Bo(e,t,r,o){t===void 0&&(t=!1),r===void 0&&(r=!1);let n=e.getBoundingClientRect(),i=nl(e),s=Lr(1);t&&(o?Re(o)&&(s=un(o)):s=un(e));let a=F0(i,r,o)?sd(i):Lr(0),u=(n.left+a.x)/s.x,l=(n.top+a.y)/s.y,c=n.width/s.x,m=n.height/s.y;if(i&&o){let d=it(i),h=Re(o)?it(o):o,g=d,b=ji(g);for(;b&&h!==g;){let w=un(b),C=b.getBoundingClientRect(),x=Lt(b),v=C.left+(b.clientLeft+parseFloat(x.paddingLeft))*w.x,_=C.top+(b.clientTop+parseFloat(x.paddingTop))*w.y;u*=w.x,l*=w.y,c*=w.x,m*=w.y,u+=v,l+=_,g=it(b),b=ji(g)}}return Vo({width:c,height:m,x:u,y:l})}function Ki(e,t){let r=Kn(e).scrollLeft;return t?t.left+r:Bo(Ar(e)).left+r}function ad(e,t){let r=e.getBoundingClientRect(),o=r.left+t.scrollLeft-Ki(e,r),n=r.top+t.scrollTop;return{x:o,y:n}}function A0(e){let{elements:t,rect:r,offsetParent:o,strategy:n}=e,i=n==="fixed",s=Ar(o),a=t?Xn(t.floating):!1;if(o===s||a&&i)return r;let u={scrollLeft:0,scrollTop:0},l=Lr(1),c=Lr(0),m=_t(o);if((m||!i)&&((Lo(o)!=="body"||Zn(s))&&(u=Kn(o)),m)){let h=Bo(o);l=un(o),c.x=h.x+o.clientLeft,c.y=h.y+o.clientTop}let d=s&&!m&&!i?ad(s,u):Lr(0);return{width:r.width*l.x,height:r.height*l.y,x:r.x*l.x-u.scrollLeft*l.x+c.x+d.x,y:r.y*l.y-u.scrollTop*l.y+c.y+d.y}}function I0(e){return e.getClientRects?Array.from(e.getClientRects()):[]}function L0(e){let t=Kn(e),r=e.ownerDocument.body,o=Cr(e.scrollWidth,e.clientWidth,r.scrollWidth,r.clientWidth),n=Cr(e.scrollHeight,e.clientHeight,r.scrollHeight,r.clientHeight),i=-t.scrollLeft+Ki(e),s=-t.scrollTop;return Lt(r).direction==="rtl"&&(i+=Cr(e.clientWidth,r.clientWidth)-o),{width:o,height:n,x:i,y:s}}var N0=25;function M0(e,t,r){r===void 0&&(r="viewport");let o=r==="layoutViewport",n=it(e),i=Ar(e),s=n.visualViewport,a=i.clientWidth,u=i.clientHeight,l=0,c=0;if(s){let d=!Bi()||t==="fixed";o?d||(l=-s.offsetLeft,c=-s.offsetTop):(a=s.width,u=s.height,d&&(l=s.offsetLeft,c=s.offsetTop))}if(Ki(i)<=0){let d=i.ownerDocument,h=d.body,g=getComputedStyle(h),b=d.compatMode==="CSS1Compat"&&parseFloat(g.marginLeft)+parseFloat(g.marginRight)||0,w=Math.abs(i.clientWidth-h.clientWidth-b),C=getComputedStyle(i).scrollbarGutter==="stable both-edges"?w/2:w;C<=N0&&(a-=C)}return{width:a,height:u,x:l,y:c}}function V0(e,t){let r=Bo(e,!0,t==="fixed"),o=r.top+e.clientTop,n=r.left+e.clientLeft,i=un(e),s=e.clientWidth*i.x,a=e.clientHeight*i.y,u=n*i.x,l=o*i.y;return{width:s,height:a,x:u,y:l}}function od(e,t,r){let o;if(t==="viewport"||t==="layoutViewport")o=M0(e,r,t);else if(t==="document")o=L0(Ar(e));else if(Re(t))o=V0(t,r);else{let n=sd(e);o={x:t.x-n.x,y:t.y-n.y,width:t.width,height:t.height}}return Vo(o)}function D0(e,t){let r=t.get(e);if(r)return r;let o=ao(e,[],!1).filter(a=>Re(a)&&Lo(a)!=="body"),n=null,i=Lt(e).position==="fixed",s=i?Fr(e):e;for(;Re(s)&&!Ir(s);){let a=Lt(s),u=Di(s),l=n?n.position:i?"fixed":"";!u&&(l==="fixed"||l==="absolute"&&a.position==="static")?o=o.filter(m=>m!==s):n=a,s=Fr(s)}return t.set(e,o),o}function B0(e){let{element:t,boundary:r,rootBoundary:o,strategy:n}=e,s=[...r==="clippingAncestors"?Xn(t)?[]:D0(t,this._c):[].concat(r),o],a=od(t,s[0],n),u=a.top,l=a.right,c=a.bottom,m=a.left;for(let d=1;d{a(!1,1e-7)},1e3)}T=!1}try{o=new IntersectionObserver(O,{...E,root:i.ownerDocument})}catch{o=new IntersectionObserver(O,E)}o.observe(e)}let u=it(e),l=()=>a(r);return u.addEventListener("resize",l),a(!0),()=>{u.removeEventListener("resize",l),s()}}function ri(e,t,r,o){o===void 0&&(o={});let{ancestorScroll:n=!0,ancestorResize:i=!0,elementResize:s=typeof ResizeObserver=="function",layoutShift:a=typeof IntersectionObserver=="function",animationFrame:u=!1}=o,l=nl(e),c=n||i?[...l?ao(l):[],...t?ao(t):[]]:[];c.forEach(C=>{n&&C.addEventListener("scroll",r),i&&C.addEventListener("resize",r)});let m=l&&a?W0(l,r,i):null,d=-1,h=null;s&&(h=new ResizeObserver(C=>{let[x]=C;x&&x.target===l&&h&&t&&(h.unobserve(t),cancelAnimationFrame(d),d=requestAnimationFrame(()=>{var v;(v=h)==null||v.observe(t)})),r()}),l&&!u&&h.observe(l),t&&h.observe(t));let g,b=u?Bo(e):null;u&&w();function w(){let C=Bo(e);b&&!cd(b,C)&&r(),b=C,g=requestAnimationFrame(w)}return r(),()=>{var C;c.forEach(x=>{n&&x.removeEventListener("scroll",r),i&&x.removeEventListener("resize",r)}),m?.(),(C=h)==null||C.disconnect(),h=null,u&&cancelAnimationFrame(g)}}var ud=$f;var fd=ed,dd=Jf,pd=rd;var md=td,Ji=(e,t,r)=>{let o=new Map,n=r??{},i={...il,...n.platform,_c:o};return Kf(e,t,{...n,platform:i})};var mt=f(ve(),1),gd=f(ve(),1),yd=f(lo(),1),Y0=typeof document<"u",q0=function(){},Qi=Y0?gd.useLayoutEffect:q0;function $i(e,t){if(e===t)return!0;if(typeof e!=typeof t)return!1;if(typeof e=="function"&&e.toString()===t.toString())return!0;let r,o,n;if(e&&t&&typeof e=="object"){if(Array.isArray(e)){if(r=e.length,r!==t.length)return!1;for(o=r;o--!==0;)if(!$i(e[o],t[o]))return!1;return!0}if(n=Object.keys(e),r=n.length,r!==Object.keys(t).length)return!1;for(o=r;o--!==0;)if(!{}.hasOwnProperty.call(t,n[o]))return!1;for(o=r;o--!==0;){let i=n[o];if(!(i==="_owner"&&e.$$typeof)&&!$i(e[i],t[i]))return!1}return!0}return e!==e&&t!==t}function vd(e){return typeof window>"u"?1:(e.ownerDocument.defaultView||window).devicePixelRatio||1}function hd(e,t){let r=vd(e);return Math.round(t*r)/r}function sl(e){let t=mt.useRef(e);return Qi(()=>{t.current=e}),t}function bd(e){e===void 0&&(e={});let{placement:t="bottom",strategy:r="absolute",middleware:o=[],platform:n,elements:{reference:i,floating:s}={},transform:a=!0,whileElementsMounted:u,open:l}=e,[c,m]=mt.useState({x:0,y:0,strategy:r,placement:t,middlewareData:{},isPositioned:!1}),[d,h]=mt.useState(o);$i(d,o)||h(o);let[g,b]=mt.useState(null),[w,C]=mt.useState(null),x=mt.useCallback(U=>{U!==E.current&&(E.current=U,b(U))},[]),v=mt.useCallback(U=>{U!==T.current&&(T.current=U,C(U))},[]),_=i||g,k=s||w,E=mt.useRef(null),T=mt.useRef(null),O=mt.useRef(c),I=u!=null,J=sl(u),D=sl(n),S=sl(l),L=mt.useCallback(()=>{if(!E.current||!T.current)return;let U={placement:t,strategy:r,middleware:d};D.current&&(U.platform=D.current),Ji(E.current,T.current,U).then(R=>{let B={...R,isPositioned:S.current!==!1};Y.current&&!$i(O.current,B)&&(O.current=B,yd.flushSync(()=>{m(B)}))})},[d,t,r,D,S]);Qi(()=>{l===!1&&O.current.isPositioned&&(O.current.isPositioned=!1,m(U=>({...U,isPositioned:!1})))},[l]);let Y=mt.useRef(!1);Qi(()=>(Y.current=!0,()=>{Y.current=!1}),[]),Qi(()=>{if(_&&(E.current=_),k&&(T.current=k),_&&k){if(J.current)return J.current(_,k,L);L()}},[_,k,L,J,I]);let A=mt.useMemo(()=>({reference:E,floating:T,setReference:x,setFloating:v}),[x,v]),N=mt.useMemo(()=>({reference:_,floating:k}),[_,k]),q=mt.useMemo(()=>{let U={position:r,left:0,top:0};if(!N.floating)return U;let R=hd(N.floating,c.x),B=hd(N.floating,c.y);return a?{...U,transform:"translate("+R+"px, "+B+"px)",...vd(N.floating)>=1.5&&{willChange:"transform"}}:{position:r,left:R,top:B}},[r,a,N.floating,c.x,c.y]);return mt.useMemo(()=>({...c,update:L,refs:A,elements:N,floatingStyles:q}),[c,L,A,N,q])}var al=(e,t)=>{let r=ud(e);return{name:r.name,fn:r.fn,options:[e,t]}},ll=(e,t)=>{let r=fd(e);return{name:r.name,fn:r.fn,options:[e,t]}},cl=(e,t)=>({fn:md(e).fn,options:[e,t]}),ul=(e,t)=>{let r=dd(e);return{name:r.name,fn:r.fn,options:[e,t]}},fl=(e,t)=>{let r=pd(e);return{name:r.name,fn:r.fn,options:[e,t]}};var es=class{attachedStores=[];attachedStoreValue=null;storeListeners=new Set;constructor(t,r,o=!0){this.fallbackStore=t,this.componentName=r,this.throwOnMissingTrigger=o}get attachedStore(){return this.attachedStoreValue}get store(){return this.attachedStoreValue??this.fallbackStore}get serverStore(){return this.fallbackStore}subscribeStore(t){return this.storeListeners.add(t),()=>{this.storeListeners.delete(t)}}attachStore(t){return this.attachedStores.push(t),this.setActiveStore(t),()=>{let r=this.attachedStores.lastIndexOf(t);r!==-1&&this.attachedStores.splice(r,1),this.setActiveStore(this.attachedStores[this.attachedStores.length-1]??null)}}setActiveStore(t){this.attachedStoreValue!==t&&(this.attachedStoreValue=t,this.storeListeners.forEach(r=>{r()}))}openByTrigger(t){let r=this.attachedStore;if(r===null)return;let o;if(t){for(let n=this.attachedStores.length-1;n>=0&&!o;n-=1)o=this.attachedStores[n].context.triggerElements.getById(t);o??=this.fallbackStore.context.triggerElements.getById(t)}if(t&&!o&&this.throwOnMissingTrigger)throw new Error(lr(99,this.componentName,t,this.componentName));r.setOpen(!0,De(Oe.imperativeAction,void 0,o))}closePopup(){let t=this.attachedStore;t!==null&&t.setOpen(!1,De(Oe.imperativeAction))}};var zo=f(ve(),1),Nd=f(lo(),1);var Id=f(ve(),1);var Fd=f(ve(),1),gl=f(ts(),1),Ad=f(Ed(),1);var Td=f(ve(),1);var pl=[],ml;function Pd(){return ml}function Od(e){pl.push(e)}function hl(e){let t=(r,o)=>{let n=Ct(fw).current,i;try{ml=n;for(let s of pl)s.before(n);i=e(r,o);for(let s of pl)s.after(n);n.didInitialize=!0}finally{ml=void 0}return i};return t.displayName=e.displayName||e.name,t}function kd(e){return Td.forwardRef(hl(e))}function fw(){return{didInitialize:!1}}var dw=rn(19),pw=dw?hw:gw;function os(e,t,r,o,n){return pw(e,t,r,o,n)}function mw(e,t,r,o,n){let i=Fd.useCallback(()=>t(e.getSnapshot(),r,o,n),[e,t,r,o,n]);return(0,gl.useSyncExternalStore)(e.subscribe,i,i)}Od({before(e){e.syncIndex=0,e.didInitialize||(e.syncTick=1,e.syncHooks=[],e.didChangeStore=!0,e.getSnapshot=()=>{let t=!1;for(let r=0;r0&&(e.didChangeStore&&(e.didChangeStore=!1,e.subscribe=t=>{let r=new Set;for(let n of e.syncHooks)r.add(n.store);let o=[];for(let n of r)o.push(n.subscribe(t));return()=>{for(let n of o)n()}}),(0,gl.useSyncExternalStore)(e.subscribe,e.getSnapshot,e.getSnapshot))}});function hw(e,t,r,o,n){let i=Pd();if(!i)return mw(e,t,r,o,n);let s=i.syncIndex;i.syncIndex+=1;let a;return i.didInitialize?(a=i.syncHooks[s],(a.store!==e||a.selector!==t||!Object.is(a.a1,r)||!Object.is(a.a2,o)||!Object.is(a.a3,n))&&(a.store!==e&&(i.didChangeStore=!0),a.store=e,a.selector=t,a.a1=r,a.a2=o,a.a3=n,a.value=t(e.getSnapshot(),r,o,n))):(a={store:e,selector:t,a1:r,a2:o,a3:n,value:t(e.getSnapshot(),r,o,n)},i.syncHooks.push(a)),a.value}function gw(e,t,r,o,n){return(0,Ad.useSyncExternalStoreWithSelector)(e.subscribe,e.getSnapshot,e.getSnapshot,i=>t(i,r,o,n))}var ns=class{constructor(t){this.state=t,this.listeners=new Set,this.updateTick=0}subscribe=t=>(this.listeners.add(t),()=>{this.listeners.delete(t)});getSnapshot=()=>this.state;setState(t){if(this.state===t)return;this.state=t,this.updateTick+=1;let r=this.updateTick;for(let o of this.listeners){if(r!==this.updateTick)return;o(t)}}update(t){for(let r in t)if(!Object.is(this.state[r],t[r])){this.setState({...this.state,...t});return}}set(t,r){Object.is(this.state[t],r)||this.setState({...this.state,[t]:r})}notifyAll(){let t={...this.state};this.setState(t)}use(t,r,o,n){return os(this,t,r,o,n)}};var jo=f(ve(),1);var mo=class extends ns{constructor(t,r={},o){super(t),this.context=r,this.selectors=o}useSyncedValue(t,r){jo.useDebugValue(t);let o=this;we(()=>{o.state[t]!==r&&o.set(t,r)},[o,t,r])}useSyncedValueWithCleanup(t,r){let o=this;we(()=>(o.state[t]!==r&&o.set(t,r),()=>{o.set(t,void 0)}),[o,t,r])}useSyncedValues(t){let r=this,o=Object.values(t);we(()=>{r.update(t)},[r,...o])}useControlledProp(t,r){jo.useDebugValue(t);let o=this,n=r!==void 0;we(()=>{n&&!Object.is(o.state[t],r)&&o.setState({...o.state,[t]:r})},[o,t,r,n])}select(t,r,o,n){let i=this.selectors[t];return i(this.state,r,o,n)}useState(t,r,o,n){return jo.useDebugValue(t),os(this,this.selectors[t],r,o,n)}useContextCallback(t,r){jo.useDebugValue(t);let o=Pe(r??tr);this.context[t]=o}useStateSetter(t){let r=jo.useRef(void 0);return r.current===void 0&&(r.current=o=>{this.set(t,o)}),r.current}observe(t,r){let o;typeof t=="function"?o=t:o=this.selectors[t];let n=o(this.state);return r(n,n,this),this.subscribe(i=>{let s=o(i);if(!Object.is(n,s)){let a=n;n=s,r(s,a,this)}})}};var yw={open:e=>e.open,transitionStatus:e=>e.transitionStatus,domReferenceElement:e=>e.domReferenceElement,referenceElement:e=>e.positionReference??e.referenceElement,floatingElement:e=>e.floatingElement,floatingId:e=>e.floatingId},ho=class extends mo{constructor(t){let{syncOnly:r,nested:o,onOpenChange:n,triggerElements:i,...s}=t;super({...s,positionReference:s.referenceElement,domReferenceElement:s.referenceElement},{onOpenChange:n,dataRef:{current:{}},events:Yf(),nested:o,triggerElements:i},yw),this.syncOnly=r}syncOpenEvent=(t,r)=>{(!t||!this.state.open||r!=null&&Of(r))&&(this.context.dataRef.current.openEvent=t?r:void 0)};dispatchOpenChange=(t,r)=>{this.syncOpenEvent(t,r.event);let o={open:t,reason:r.reason,nativeEvent:r.event,nested:this.context.nested,triggerElement:r.trigger};this.context.events.emit("openchange",o)};setOpen=(t,r)=>{if(this.syncOnly){this.context.onOpenChange?.(t,r);return}this.dispatchOpenChange(t,r),this.context.onOpenChange?.(t,r)}};function Ld(e){let{popupStore:t,treatPopupAsFloatingElement:r=!1,floatingRootContext:o,floatingId:n,nested:i,onOpenChange:s}=e,a=t.useState("open"),u=t.useState("activeTriggerElement"),l=t.useState(r?"popupElement":"positionerElement"),c=t.context.triggerElements,m=s,d=Id.useRef(null);o===void 0&&d.current===null&&(d.current=new ho({open:a,transitionStatus:void 0,referenceElement:u,floatingElement:l,triggerElements:c,onOpenChange:m,floatingId:n,syncOnly:!0,nested:i}));let h=o??d.current;return t.useSyncedValue("floatingId",n),we(()=>{let g={open:a,floatingId:n,referenceElement:u,floatingElement:l};Re(u)&&(g.domReferenceElement=u),h.state.positionReference===h.state.referenceElement&&(g.positionReference=u),h.update(g)},[a,n,u,l,h]),h.context.onOpenChange=m,h.context.nested=i,h}var Md={tabIndex:-1,[Xa]:""};function Vd(e,t=!1){let r=on(),o=Xi()!=null,n=Ct(()=>e(r,o)).current;return Ld({popupStore:n,treatPopupAsFloatingElement:t,floatingRootContext:n.state.floatingRootContext,floatingId:r,nested:o,onOpenChange:n.setOpen}),n}function Dd({handle:e,store:t}){return we(()=>e.attachStore(t),[e,t]),null}function vw(e,t){let r=zo.useRef(null),o=zo.useRef(null);return zo.useCallback(n=>{if(e===void 0)return;let i=!1;if(r.current!==null){let s=r.current,a=o.current,u=t.context.triggerElements.getById(s);a&&u===a&&(t.context.triggerElements.delete(s),i=!0),r.current=null,o.current=null}if(n!==null&&(r.current=e,o.current=n,t.context.triggerElements.add(e,n),i=!0),i){let s=t.context.triggerElements.size;t.select("open")&&t.state.triggerCount!==s&&t.set("triggerCount",s)}},[t,e])}function bw(e,t,r,o=!1){t?e.preventUnmountingOnClose=!1:o&&(e.preventUnmountingOnClose=!0);let n=r?.id??null;(n||t)&&(e.activeTriggerId=n,e.activeTriggerElement=r??null)}function ww(e){let t=!1;return e.preventUnmountOnClose=()=>{t=!0},()=>t}function Bd(e,t,r,o={}){let n=r.reason,i=n===Oe.triggerHover,s=t&&n===Oe.triggerFocus,a=!t&&(n===Oe.triggerPress||n===Oe.escapeKey),u=ww(r);if(e.context.onOpenChange?.(t,r),r.isCanceled)return;o.onBeforeDispatch?.(),e.state.floatingRootContext.dispatchOpenChange(t,r);let l=()=>{let c={...o.extraState,open:t};s?c.instantType="focus":a?c.instantType="dismiss":i&&(c.instantType=void 0),bw(c,t,r.trigger,u()),e.update(c)};i?Nd.flushSync(l):l()}function jd(e,t,r,o){let n=r.useState("isMountedByTrigger",e),i=vw(e,r),s=Pe(u=>{let l=r.select("open"),c=r.select("activeTriggerId");if(c===e){r.update({activeTriggerElement:u,...l?o:null});return}c==null&&l&&r.update({activeTriggerId:e,activeTriggerElement:u,...o})}),a=zo.useCallback(u=>{i(u),u&&s(u)},[i,s]);return we(()=>{n&&r.update({activeTriggerElement:t.current,...o})},[n,r,t,...Object.values(o)]),{registerTrigger:a,isMountedByThisTrigger:n}}function zd(e,t={}){let{closeOnActiveTriggerUnmount:r=!1}=t,o=zo.useRef(null),n=e.useState("open"),i=e.useState("triggerCount"),s=e.useState("activeTriggerId"),a=e.useState("activeTriggerElement");we(()=>{if(!n){o.current=null,e.state.triggerCount!==0&&e.set("triggerCount",0);return}let u=e.context.triggerElements.size,l={};e.state.triggerCount!==u&&(l.triggerCount=u);let c=e.select("activeTriggerId"),m=null;if(c){let d=e.context.triggerElements.getById(c);if(d)o.current=c,d!==e.state.activeTriggerElement&&(l.activeTriggerElement=d);else{for(let[h,g]of e.context.triggerElements.entries())if(g===e.state.activeTriggerElement){l.activeTriggerId=h,l.activeTriggerElement=g,o.current=h;break}l.activeTriggerId===void 0&&(o.current===c?m=c:o.current=null)}}else o.current=null;if(!m&&!c&&u===1){let d=e.context.triggerElements.entries().next();if(!d.done){let[h,g]=d.value;l.activeTriggerId=h,l.activeTriggerElement=g,o.current=h}}(l.triggerCount!==void 0||l.activeTriggerId!==void 0||l.activeTriggerElement!==void 0)&&e.update(l),m&&r&&queueMicrotask(()=>{if(e.select("open")&&e.select("activeTriggerId")===m&&!e.context.triggerElements.getById(m)){let d=De(Oe.none);e.setOpen(!1,d),d.isCanceled||e.update({activeTriggerId:null,activeTriggerElement:null})}})},[n,e,i,s,a,r])}function Hd(e,t,r){let{mounted:o,setMounted:n,transitionStatus:i}=hf(e),s=t.useState("preventUnmountingOnClose"),a=e?!1:s;t.useSyncedValues({mounted:o,transitionStatus:i,preventUnmountingOnClose:a});let u=Pe(()=>{n(!1),t.update({activeTriggerId:null,activeTriggerElement:null,mounted:!1,preventUnmountingOnClose:!1}),r?.(),t.context.onOpenChangeComplete?.(!1)});return zi({enabled:o&&!e&&!a,open:e,ref:t.context.popupRef,onComplete(){e||u()}}),{forceUnmount:u,transitionStatus:i}}function Ud(e,t){e.useSyncedValues(t),we(()=>()=>{e.update({activeTriggerProps:nt,inactiveTriggerProps:nt,popupProps:nt})},[e])}var Ho=class{constructor(){this.idMap=new Map}add(t,r){this.idMap.set(t,r)}delete(t){this.idMap.delete(t)}hasElement(t){for(let r of this.idMap.values())if(r===t)return!0;return!1}hasMatchingElement(t){for(let r of this.idMap.values())if(t(r))return!0;return!1}getById(t){return this.idMap.get(t)}entries(){return this.idMap.entries()}elements(){return this.idMap.values()}get size(){return this.idMap.size}};function Wd(){return new ho({open:!1,transitionStatus:void 0,floatingElement:null,referenceElement:null,triggerElements:new Ho,floatingId:void 0,syncOnly:!1,nested:!1,onOpenChange:void 0})}function Yd(){return{open:!1,openProp:void 0,mounted:!1,transitionStatus:void 0,floatingRootContext:Wd(),floatingId:void 0,triggerCount:0,preventUnmountingOnClose:!1,payload:void 0,activeTriggerId:null,activeTriggerElement:null,triggerIdProp:void 0,popupElement:null,positionerElement:null,activeTriggerProps:nt,inactiveTriggerProps:nt,popupProps:nt}}function qd(e,t,r=!1){return new ho({open:!1,transitionStatus:void 0,floatingElement:null,referenceElement:null,triggerElements:e,floatingId:t,syncOnly:!0,nested:r,onOpenChange:void 0})}var oi=e=>e.triggerIdProp??e.activeTriggerId,yl=e=>e.openProp??e.open,Gd=e=>(e.popupElement?.id??e.floatingId)||void 0;function Zd(e,t){return t!==void 0&&yl(e)&&oi(e)===t}function xw(e,t){return Zd(e,t)?!0:t!==void 0&&yl(e)&&oi(e)==null&&e.triggerCount===1}var Xd={open:yl,mounted:e=>e.mounted,transitionStatus:e=>e.transitionStatus,floatingRootContext:e=>e.floatingRootContext,triggerCount:e=>e.triggerCount,preventUnmountingOnClose:e=>e.preventUnmountingOnClose,payload:e=>e.payload,activeTriggerId:oi,activeTriggerElement:e=>e.mounted?e.activeTriggerElement:null,popupId:Gd,isTriggerActive:(e,t)=>t!==void 0&&oi(e)===t,isOpenedByTrigger:(e,t)=>Zd(e,t),isMountedByTrigger:(e,t)=>t!==void 0&&oi(e)===t&&e.mounted,triggerProps:(e,t)=>t?e.activeTriggerProps:e.inactiveTriggerProps,triggerPopupId:(e,t)=>xw(e,t)?Gd(e):void 0,popupProps:e=>e.popupProps,popupElement:e=>e.popupElement,positionerElement:e=>e.positionerElement};var vl=f(ve(),1),Kd=f(ts(),1);function Jd(e){let t=vl.useCallback(o=>e===void 0?tr:e.subscribeStore(o),[e]),r=vl.useCallback(()=>e===void 0?void 0:e.store,[e]);return(0,Kd.useSyncExternalStore)(t,r,()=>e?.serverStore)}function Qd(e){return Sw(e,e.rootContext)}function Sw(e,t){let{nodeId:r,externalTree:o}=e,n=t.useState("referenceElement"),i=t.useState("floatingElement"),s=t.useState("domReferenceElement"),a=t.useState("open"),u=t.useState("floatingId"),[l,c]=Pt.useState(null),[m,d]=Pt.useState(void 0),[h,g]=Pt.useState(void 0),b=Pt.useRef(null),w=po(o),C=Pt.useMemo(()=>({reference:n,floating:i,domReference:s}),[n,i,s]),x=bd({...e,elements:{...C,...l&&{reference:l}}}),v=Re(m)?m:null,_=h===void 0?t.state.floatingElement:h;t.useSyncedValue("referenceElement",m??null),t.useSyncedValue("domReferenceElement",m===void 0?s:v),t.useSyncedValue("floatingElement",_);let k=Pt.useCallback(D=>{let S=Re(D)?{getBoundingClientRect:()=>D.getBoundingClientRect(),getClientRects:()=>D.getClientRects(),contextElement:D}:D;c(S),x.refs.setReference(S)},[x.refs]),E=Pt.useCallback(D=>{(Re(D)||D===null)&&(b.current=D,d(D)),(Re(x.refs.reference.current)||x.refs.reference.current===null||D!==null&&!Re(D))&&x.refs.setReference(D)},[x.refs,d]),T=Pt.useCallback(D=>{g(D),x.refs.setFloating(D)},[x.refs]),O=Pt.useMemo(()=>({...x.refs,setReference:E,setFloating:T,setPositionReference:k,domReference:b}),[x.refs,E,T,k]),I=Pt.useMemo(()=>({...x.elements,domReference:s}),[x.elements,s]),J=Pt.useMemo(()=>({...x,dataRef:t.context.dataRef,open:a,onOpenChange:t.setOpen,events:t.context.events,floatingId:u,refs:O,elements:I,nodeId:r,rootStore:t}),[x,O,I,r,t,a,u]);return we(()=>{s&&(b.current=s)},[s]),we(()=>{t.context.dataRef.current.floatingContext=J;let D=w?.nodesRef.current.find(S=>S.id===r);D&&(D.context=J)}),Pt.useMemo(()=>({...x,context:J,refs:O,elements:I,rootStore:t}),[x,O,I,J,t])}var Mr=f(ve(),1);var bl=Zr.os.mac&&Zr.engine.webkit;function wl(e,t={}){let{enabled:r=!0,delay:o}=t,n="rootStore"in e?e.rootStore:e,{events:i,dataRef:s}=n.context,a=Mr.useRef(!1),u=Mr.useRef(null),l=Mr.useRef(!0),c=xr();Mr.useEffect(()=>{let d=n.select("domReferenceElement");if(!r)return;let h=it(d);function g(){let C=n.select("domReferenceElement");!n.select("open")&&_t(C)&&C===Hi(Rt(C))&&(a.current=!0)}function b(){l.current=!0}function w(){l.current=!1}return Sr(ze(h,"blur",g),bl&&ze(h,"keydown",b,!0),bl&&ze(h,"pointerdown",w,!0))},[n,r]),Mr.useEffect(()=>{if(!r)return;function d(h){if(h.reason===Oe.triggerPress||h.reason===Oe.escapeKey){let g=n.select("domReferenceElement");Re(g)&&(u.current=g,a.current=!0)}}return i.on("openchange",d),()=>{i.off("openchange",d)}},[i,r,n]);let m=Mr.useMemo(()=>{function d(){a.current=!1,u.current=null}return{onMouseLeave(){d()},onFocus(h){let g=h.currentTarget;if(a.current){if(u.current===g)return;d()}let b=Nt(h.nativeEvent);if(Re(b)){if(bl&&!h.relatedTarget){if(!l.current&&!Ff(b))return}else if(!Af(b))return}let w=co(h.relatedTarget,n.context.triggerElements),{nativeEvent:C,currentTarget:x}=h,v=typeof o=="function"?o():o;if(n.select("open")&&w||v===0||v===void 0){n.setOpen(!0,De(Oe.triggerFocus,C,x));return}c.start(v,()=>{a.current||n.setOpen(!0,De(Oe.triggerFocus,C,x))})},onBlur(h){d();let g=h.relatedTarget,b=h.nativeEvent,w=Re(g)&&g.hasAttribute(cn("focus-guard"))&&g.getAttribute("data-type")==="outside";c.start(0,()=>{let C=n.select("domReferenceElement"),x=Hi(Rt(C));!g&&x===C||Ge(s.current.floatingContext?.refs.floating.current,x)||Ge(C,x)||w||co(g??x,n.context.triggerElements)||n.setOpen(!1,De(Oe.triggerFocus,b))})}}},[s,o,n,c]);return Mr.useMemo(()=>r?{reference:m,trigger:m}:{},[r,m])}var Sl=f(ve(),1);var xl=class e{constructor(){this.pointerType=void 0,this.interactedInside=!1,this.handler=void 0,this.blockMouseMove=!0,this.performedPointerEventsMutation=!1,this.pointerEventsScopeElement=null,this.pointerEventsReferenceElement=null,this.pointerEventsFloatingElement=null,this.restTimeoutPending=!1,this.openChangeTimeout=new rr,this.restTimeout=new rr,this.handleCloseOptions=void 0}static create(){return new e}dispose=()=>{this.openChangeTimeout.clear(),this.restTimeout.clear()};disposeEffect=()=>this.dispose},is=new WeakMap;function dn(e){if(!e.performedPointerEventsMutation)return;let t=e.pointerEventsScopeElement;t&&is.get(t)===e&&(e.pointerEventsScopeElement?.style.removeProperty("pointer-events"),e.pointerEventsReferenceElement?.style.removeProperty("pointer-events"),e.pointerEventsFloatingElement?.style.removeProperty("pointer-events"),is.delete(t)),e.performedPointerEventsMutation=!1,e.pointerEventsScopeElement=null,e.pointerEventsReferenceElement=null,e.pointerEventsFloatingElement=null}function ss(e,t){let{scopeElement:r,referenceElement:o,floatingElement:n}=t,i=is.get(r);i&&i!==e&&dn(i),dn(e),e.performedPointerEventsMutation=!0,e.pointerEventsScopeElement=r,e.pointerEventsReferenceElement=o,e.pointerEventsFloatingElement=n,is.set(r,e),r.style.pointerEvents="none",o.style.pointerEvents="auto",n.style.pointerEvents="auto"}function pn(e){let t=e.context.dataRef.current,r=Ct(()=>t.hoverInteractionState??xl.create()).current;return t.hoverInteractionState||(t.hoverInteractionState=r),nn(t.hoverInteractionState.disposeEffect),t.hoverInteractionState}function Cl(e,t={}){let{enabled:r=!0,closeDelay:o=0,nodeId:n}=t,i="rootStore"in e?e.rootStore:e,s=i.useState("open"),a=i.useState("floatingElement"),u=i.useState("domReferenceElement"),{dataRef:l}=i.context,c=po(),m=Xi(),d=pn(i),h=xr(),g=Pe(()=>Wi(l.current.openEvent?.type,d.interactedInside)),b=Pe(()=>If(l.current.openEvent?.type)),w=Pe(()=>{dn(d)});we(()=>{s||(d.pointerType=void 0,d.restTimeoutPending=!1,d.interactedInside=!1,w())},[s,d,w]),Sl.useEffect(()=>w,[w]),we(()=>{if(r&&s&&d.handleCloseOptions?.blockPointerEvents&&b()&&Re(u)&&a){let C=u,x=a,v=Rt(a),_=c?.nodesRef.current.find(O=>O.id===m)?.context?.elements.floating;_&&(_.style.pointerEvents="");let k=d.pointerEventsScopeElement!==x?d.pointerEventsScopeElement:null,E=_!==x?_:null,T=d.handleCloseOptions?.getScope?.()??k??E??C.closest("[data-rootownerid]")??v.body;return ss(d,{scopeElement:T,referenceElement:C,floatingElement:x}),()=>{w()}}},[r,s,u,a,d,b,c,m,w]),Sl.useEffect(()=>{if(!r)return;function C(){return!!(c&&m&&Kr(c.nodesRef.current,m).length>0)}function x(O){let I=cr(o,"close",d.pointerType),J=()=>{i.setOpen(!1,De(Oe.triggerHover,O)),c?.events.emit("floating.closed",O)};I?d.openChangeTimeout.start(I,J):(d.openChangeTimeout.clear(),J())}function v(O){let I=Nt(O);if(!Ja(I)){d.interactedInside=!1;return}d.interactedInside=I?.closest("[aria-haspopup]")!=null}function _(){d.openChangeTimeout.clear(),h.clear(),c?.events.off("floating.closed",E),w()}function k(O){if(C()&&c){c.events.on("floating.closed",E);return}if(co(O.relatedTarget,i.context.triggerElements))return;let I=l.current.floatingContext?.nodeId??n,J=O.relatedTarget;if(!(c&&I&&Re(J)&&Kr(c.nodesRef.current,I,!1).some(S=>Ge(S.context?.elements.floating,J)))){if(d.handler){d.handler(O);return}w(),b()&&!g()&&x(O)}}function E(O){!c||!m||C()||h.start(0,()=>{c.events.off("floating.closed",E),i.setOpen(!1,De(Oe.triggerHover,O)),c.events.emit("floating.closed",O)})}let T=a;return Sr(T&&ze(T,"mouseenter",_),T&&ze(T,"mouseleave",k),T&&ze(T,"pointerdown",v,!0),()=>{c?.events.off("floating.closed",E)})},[r,a,i,l,o,n,b,g,w,d,c,m,h])}var go=f(ve(),1),$d=f(lo(),1);var Cw={current:null};function _l(e,t={}){let{enabled:r=!0,delay:o=0,handleClose:n=null,mouseOnly:i=!1,restMs:s=0,move:a=!0,triggerElementRef:u=Cw,externalTree:l,isActiveTrigger:c=!0,getHandleCloseContext:m,isClosing:d,shouldOpen:h,guardStaleOpen:g=!1}=t,b="rootStore"in e?e.rootStore:e,{dataRef:w,events:C}=b.context,x=po(l),v=pn(b),_=go.useRef(!1),k=Yt(n),E=Yt(o),T=Yt(s),O=Yt(r),I=Yt(h),J=Yt(d),D=Pe(()=>Wi(w.current.openEvent?.type,v.interactedInside)),S=Pe(()=>I.current?.()!==!1),L=Pe((N,q,U)=>{let R=b.context.triggerElements;if(R.hasElement(q))return!N||!Ge(N,q);if(!Re(U))return!1;let B=U;return R.hasMatchingElement(re=>Ge(re,B))&&(!N||!Ge(N,B))}),Y=Pe(()=>{if(!v.handler)return;Rt(b.select("domReferenceElement")).removeEventListener("mousemove",v.handler),v.handler=void 0}),A=Pe(()=>{dn(v)});return c&&(v.handleCloseOptions=k.current?.__options),go.useEffect(()=>Y,[Y]),go.useEffect(()=>{if(!r)return;function N(q){q.open?_.current=!1:(_.current=q.reason===Oe.triggerHover,Y(),v.openChangeTimeout.clear(),v.restTimeout.clear(),v.blockMouseMove=!0,v.restTimeoutPending=!1)}return C.on("openchange",N),()=>{C.off("openchange",N)}},[r,C,v,Y]),go.useEffect(()=>{if(!r)return;function N(P,W=!0){let ne=cr(E.current,"close",v.pointerType);ne?v.openChangeTimeout.start(ne,()=>{b.setOpen(!1,De(Oe.triggerHover,P)),x?.events.emit("floating.closed",P)}):W&&(v.openChangeTimeout.clear(),b.setOpen(!1,De(Oe.triggerHover,P)),x?.events.emit("floating.closed",P))}let q=u.current??(c?b.select("domReferenceElement"):null);if(!Re(q))return;function U(P){if(v.openChangeTimeout.clear(),v.blockMouseMove=!1,i&&!Xr(v.pointerType))return;let W=Qa(T.current),ne=cr(E.current,"open",v.pointerType),xe=Nt(P),se=P.currentTarget??null,be=b.select("domReferenceElement"),ye=se;if(Re(xe)&&!b.context.triggerElements.hasElement(xe)){for(let H of b.context.triggerElements.elements())if(Ge(H,xe)){ye=H;break}}Re(se)&&Re(be)&&!b.context.triggerElements.hasElement(se)&&Ge(se,be)&&(ye=be);let $=ye==null?!1:L(be,ye,xe),_e=b.select("open"),Fe=J.current?.()??b.select("transitionStatus")==="ending",xt=!_e&&Fe&&_.current,Le=!$&&Re(ye)&&Re(be)&&Ge(be,ye)&&xt,X=W>0&&!ne,M=$&&(_e||xt)||Le,K=!_e||$;if(M){S()&&b.setOpen(!0,De(Oe.triggerHover,P,ye));return}X||(ne?v.openChangeTimeout.start(ne,()=>{K&&S()&&b.setOpen(!0,De(Oe.triggerHover,P,ye))}):K&&S()&&b.setOpen(!0,De(Oe.triggerHover,P,ye)))}function R(P){if(D()){A();return}Y();let W=b.select("domReferenceElement"),ne=Rt(W);v.restTimeout.clear(),v.restTimeoutPending=!1;let xe=w.current.floatingContext??m?.();if(co(P.relatedTarget,b.context.triggerElements))return;if(k.current&&xe){b.select("open")||v.openChangeTimeout.clear();let be=u.current;v.handler=k.current({...xe,tree:x,x:P.clientX,y:P.clientY,onClose(){A(),Y(),O.current&&!D()&&be===b.select("domReferenceElement")&&N(P,!0)}}),ne.addEventListener("mousemove",v.handler),v.handler(P);return}(v.pointerType!=="touch"||!Ge(b.select("floatingElement"),P.relatedTarget))&&N(P)}function B(P){Ge(q,P.relatedTarget)||(v.openChangeTimeout.clear(),v.restTimeout.clear(),v.restTimeoutPending=!1)}let re=g?ze(q,"mouseout",B):void 0;return a?Sr(ze(q,"mousemove",U,{once:!0}),ze(q,"mouseenter",U),ze(q,"mouseleave",R),re):Sr(ze(q,"mouseenter",U),ze(q,"mouseleave",R),re)},[Y,A,w,E,b,r,k,v,c,L,D,i,a,T,u,x,O,m,J,S,g]),go.useMemo(()=>{if(!r)return;function N(q){v.pointerType=q.pointerType}return{onPointerDown:N,onPointerEnter:N,onMouseMove(q){let{nativeEvent:U}=q,R=q.currentTarget,B=b.select("domReferenceElement"),re=b.select("open"),P=L(B,R,q.target);if(i&&!Xr(v.pointerType))return;if(re&&P&&v.handleCloseOptions?.blockPointerEvents){let xe=b.select("floatingElement");if(xe){let se=v.handleCloseOptions?.getScope?.()??R.ownerDocument.body;ss(v,{scopeElement:se,referenceElement:R,floatingElement:xe})}}let W=Qa(T.current);if(re&&!P||W===0||!P&&v.restTimeoutPending&&q.movementX**2+q.movementY**2<2)return;v.restTimeout.clear();function ne(){if(v.restTimeoutPending=!1,D())return;let xe=b.select("open");!v.blockMouseMove&&(!xe||P)&&S()&&b.setOpen(!0,De(Oe.triggerHover,U,R))}v.pointerType==="touch"?$d.flushSync(()=>{ne()}):P&&re?ne():(v.restTimeoutPending=!0,v.restTimeout.start(W,ne))}}},[r,v,D,L,i,b,T,S])}var ep=.1,_w=ep*ep,Xe=.5;function as(e,t,r,o,n,i){return o>=t!=i>=t&&e<=(n-r)*(t-o)/(i-o)+r}function ls(e,t,r,o,n,i,s,a,u,l){let c=!1;return as(e,t,r,o,n,i)&&(c=!c),as(e,t,n,i,s,a)&&(c=!c),as(e,t,s,a,u,l)&&(c=!c),as(e,t,u,l,r,o)&&(c=!c),c}function Rw(e,t,r){return e>=r.x&&e<=r.x+r.width&&t>=r.y&&t<=r.y+r.height}function cs(e,t,r,o,n,i){let s=Math.min(r,n),a=Math.max(r,n),u=Math.min(o,i),l=Math.max(o,i);return e>=s&&e<=a&&t>=u&&t<=l}function Rl(e={}){let{blockPointerEvents:t=!1}=e,r=new rr,o=({x:n,y:i,placement:s,elements:a,onClose:u,nodeId:l,tree:c})=>{let m=s?.split("-")[0],d=!1,h=null,g=null,b=typeof performance<"u"?performance.now():0;function w(x,v){let _=performance.now(),k=_-b;if(h===null||g===null||k===0)return h=x,g=v,b=_,!1;let E=x-h,T=v-g,O=E*E+T*T,I=k*k*_w;return h=x,g=v,b=_,O0)}function L(){S()||C()}if(S())return;let Y=_.getBoundingClientRect(),A=k.getBoundingClientRect(),N=n>A.right-A.width/2,q=i>A.bottom-A.height/2,U=A.width>Y.width,R=A.height>Y.height,B=(U?Y:A).left,re=(U?Y:A).right,P=(R?Y:A).top,W=(R?Y:A).bottom;if(m==="top"&&i>=Y.bottom-1||m==="bottom"&&i<=Y.top+1||m==="left"&&n>=Y.right-1||m==="right"&&n<=Y.left+1){L();return}let ne=!1;switch(m){case"top":ne=cs(E,T,B,Y.top+1,re,A.bottom-1);break;case"bottom":ne=cs(E,T,B,A.top+1,re,Y.bottom-1);break;case"left":ne=cs(E,T,A.right-1,W,Y.left+1,P);break;case"right":ne=cs(E,T,Y.right-1,W,A.left+1,P);break;default:}if(ne)return;if(d&&!Rw(E,T,Y)){L();return}if(!I&&w(E,T)){L();return}let xe=!1;switch(m){case"top":{let se=U?Xe/2:Xe*4,be=U||N?n+se:n-se,ye=U?n-se:N?n+se:n-se,$=i+Xe+1,_e=N||U?A.bottom-Xe:A.top,Fe=N?U?A.bottom-Xe:A.top:A.bottom-Xe;xe=ls(E,T,be,$,ye,$,A.left,_e,A.right,Fe);break}case"bottom":{let se=U?Xe/2:Xe*4,be=U||N?n+se:n-se,ye=U?n-se:N?n+se:n-se,$=i-Xe,_e=N||U?A.top+Xe:A.bottom,Fe=N?U?A.top+Xe:A.bottom:A.top+Xe;xe=ls(E,T,be,$,ye,$,A.left,_e,A.right,Fe);break}case"left":{let se=R?Xe/2:Xe*4,be=R||q?i+se:i-se,ye=R?i-se:q?i+se:i-se,$=n+Xe+1,_e=q||R?A.right-Xe:A.left,Fe=q?R?A.right-Xe:A.left:A.right-Xe;xe=ls(E,T,_e,A.top,Fe,A.bottom,$,be,$,ye);break}case"right":{let se=R?Xe/2:Xe*4,be=R||q?i+se:i-se,ye=R?i-se:q?i+se:i-se,$=n-Xe,_e=q||R?A.left+Xe:A.right,Fe=q?R?A.left+Xe:A.right:A.left+Xe;xe=ls(E,T,$,be,$,ye,_e,A.top,Fe,A.bottom);break}default:}xe?d||r.start(40,L):L()}};return o.__options={...e,blockPointerEvents:t},o}var us=class extends mo{setState(t){}update(t){}set(t,r){}notifyAll(){}};var zk=(function(e){return e.open="data-open",e.closed="data-closed",e[e.startingStyle=ja.startingStyle]="startingStyle",e[e.endingStyle=ja.endingStyle]="endingStyle",e.anchorHidden="data-anchor-hidden",e.side="data-side",e.align="data-align",e})({});var Ew={"data-popup-open":""};var Tw={"data-open":""},Pw={"data-closed":""},Ow={"data-anchor-hidden":""},tp={open(e){return e?Ew:null}};var ni={open(e){return e?Tw:Pw},anchorHidden(e){return e?Ow:null}},rp={...ni,...gf};function op(e){return rn(19)?e:e?"true":void 0}var fs=f(ve(),1),El=fs.createContext(void 0);function mn(){return fs.useContext(El)?.direction??"ltr"}var nr=f(ve(),1);var kw=e=>({name:"arrow",options:e,async fn(t){let{x:r,y:o,placement:n,rects:i,platform:s,elements:a,middlewareData:u}=t,{element:l,padding:c=0,offsetParent:m="real"}=Nr(e,t)||{};if(l==null)return{};let d=Zi(c),h={x:r,y:o},g=ti(n),b=ei(g),w=await s.getDimensions(l),C=g==="y",x=C?"top":"left",v=C?"bottom":"right",_=C?"clientHeight":"clientWidth",k=i.reference[b]+i.reference[g]-h[g]-i.floating[b],E=h[g]-i.reference[g],T=m==="real"?await s.getOffsetParent?.(l):a.floating,O=a.floating[_]||i.floating[b];(!O||!await s.isElement?.(T))&&(O=a.floating[_]||i.floating[b]);let I=k/2-E/2,J=O/2-w[b]/2-1,D=Math.min(d[x],J),S=Math.min(d[v],J),L=D,Y=O-w[b]-S,A=O/2-w[b]/2+I,N=Yi(L,A,Y),q=!u.arrow&&_r(n)!=null&&A!==N&&i.reference[b]/2-(A({...kw(e),options:[e,t]});var ip={name:"hide",async fn(e){let{width:t,height:r,x:o,y:n}=e.rects.reference,i=t===0&&r===0&&o===0&&n===0,s=await e.platform.detectOverflow(e,{elementContext:"reference"});return{data:{referenceHidden:s.top-r>=0||s.right-t>=0||s.bottom-r>=0||s.left-t>=0||i}}}};var hn={sideX:"left",sideY:"top"};var sp="--available-width",ap="--available-height";function up(e,t,r){let o=e==="inline-start"||e==="inline-end";return{top:"top",right:o?r?"inline-start":"inline-end":"right",bottom:"bottom",left:o?r?"inline-end":"inline-start":"left"}[t]}function lp(e,t,r){let{rects:o,placement:n}=e;return{side:up(t,Tt(n),r),align:_r(n)||"center",anchor:{width:o.reference.width,height:o.reference.height},positioner:{width:o.floating.width,height:o.floating.height}}}function fp(e){return Fw(e,Qd)}function Fw(e,t){let{anchor:r,positionMethod:o="absolute",side:n="bottom",sideOffset:i=0,align:s="center",alignOffset:a=0,collisionBoundary:u,collisionPadding:l=5,sticky:c=!1,arrowPadding:m=5,disableAnchorTracking:d=!1,inline:h,keepMounted:g=!1,floatingRootContext:b,mounted:w,collisionAvoidance:C,shift:x,nodeId:v,adaptiveOrigin:_,lazyFlip:k=!1,externalTree:E}=e,[T,O]=nr.useState(null);!w&&T!==null&&O(null);let I=C.side||"flip",J=C.align||"flip",D=C.fallbackAxisSide||"end",S=x?.crossAxis??!1,L=x?.rootBoundary,Y=typeof r=="function"?r:void 0,A=Pe(Y),N=Y?A:r,q=Yt(r),U=Yt(w),B=mn()==="rtl",re=T||{top:"top",right:"right",bottom:"bottom",left:"left","inline-end":B?"left":"right","inline-start":B?"right":"left"}[n],P=s==="center"?re:`${re}-${s}`,W=l;typeof W=="number"?W={top:W,right:W,bottom:W,left:W}:W&&(W={top:W.top||0,right:W.right||0,bottom:W.bottom||0,left:W.left||0});let ne=1,xe=n==="bottom"?ne:0,se=n==="top"?ne:0,be=n==="right"?ne:0,ye=n==="left"?ne:0,$={boundary:u==="clipping-ancestors"?"clippingAncestors":u,padding:W},_e=nr.useRef(null),Fe=Yt(i),xt=Yt(a),Le=typeof i!="function"?i:0,X=typeof a!="function"?a:0,M=[];h&&M.push(h),M.push(al(G=>{let y=lp(G,n,B),oe=typeof Fe.current=="function"?Fe.current(y):Fe.current,Ae=typeof xt.current=="function"?xt.current(y):xt.current;return{mainAxis:oe,crossAxis:Ae,alignmentAxis:Ae}},[Le,X,B,n]));let K=J==="none"&&I!=="shift",H=!K&&(c||S||I==="shift"),Q=I==="none"?null:ul({...$,padding:{top:W.top+ne+xe,right:W.right+ne+ye,bottom:W.bottom+ne+se,left:W.left+ne+be},mainAxis:!S&&I==="flip",crossAxis:J==="flip"?"alignment":!1,fallbackAxisSideDirection:D}),pe=K?null:ll({...$,rootBoundary:L,mainAxis:J!=="none",crossAxis:H,limiter:c||S?void 0:cl(G=>{if(!_e.current)return{};let{width:y,height:oe}=_e.current.getBoundingClientRect(),Ae=qt(Tt(G.placement)),ee=Ae==="y"?y:oe,Qe=Ae==="y"?W.left+W.right:W.top+W.bottom;return{offset:ee/2+Qe/2}})},[$,c,S,L,W,J]);I==="shift"||J==="shift"||s==="center"?M.push(pe,Q):M.push(Q,pe),M.push(fl({...$,apply({elements:{floating:G},availableWidth:y,availableHeight:oe,rects:Ae}){if(!U.current)return;let ee=G.style;ee.setProperty(sp,`${y}px`),ee.setProperty(ap,`${oe}px`);let Qe=it(G).devicePixelRatio||1,{x:ie,y:Je,width:j,height:z}=Ae.reference,vr=(Math.round((ie+j)*Qe)-Math.round(ie*Qe))/Qe,je=(Math.round((Je+z)*Qe)-Math.round(Je*Qe))/Qe;ee.setProperty("--anchor-width",`${vr}px`),ee.setProperty("--anchor-height",`${je}px`)}}),np(G=>({element:_e.current||Rt(G.elements.floating).createElement("div"),padding:m,offsetParent:"floating"}),[m]),{name:"transformOrigin",fn(G){let{elements:y,middlewareData:oe,placement:Ae,rects:ee,y:Qe}=G,ie=Tt(Ae),Je=qt(ie),j=_e.current,z=oe.arrow?.x||0,vr=oe.arrow?.y||0,je=j?.clientWidth||0,ce=j?.clientHeight||0,br=z+je/2,Or=vr+ce/2,et=Math.abs(oe.shift?.y||0),Me=ee.reference.height/2,$e=typeof i=="function"?i(lp(G,n,B)):i,ut=et>$e,pt={top:`${br}px calc(100% + ${$e}px)`,bottom:`${br}px ${-$e}px`,left:`calc(100% + ${$e}px) ${Or}px`,right:`${-$e}px ${Or}px`}[ie],wr=`${br}px ${ee.reference.y+Me-Qe}px`;return y.floating.style.setProperty("--transform-origin",H&&Je==="y"&&ut?wr:pt),{}}},ip,_),we(()=>{!w&&b&&b.update({referenceElement:null,floatingElement:null,domReferenceElement:null,positionReference:null})},[w,b]);let le=nr.useMemo(()=>({elementResize:!d&&typeof ResizeObserver<"u",layoutShift:!d&&typeof IntersectionObserver<"u"}),[d]),{refs:fe,elements:me,x:he,y:V,middlewareData:te,update:Ne,placement:He,context:ot,isPositioned:Ze,floatingStyles:Be}=t({rootContext:b,open:g?w:void 0,placement:P,middleware:M,strategy:o,whileElementsMounted:g?void 0:(...G)=>ri(...G,le),nodeId:v,externalTree:E}),{sideX:Ue,sideY:ct}=te.adaptiveOrigin||hn,Se=Ze?o:"fixed",Pr=nr.useMemo(()=>{let G;return Ze?_?G={position:Se,[Ue]:he,[ct]:V}:G={...Be,position:Se}:G={position:Se,top:0,left:0},G[sp]="100vw",G[ap]="100vh",Ze||(G.opacity=0),G},[_,Se,Ue,he,ct,V,Be,Ze]),$t=nr.useRef(null);we(()=>{if(!w)return;let G=q.current,y=typeof G=="function"?G():G,Ae=(cp(y)?y.current:y)||null||null;Ae!==$t.current&&(fe.setPositionReference(Ae),$t.current=Ae)},[w,fe,N,q]),nr.useEffect(()=>{if(!w)return;let G=q.current;typeof G!="function"&&cp(G)&&G.current!==$t.current&&(fe.setPositionReference(G.current),$t.current=G.current)},[w,fe,N,q]),nr.useEffect(()=>{if(g&&w&&me.reference&&me.floating)return ri(me.reference,me.floating,Ne,le)},[g,w,me,Ne,le]);let Ye=Tt(He),Yr=up(n,Ye,B),St=_r(He)||"center",kt=!!te.hide?.referenceHidden;we(()=>{k&&w&&Ze&&Ye!==re&&O(Ye)},[k,w,Ze,Ye,re]);let vt=nr.useMemo(()=>({position:"absolute",top:te.arrow?.y,left:te.arrow?.x}),[te.arrow]),F=te.arrow?.centerOffset!==0;return nr.useMemo(()=>({positionerStyles:Pr,arrowStyles:vt,arrowRef:_e,arrowUncentered:F,side:Yr,align:St,physicalSide:Ye,anchorHidden:kt,refs:fe,context:ot,isPositioned:Ze,update:Ne}),[Pr,vt,_e,F,Yr,St,Ye,kt,fe,ot,Ze,Ne])}function cp(e){return e!=null&&"current"in e}function ds(e){return e==="starting"?zf:nt}function dp(e,t,{styles:r,transitionStatus:o,props:n,refs:i,hidden:s,inert:a=!1}){let u={...r};return a&&(u.pointerEvents="none"),Gt("div",e,{state:t,ref:i,props:[{role:"presentation",hidden:s,style:u},ds(o),n],stateAttributesMapping:ni})}var Et=f(ve(),1),xp=f(lo(),1);var pp=f(ve(),1);function mp(e){let[t,r]=pp.useState({current:e,previous:null});return Object.is(e,t.current)||r({current:e,previous:t.current}),t.previous}var gn=f(ve(),1);function Tl(e){let t=Lt(e),r=parseFloat(t.width)||0,o=parseFloat(t.height)||0,n=_t(e),i=n?e.offsetWidth:r,s=n?e.offsetHeight:o;return(fo(r)!==i||fo(o)!==s)&&(r=i,o=s),{width:r,height:o}}function gp(e){let{popupElement:t,positionerElement:r,content:o,mounted:n,onMeasureLayout:i,onMeasureLayoutComplete:s,side:a,direction:u}=e,l=ln(t,!0),c=sn(),m=gn.useRef(null),d=gn.useRef(!0),h=gn.useRef(tr),g=Pe(i),b=Pe(s),w=gn.useMemo(()=>Aw(a,u),[a,u]);we(()=>{if(!n){h.current=tr,d.current=!0,m.current=null;return}if(!t||!r)return;h.current=hp(t,w),Pl(t,"auto");let C=ms(t,"position","static"),x=ms(t,"transform","none"),v=ms(t,"scale","1"),_=hp(r,{"--available-width":"max-content","--available-height":"max-content"});function k(){C(),x(),_()}function E(){k(),v()}if(g?.(),d.current||m.current===null){ps(r,"max-content");let J=Tl(t);return m.current=J,ps(r,J),E(),b?.(null,J),d.current=!1,()=>{h.current(),h.current=tr}}ps(r,"max-content");let T=m.current,O=Tl(t);m.current=O,Pl(t,T),E(),b?.(T,O),ps(r,O);let I=new AbortController;return c.request(()=>{Pl(t,O),l(()=>{t.style.setProperty("--popup-width","auto"),t.style.setProperty("--popup-height","auto")},I.signal)}),()=>{I.abort(),c.cancel(),h.current(),h.current=tr}},[o,t,r,l,c,n,g,b,w])}function Aw(e,t){let r=e==="top",o=e==="left"||e===(t==="rtl"?"inline-end":"inline-start");return!r&&!o?nt:{position:"absolute",[r?"bottom":"top"]:"0",[o?"right":"left"]:"0"}}function ms(e,t,r){let o=e.style.getPropertyValue(t);return e.style.setProperty(t,r),()=>{e.style.setProperty(t,o)}}function hp(e,t){let r=[];for(let[o,n]of Object.entries(t))r.push(ms(e,o,n));return r.length?()=>{r.forEach(o=>o())}:tr}function Pl(e,t){let r=t==="auto"?"auto":`${t.width}px`,o=t==="auto"?"auto":`${t.height}px`;e.style.setProperty("--popup-width",r),e.style.setProperty("--popup-height",o)}function ps(e,t){let r=t==="max-content"?"max-content":`${t.width}px`,o=t==="max-content"?"max-content":`${t.height}px`;e.style.setProperty("--positioner-width",r),e.style.setProperty("--positioner-height",o)}var yp=f(ve(),1);var vp=f(Z(),1),hs=function(t){let{direction:r="ltr"}=t,o=yp.useMemo(()=>({direction:r}),[r]);return(0,vp.jsx)(El.Provider,{value:o,children:t.children})};var bp={name:"adaptiveOrigin",async fn(e){let{x:t,y:r,rects:{floating:o},elements:{floating:n},platform:i,strategy:s,placement:a}=e,u=it(n),l=u.getComputedStyle(n);if(!(l.transitionDuration!=="0s"&&l.transitionDuration!==""))return{x:t,y:r,data:hn};let m=await i.getOffsetParent?.(n),d={width:0,height:0};if(s==="fixed"&&u?.visualViewport)d={width:u.visualViewport.width,height:u.visualViewport.height};else if(m===u){let x=Rt(n);d={width:x.documentElement.clientWidth,height:x.documentElement.clientHeight}}else await i.isElement?.(m)&&(d=await i.getDimensions(m));let h=Tt(a),g=t,b=r;h==="left"&&(g=d.width-(t+o.width)),h==="top"&&(b=d.height-(r+o.height));let w=h==="left"?"right":hn.sideX,C=h==="top"?"bottom":hn.sideY;return{x:g,y:b,data:{sideX:w,sideY:C}}}};var yn=f(Z(),1),Sp={activationDirection:e=>e?{"data-activation-direction":e}:null};function Cp(e){let{store:t,side:r,children:o}=e,n=mn(),i=t.useState("activeTriggerElement"),s=t.useState("activeTriggerId"),a=t.useState("open"),u=t.useState("payload"),l=t.useState("mounted"),c=t.useState("popupElement"),m=t.useState("positionerElement"),d=mp(a?i:null),h=Nw(s,u),g=Et.useRef(null),[b,w]=Et.useState(null),[C,x]=Et.useState(null),v=Et.useRef(null),_=Et.useRef(null),k=ln(v,!0),E=sn(),T=Et.useRef(null),[O,I]=Et.useState(null),[J,D]=Et.useState(!1);we(()=>(t.set("adaptiveOrigin",bp),()=>{t.set("adaptiveOrigin",void 0)}),[t]);let S=Pe(()=>{v.current?.style.setProperty("animation","none"),v.current?.style.setProperty("transition","none"),_.current?.style.setProperty("display","none")}),L=Pe(R=>{v.current?.style.removeProperty("animation"),v.current?.style.removeProperty("transition"),_.current?.style.removeProperty("display"),R&&I(R)}),Y=Pe(()=>{T.current?.abort();let R=new AbortController;T.current=R,k(()=>{w(null),I(null),g.current=null},R.signal)}),A=Et.useRef(null);we(()=>{(!a||!l)&&(A.current=null)},[a,l]),we(()=>{if(i&&d&&i!==d&&A.current!==i&&g.current){w(g.current),D(!0);let R=Lw(d,i);x(R),A.current=i}},[i,d]),we(()=>{b!=null&&(T.current?.abort(),D(!0),E.request(()=>{xp.flushSync(()=>{D(!1)}),Y()}))},[h,b,Y,E]),we(()=>{let R=v.current;if(!R)return;let B=Rt(R).createElement("div");for(let re of Array.from(R.childNodes))B.appendChild(re.cloneNode(!0));g.current=B});let N=b!=null,q;N?q=(0,yn.jsxs)(Et.Fragment,{children:[(0,yn.jsx)("div",{"data-previous":!0,inert:op(!0),ref:_,style:{...O?{"--popup-width":`${O.width}px`,"--popup-height":`${O.height}px`}:null,position:"absolute"},"data-ending-style":J?void 0:""},"previous"),(0,yn.jsx)("div",{"data-current":!0,ref:v,"data-starting-style":J?"":void 0,children:o},h)]}):q=(0,yn.jsx)("div",{"data-current":!0,ref:v,children:o},h),we(()=>{let R=_.current;!R||!b||R.replaceChildren(...Array.from(b.childNodes))},[b]),gp({popupElement:c,positionerElement:m,mounted:l,content:u,onMeasureLayout:S,onMeasureLayoutComplete:L,side:r,direction:n});let U={activationDirection:Iw(C),transitioning:N};return{children:q,state:U}}function Iw(e){if(e)return`${wp(e.horizontal,5,"right","left")} ${wp(e.vertical,5,"down","up")}`}function wp(e,t,r,o){return e>t?r:e<-t?o:""}function Lw(e,t){let r=e.getBoundingClientRect(),o=t.getBoundingClientRect(),n={x:r.left+r.width/2,y:r.top+r.height/2},i={x:o.left+o.width/2,y:o.top+o.height/2};return{horizontal:i.x-n.x,vertical:i.y-n.y}}function Nw(e,t){let[r,o]=Et.useState(0),n=Et.useRef(e),i=Et.useRef(t),s=Et.useRef(!1);return we(()=>{let a=n.current,u=i.current,l=e!==a,c=t!==u;l?(o(m=>m+1),s.current=!c):s.current&&c&&(o(m=>m+1),s.current=!1),n.current=e,i.current=t},[e,t]),`${e??"current"}-${r}`}var gs=f(ve(),1),_p=f(lo(),1);var Rp=f(Z(),1),Ep=gs.forwardRef(function(t,r){let{children:o,container:n,className:i,render:s,style:a,...u}=t,{node:l,subtree:c}=Gf({container:n,ref:r,componentProps:t,elementProps:u});return!c&&!l?null:(0,Rp.jsxs)(gs.Fragment,{children:[c,l&&_p.createPortal(o,l)]})});var Xt={};so(Xt,{Arrow:()=>Gp,Handle:()=>si,Popup:()=>Up,Portal:()=>Bp,Positioner:()=>zp,Provider:()=>qp,Root:()=>Ap,Trigger:()=>Mp,Viewport:()=>Xp,createHandle:()=>Kp});var vn=f(ve(),1);var ys=f(ve(),1),Ol=ys.createContext(void 0);function ur(e){let t=ys.useContext(Ol);if(t===void 0&&!e)throw new Error(lr(72));return t}var Tp=f(ve(),1);var Pp={...Xd,disabled:e=>e.disabled,instantType:e=>e.instantType,isInstantPhase:e=>e.isInstantPhase,trackCursorAxis:e=>e.trackCursorAxis,disableHoverablePopup:e=>e.disableHoverablePopup,lastOpenChangeReason:e=>e.openChangeReason,closeOnClick:e=>e.closeOnClick,closeDelay:e=>e.closeDelay,adaptiveOrigin:e=>e.adaptiveOrigin},vs=class extends mo{constructor(t,r,o){let n=new Ho;super(kp(t,n,r,o),Fp(n),Pp)}setOpen=(t,r)=>{Bd(this,t,r,{extraState:{openChangeReason:r.reason}})};cancelPendingOpen(t){this.state.floatingRootContext.dispatchOpenChange(!1,De(Oe.triggerPress,t))}};function Op(){let e=new Ho,t=new us(Object.freeze(kp(void 0,e)),Object.freeze(Fp(e)),Pp);return Object.assign(t,{setOpen:tr,cancelPendingOpen:tr})}function kp(e,t,r,o=!1){let n={...Yd(),disabled:!1,instantType:void 0,isInstantPhase:!1,trackCursorAxis:"none",disableHoverablePopup:!1,openChangeReason:null,closeOnClick:!0,closeDelay:0,adaptiveOrigin:void 0,...e};return n.floatingRootContext=qd(t,r,o),n}function Fp(e){return{popupRef:Tp.createRef(),onOpenChange:void 0,onOpenChangeComplete:void 0,triggerElements:e}}var ii=f(Z(),1),Ap=hl(function(t){let{disabled:r=!1,defaultOpen:o=!1,open:n,disableHoverablePopup:i=!1,trackCursorAxis:s="none",actionsRef:a,onOpenChange:u,onOpenChangeComplete:l,handle:c,triggerId:m,defaultTriggerId:d=null,children:h}=t,g=Vd((D,S)=>new vs({open:o,openProp:n,activeTriggerId:d,triggerIdProp:m},D,S));g.useControlledProp("openProp",n),g.useControlledProp("triggerIdProp",m),g.useContextCallback("onOpenChange",u),g.useContextCallback("onOpenChangeComplete",l);let b=g.useState("open"),w=!r&&b,C=g.useState("activeTriggerId"),x=g.useState("mounted"),v=g.useState("payload");g.useSyncedValues({trackCursorAxis:s,disableHoverablePopup:i,disabled:r}),zd(g,{closeOnActiveTriggerUnmount:!0});let{forceUnmount:_,transitionStatus:k}=Hd(w,g),E=g.useState("isInstantPhase"),T=g.useState("instantType"),O=g.useState("lastOpenChangeReason"),I=vn.useRef(null);we(()=>{b&&r&&g.setOpen(!1,De(Oe.disabled))},[b,r,g]),we(()=>{k==="ending"&&O===Oe.none||k!=="ending"&&E?(T!=="delay"&&(I.current=T),g.set("instantType","delay")):I.current!==null&&(g.set("instantType",I.current),I.current=null)},[k,E,O,T,g]),we(()=>{w&&C==null&&g.set("payload",void 0)},[g,C,w]),vn.useImperativeHandle(a,()=>({unmount:_,close:()=>g.setOpen(!1,De(Oe.imperativeAction))}),[_,g]);let J=w||x||!r&&s!=="none";return(0,ii.jsxs)(Ol.Provider,{value:g,children:[c&&(0,ii.jsx)(Dd,{handle:c,store:g}),J&&(0,ii.jsx)(Mw,{store:g,disabled:r,trackCursorAxis:s}),typeof h=="function"?h({payload:v}):h]})});function Mw({store:e,disabled:t,trackCursorAxis:r}){let o=e.useState("floatingRootContext"),n=rl(o,{enabled:!t,referencePress:()=>e.select("closeOnClick")}),i=tl(o,{enabled:!t&&r!=="none",axis:r==="none"?void 0:r}),s=vn.useMemo(()=>It(i.reference,n.reference),[i.reference,n.reference]);return Ud(e,{activeTriggerProps:s,inactiveTriggerProps:s,popupProps:n.floating??nt}),null}var ws=f(ve(),1);var bs=f(ve(),1),kl=bs.createContext(void 0);function Ip(){return bs.useContext(kl)}var Np="data-base-ui-tooltip-trigger";function Lp(e){if("composedPath"in e){let r=e.composedPath();for(let o=0;ow.select("transitionStatus")==="ending",shouldOpen(){return!B.current}}),be=wl(_,{enabled:!N}).reference,ye=Le=>{let X=B.current,M=Lp(Le),K=xe(M),H=k.current,Q=H&&M&&Ge(H,M);if(K&&w.select("open")&&w.select("lastOpenChangeReason")===Oe.triggerHover){w.setOpen(!1,De(Oe.triggerHover,Le));return}if(X&&!K&&Q&&!q.current&&!w.select("open")&&H&&Xr(P.current)){let pe=()=>{!B.current&&!q.current&&!w.select("open")&&w.setOpen(!0,De(Oe.triggerHover,Le,H))},le=W();le===0?(re.clear(),pe()):re.start(le,pe)}},$=w.useState("triggerProps",I);return Gt("button",t,{state:{open:v},ref:[r,O,k],props:[se,be,I||U!=="none"?$:void 0,{onMouseOver(Le){ye(Le.nativeEvent)},onFocus(Le){ne(Lp(Le.nativeEvent))&&Le.preventBaseUIHandler()},onMouseLeave(){B.current=!1,re.clear(),P.current=void 0},onPointerEnter(Le){P.current=Le.pointerType},onPointerDown(Le){P.current=Le.pointerType,w.set("closeOnClick",c),c&&!w.select("open")&&w.cancelPendingOpen(Le.nativeEvent)},onClick(Le){c&&!w.select("open")&&w.cancelPendingOpen(Le.nativeEvent)},id:C,"data-trigger-disabled":N?"":void 0,[Np]:N?void 0:""},h],stateAttributesMapping:tp})});var Dp=f(ve(),1);var xs=f(ve(),1),Fl=xs.createContext(void 0);function Vp(){let e=xs.useContext(Fl);if(e===void 0)throw new Error(lr(70));return e}var Al=f(Z(),1),Bp=Dp.forwardRef(function(t,r){let{keepMounted:o=!1,...n}=t;return ur().useState("mounted")||o?(0,Al.jsx)(Fl.Provider,{value:o,children:(0,Al.jsx)(Ep,{ref:r,...n})}):null});var Cs=f(ve(),1);var Ss=f(ve(),1),Il=Ss.createContext(void 0);function bn(){let e=Ss.useContext(Il);if(e===void 0)throw new Error(lr(71));return e}var jp=f(Z(),1),zp=Cs.forwardRef(function(t,r){let{render:o,className:n,anchor:i,positionMethod:s="absolute",side:a="top",align:u="center",sideOffset:l=0,alignOffset:c=0,collisionBoundary:m="clipping-ancestors",collisionPadding:d=5,arrowPadding:h=5,sticky:g=!1,disableAnchorTracking:b=!1,collisionAvoidance:w=Hf,style:C,...x}=t,v=ur(),_=Vp(),k=v.useState("open"),E=v.useState("mounted"),T=v.useState("trackCursorAxis"),O=v.useState("disableHoverablePopup"),I=v.useState("floatingRootContext"),J=v.useState("instantType"),D=v.useState("transitionStatus"),S=v.useState("adaptiveOrigin"),L=fp({anchor:i,positionMethod:s,floatingRootContext:I,mounted:E,side:a,sideOffset:l,align:u,alignOffset:c,collisionBoundary:m,collisionPadding:d,sticky:g,arrowPadding:h,disableAnchorTracking:b,keepMounted:_,collisionAvoidance:w,adaptiveOrigin:S}),Y=Cs.useMemo(()=>({open:k,side:L.side,align:L.align,anchorHidden:L.anchorHidden,instant:T!=="none"?"tracking-cursor":J}),[k,L.side,L.align,L.anchorHidden,T,J]),A=dp(t,Y,{styles:L.positionerStyles,transitionStatus:D,props:x,refs:[r,v.useStateSetter("positionerElement")],hidden:!E,inert:!k||T==="both"||O});return(0,jp.jsx)(Il.Provider,{value:L,children:A})});var Hp=f(ve(),1);var Up=Hp.forwardRef(function(t,r){let{render:o,className:n,style:i,...s}=t,a=ur(),{side:u,align:l}=bn(),c=a.useState("open"),m=a.useState("instantType"),d=a.useState("transitionStatus"),h=a.useState("popupProps"),g=a.useState("floatingRootContext"),b=a.useState("disabled"),w=a.useState("closeDelay");zi({open:c,ref:a.context.popupRef,onComplete(){c&&a.context.onOpenChangeComplete?.(!0)}}),Cl(g,{enabled:!b,closeDelay:w});let C=a.useStateSetter("popupElement");return Gt("div",t,{state:{open:c,side:u,align:l,instant:m,transitionStatus:d},ref:[r,a.context.popupRef,C],props:[Md,h,ds(d),s],stateAttributesMapping:rp})});var Wp=f(ve(),1);var Gp=Wp.forwardRef(function(t,r){let{render:o,className:n,style:i,...s}=t,a=ur(),{arrowRef:u,side:l,align:c,arrowUncentered:m,arrowStyles:d}=bn(),h=a.useState("open"),g=a.useState("instantType");return Gt("div",t,{state:{open:h,side:l,align:c,uncentered:m,instant:g},ref:[r,u],props:[{style:d,"aria-hidden":!0},s],stateAttributesMapping:ni})});var Yp=f(ve(),1);var Ll=f(Z(),1),qp=function(t){let{delay:r,closeDelay:o,timeout:n=400}=t,i=Yp.useMemo(()=>({open:r,close:o}),[r,o]);return(0,Ll.jsx)(kl.Provider,{value:r,children:(0,Ll.jsx)($a,{delay:i,timeoutMs:n,children:t.children})})};var Zp=f(ve(),1);var Xp=Zp.forwardRef(function(t,r){let{render:o,className:n,style:i,children:s,...a}=t,u=ur(),l=bn(),c=u.useState("instantType"),{children:m,state:d}=Cp({store:u,side:l.side,children:s}),h={activationDirection:d.activationDirection,transitioning:d.transitioning,instant:c};return Gt("div",t,{state:h,ref:r,props:[a,{children:m}],stateAttributesMapping:Sp})});var si=class extends es{constructor(){super(Op(),"Tooltip")}open(t){this.openByTrigger(t)}close(){this.closePopup()}get isOpen(){return this.attachedStore?.select("open")??!1}};function Kp(){return new si}function Vr(e){return Gt(e.defaultTagName??"div",e,e)}var $p=f(Te(),1),Nl="data-wp-hash";function Ml(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&jw(document)),e.__wpStyleRuntime}function Bw(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${Nl}]`))if(r.getAttribute(Nl)===t)return!0;return!1}function em(e,t,r){if(!e.head)return;let o=Ml(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(Bw(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(Nl,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function jw(e){let t=Ml();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)em(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function tm(e,t){let r=Ml();r.styles.set(e,t);for(let o of r.documents.keys())em(o,e,t)}typeof process>"u",tm("a495f9d138",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._83ed8a8da5dd50ea__text{margin:0}._14437cfb77831647__heading-2xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-2xl,32px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-2xl,32px);--_gcd-p-line-height:var(--wpds-typography-line-height-2xl,40px);font-size:var(--wpds-typography-font-size-2xl,32px);line-height:var(--wpds-typography-line-height-2xl,40px)}._14437cfb77831647__heading-2xl,._3c78b7fa9b4072dd__heading-xl{font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-emphasis,600)}._3c78b7fa9b4072dd__heading-xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-p-line-height:var(--wpds-typography-line-height-md,24px);font-size:var(--wpds-typography-font-size-xl,20px);line-height:var(--wpds-typography-line-height-md,24px)}.aa58f227716bcde2__heading-lg{--_gcd-heading-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-lg,15px)}.aa58f227716bcde2__heading-lg,.fc4da56d8dfe52c4__heading-md{font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:var(--wpds-typography-line-height-sm,20px)}.fc4da56d8dfe52c4__heading-md{--_gcd-heading-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-md,13px)}.a9b78c7c82e8dff7__heading-sm{--_gcd-heading-font-size:var(--wpds-typography-font-size-xs,11px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-xs,11px);--_gcd-p-line-height:var(--wpds-typography-line-height-xs,16px);font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-xs,11px);font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:var(--wpds-typography-line-height-xs,16px);text-transform:uppercase}._305ff559e52180d5__body-xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-p-line-height:var(--wpds-typography-line-height-xl,32px);font-size:var(--wpds-typography-font-size-xl,20px);line-height:var(--wpds-typography-line-height-xl,32px)}._305ff559e52180d5__body-xl,.ca1aa3fc2029e958__body-lg{font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-default,400)}.ca1aa3fc2029e958__body-lg{--_gcd-heading-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-p-line-height:var(--wpds-typography-line-height-md,24px);font-size:var(--wpds-typography-font-size-lg,15px);line-height:var(--wpds-typography-line-height-md,24px)}._131101940be12424__body-md{--_gcd-heading-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-md,13px);line-height:var(--wpds-typography-line-height-sm,20px)}._0e8d87a42c1f75fa__body-sm,._131101940be12424__body-md{font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-default,400)}._0e8d87a42c1f75fa__body-sm{--_gcd-heading-font-size:var(--wpds-typography-font-size-sm,12px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-sm,12px);--_gcd-p-line-height:var(--wpds-typography-line-height-xs,16px);font-size:var(--wpds-typography-font-size-sm,12px);line-height:var(--wpds-typography-line-height-xs,16px)}}}');var Jp={text:"_83ed8a8da5dd50ea__text","heading-2xl":"_14437cfb77831647__heading-2xl","heading-xl":"_3c78b7fa9b4072dd__heading-xl","heading-lg":"aa58f227716bcde2__heading-lg","heading-md":"fc4da56d8dfe52c4__heading-md","heading-sm":"a9b78c7c82e8dff7__heading-sm","body-xl":"_305ff559e52180d5__body-xl","body-lg":"ca1aa3fc2029e958__body-lg","body-md":"_131101940be12424__body-md","body-sm":"_0e8d87a42c1f75fa__body-sm"};typeof process>"u",tm("af6d9984a6","._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}");var Qp={button:"_6defc79820e382c6__button",input:"d2cff2e5dea83bd1__input",textarea:"_547d86373d02e108__textarea",div:"_8c15fd0ed9f28ba4__div",p:"_43cec3e1eec1066d__p",heading:"e97669c6d9a38497__heading",a:"_2c0831b0499dbd6e__a"},wn=(0,$p.forwardRef)(function({variant:t="body-md",render:r,className:o,...n},i){return Vr({render:r,defaultTagName:"span",ref:i,props:It(n,{className:We(Jp.text,Qp.heading,Qp.p,Jp[t],o)})})});var _s=f(Te(),1),ai=(0,_s.forwardRef)(({icon:e,size:t=24,...r},o)=>(0,_s.cloneElement)(e,{width:t,height:t,...r,ref:o}));var Rs=f(xn(),1),Vl=f(Z(),1),Uo=(0,Vl.jsx)(Rs.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,Vl.jsx)(Rs.Path,{d:"M14.6 7l-1.2-1L8 12l5.4 6 1.2-1-4.6-5z"})});var Es=f(xn(),1),Dl=f(Z(),1),Wo=(0,Dl.jsx)(Es.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,Dl.jsx)(Es.Path,{d:"M10.6 6L9.4 7l4.6 5-4.6 5 1.2 1 5.4-6z"})});var Ts=f(xn(),1),Bl=f(Z(),1),jl=(0,Bl.jsx)(Ts.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,Bl.jsx)(Ts.Path,{d:"M13 19h-2v-2h2v2zm0-6h-2v-2h2v2zm0-6h-2V5h2v2z"})});var Ps=f(xn(),1),zl=f(Z(),1),Os=(0,zl.jsx)(Ps.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,zl.jsx)(Ps.Path,{d:"M6.6 6L5.4 7l4.5 5-4.5 5 1.1 1 5.5-6-5.4-6zm6 0l-1.1 1 4.5 5-4.5 5 1.1 1 5.5-6-5.5-6z"})});var ks=f(xn(),1),Hl=f(Z(),1),Fs=(0,Hl.jsx)(ks.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,Hl.jsx)(ks.Path,{d:"M11.6 7l-1.1-1L5 12l5.5 6 1.1-1L7 12l4.6-5zm6 0l-1.1-1-5.5 6 5.5 6 1.1-1-4.6-5 4.6-5z"})});var Sn={};so(Sn,{Popup:()=>Cm,Portal:()=>As,Positioner:()=>Is,Provider:()=>Am,Root:()=>km,Trigger:()=>Em});var xm=f(Te(),1);var lm=f(Te(),1);var Wl="data-wp-hash";function Gl(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Hw(document)),e.__wpStyleRuntime}function zw(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${Wl}]`))if(r.getAttribute(Wl)===t)return!0;return!1}function im(e,t,r){if(!e.head)return;let o=Gl(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(zw(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(Wl,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function Hw(e){let t=Gl();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)im(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function Uw(e,t){let r=Gl();r.styles.set(e,t);for(let o of r.documents.keys())im(o,e,t)}typeof process>"u",Uw("be37f31c1e","._11fc52b637ff8a7e__slot{inset:0;isolation:isolate;pointer-events:none;position:fixed;z-index:1000000003}@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._11fc52b637ff8a7e__slot>*{pointer-events:auto}}}");var nm={slot:"_11fc52b637ff8a7e__slot"},sm="data-wp-compat-overlay-slot";function Ww(){return typeof document>"u"?null:document}function Gw(){let e;try{e=window.top?.wp}catch{}let t=e??window.wp;return typeof t?.components=="object"&&t.components!==null}var Dr=null;function Ul(e){return e.setAttribute("aria-hidden","false"),e}function Yw(e){let t=e.createElement("div");return t.setAttribute(sm,""),nm.slot&&t.classList.add(nm.slot),e.body.appendChild(t),t}function am(){if(typeof window>"u"||!Gw()&&window.__wpUiCompatOverlaySlotEnabled!==!0)return;let e=Ww();if(!e||!e.body)return;if(Dr&&Dr.ownerDocument===e&&Dr.isConnected)return Ul(Dr);let t=e.querySelector(`[${sm}]`);return t instanceof HTMLDivElement?(Dr=Ul(t),Dr):(Dr?.isConnected&&Dr.remove(),Dr=Ul(Yw(e)),Dr)}var cm=f(Z(),1),As=(0,lm.forwardRef)(function({container:t,...r},o){return(0,cm.jsx)(Xt.Portal,{container:t??am(),...r,ref:o})});var um=f(Te(),1),pm=f(Z(),1),Yl="data-wp-hash";function ql(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Zw(document)),e.__wpStyleRuntime}function qw(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${Yl}]`))if(r.getAttribute(Yl)===t)return!0;return!1}function fm(e,t,r){if(!e.head)return;let o=ql(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(qw(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(Yl,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function Zw(e){let t=ql();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)fm(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function dm(e,t){let r=ql();r.styles.set(e,t);for(let o of r.documents.keys())fm(o,e,t)}typeof process>"u",dm("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var Xw={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",dm("19fcc06039",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}');var Kw={positioner:"_480b748dd3510e64__positioner",popup:"_50096b232db7709d__popup"},Is=(0,um.forwardRef)(function({align:t="center",className:r,side:o="top",sideOffset:n=4,...i},s){return(0,pm.jsx)(Xt.Positioner,{ref:s,align:t,side:o,sideOffset:n,...i,className:We(Xw["box-sizing"],Kw.positioner,r)})});var mm=f(Te(),1);function Zl(e,t,r){return(0,mm.cloneElement)(e??t,{children:r})}var Jw=f(gm(),1);var vm=f(li(),1),{lock:dA,unlock:bm}=(0,vm.__dangerousOptInToUnstableAPIsOnlyForCoreModules)("I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.","@wordpress/ui");function Qw(){let e=Jw;if(e.ThemeProvider)return e.ThemeProvider;if(!e.privateApis)throw new Error("@wordpress/ui: @wordpress/theme must expose `ThemeProvider` or `privateApis.ThemeProvider`.");return bm(e.privateApis).ThemeProvider}var wm=Qw();var ci=f(Z(),1),Xl="data-wp-hash";function Kl(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&e1(document)),e.__wpStyleRuntime}function $w(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${Xl}]`))if(r.getAttribute(Xl)===t)return!0;return!1}function Sm(e,t,r){if(!e.head)return;let o=Kl(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if($w(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(Xl,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function e1(e){let t=Kl();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)Sm(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function t1(e,t){let r=Kl();r.styles.set(e,t);for(let o of r.documents.keys())Sm(o,e,t)}typeof process>"u",t1("19fcc06039",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}');var r1={positioner:"_480b748dd3510e64__positioner",popup:"_50096b232db7709d__popup"},o1={background:"#1e1e1e"},Cm=(0,xm.forwardRef)(function({portal:t,positioner:r,children:o,className:n,...i},s){let a=(0,ci.jsx)(wm,{color:o1,children:(0,ci.jsx)(Xt.Popup,{ref:s,className:We(r1.popup,n),...i,children:o})}),u=Zl(r,(0,ci.jsx)(Is,{}),a);return Zl(t,(0,ci.jsx)(As,{}),u)});var _m=f(Te(),1),Rm=f(Z(),1),Em=(0,_m.forwardRef)(function(t,r){return(0,Rm.jsx)(Xt.Trigger,{ref:r,...t})});var Tm=f(ge(),1),Pm=f(Z(),1);function Om({children:e}){return(0,Pm.jsx)(hs,{direction:(0,Tm.isRTL)()?"rtl":"ltr",children:e})}var Jl=f(Z(),1);function km(e){return(0,Jl.jsx)(Om,{children:(0,Jl.jsx)(Xt.Root,{...e})})}var Fm=f(Z(),1);function Am({...e}){return(0,Fm.jsx)(Xt.Provider,{...e})}var Im=f(Te(),1),Ql="data-wp-hash";function $l(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&i1(document)),e.__wpStyleRuntime}function n1(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${Ql}]`))if(r.getAttribute(Ql)===t)return!0;return!1}function Lm(e,t,r){if(!e.head)return;let o=$l(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(n1(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(Ql,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function i1(e){let t=$l();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)Lm(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function s1(e,t){let r=$l();r.styles.set(e,t);for(let o of r.documents.keys())Lm(o,e,t)}typeof process>"u",s1("fa606a57ae","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.f37b9e2e191ebd66__visually-hidden{word-wrap:normal;border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-break:normal}}}");var a1={"visually-hidden":"f37b9e2e191ebd66__visually-hidden"},ec=(0,Im.forwardRef)(function({render:t,...r},o){return Vr({render:t,ref:o,props:It({className:a1["visually-hidden"]},r,{"data-visually-hidden":""})})});var Nm=f(Te(),1),tc="data-wp-hash";function rc(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&c1(document)),e.__wpStyleRuntime}function l1(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${tc}]`))if(r.getAttribute(tc)===t)return!0;return!1}function Mm(e,t,r){if(!e.head)return;let o=rc(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(l1(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(tc,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function c1(e){let t=rc();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)Mm(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function u1(e,t){let r=rc();r.styles.set(e,t);for(let o of r.documents.keys())Mm(o,e,t)}typeof process>"u",u1("32aba35fe1","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._19ce0419607e1896__stack{display:flex}}}");var f1={stack:"_19ce0419607e1896__stack"},d1={xs:"var(--wpds-dimension-gap-xs, 4px)",sm:"var(--wpds-dimension-gap-sm, 8px)",md:"var(--wpds-dimension-gap-md, 12px)",lg:"var(--wpds-dimension-gap-lg, 16px)",xl:"var(--wpds-dimension-gap-xl, 24px)","2xl":"var(--wpds-dimension-gap-2xl, 32px)","3xl":"var(--wpds-dimension-gap-3xl, 40px)"},vo=(0,Nm.forwardRef)(function({direction:t,gap:r,align:o,justify:n,wrap:i,render:s,...a},u){let l={gap:r&&d1[r],alignItems:o,justifyContent:n,flexDirection:t,flexWrap:i};return Vr({render:s,ref:u,props:It(a,{style:l,className:f1.stack})})});var Vm=f(Te(),1),Dm=f(ge(),1),Cn=f(Z(),1),oc="data-wp-hash";function nc(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&m1(document)),e.__wpStyleRuntime}function p1(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${oc}]`))if(r.getAttribute(oc)===t)return!0;return!1}function Bm(e,t,r){if(!e.head)return;let o=nc(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(p1(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(oc,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function m1(e){let t=nc();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)Bm(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function Ns(e,t){let r=nc();r.styles.set(e,t);for(let o of r.documents.keys())Bm(o,e,t)}typeof process>"u",Ns("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var h1={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",Ns("96553466c8","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._64de9947bf305b7a__outset-ring--focus-within-visible:focus-within:has(:focus-visible),.af79fb116edb0dd7__outset-ring--focus:focus,.dfcfdc28396e5d98__outset-ring--focus-visible:focus-visible,.e5cd9ee879f6403a__outset-ring--focus-within:focus-within,:focus-visible ._81935a08e952f267__outset-ring--focus-parent-visible{--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within,.abc777e9713fa711__outset-ring--focus-except-active:focus{outline:none}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within:not(:has(:active)),.abc777e9713fa711__outset-ring--focus-except-active:focus:not(:active){--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}}}");var g1={"outset-ring--focus":"af79fb116edb0dd7__outset-ring--focus","outset-ring--focus-visible":"dfcfdc28396e5d98__outset-ring--focus-visible","outset-ring--focus-within":"e5cd9ee879f6403a__outset-ring--focus-within","outset-ring--focus-within-visible":"_64de9947bf305b7a__outset-ring--focus-within-visible","outset-ring--focus-parent-visible":"_81935a08e952f267__outset-ring--focus-parent-visible","outset-ring--focus-except-active":"abc777e9713fa711__outset-ring--focus-except-active","outset-ring--focus-within-except-active":"_3c9f5ee9fc9c136d__outset-ring--focus-within-except-active"};typeof process>"u",Ns("e8e6a9be37",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.d4250949359b05ce__link{text-decoration-thickness:from-font;text-underline-offset:.2em}.c6055659b8e2cd2c__is-brand,.c6055659b8e2cd2c__is-brand:visited{--_gcd-a-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9))}.c6055659b8e2cd2c__is-brand:active,.c6055659b8e2cd2c__is-brand:hover{--_gcd-a-color:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));color:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000))}._92e0dfcaeee15b88__is-neutral,._92e0dfcaeee15b88__is-neutral:visited{--_gcd-a-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);text-decoration-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d)}._92e0dfcaeee15b88__is-neutral:active,._92e0dfcaeee15b88__is-neutral:hover{--_gcd-a-color:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);color:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e)}.cf122a9bf1035d42__is-unstyled{--_gcd-a-color:inherit;color:inherit;text-decoration:none}._0cb411afac4c86c7__link-icon{display:inline-block;font-weight:var(--wpds-typography-font-weight-default,400);line-height:1;margin-inline-start:var(--wpds-dimension-padding-xs,4px);text-decoration:none}._0cb411afac4c86c7__link-icon:after{content:"\\2197"}._0cb411afac4c86c7__link-icon:dir(rtl):after{content:"\\2196"}}}');var Ls={link:"d4250949359b05ce__link","is-brand":"c6055659b8e2cd2c__is-brand","is-neutral":"_92e0dfcaeee15b88__is-neutral","is-unstyled":"cf122a9bf1035d42__is-unstyled","link-icon":"_0cb411afac4c86c7__link-icon"};typeof process>"u",Ns("af6d9984a6","._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}");var y1={button:"_6defc79820e382c6__button",input:"d2cff2e5dea83bd1__input",textarea:"_547d86373d02e108__textarea",div:"_8c15fd0ed9f28ba4__div",p:"_43cec3e1eec1066d__p",heading:"e97669c6d9a38497__heading",a:"_2c0831b0499dbd6e__a"},ic=(0,Vm.forwardRef)(function({children:t,variant:r="default",tone:o="brand",openInNewTab:n=!1,render:i,className:s,...a},u){return Vr({render:i,defaultTagName:"a",ref:u,props:It(a,{className:We(y1.a,h1["box-sizing"],g1["outset-ring--focus-except-active"],r!=="unstyled"&&Ls.link,r!=="unstyled"&&Ls[`is-${o}`],r==="unstyled"&&Ls["is-unstyled"],s),target:n?"_blank":void 0,children:(0,Cn.jsxs)(Cn.Fragment,{children:[t,n&&(0,Cn.jsx)("span",{className:Ls["link-icon"],role:"img","aria-label":(0,Dm.__)("(opens in a new tab)")})]})})})});var zm=f(Te(),1),sc="data-wp-hash";function ac(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&b1(document)),e.__wpStyleRuntime}function v1(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${sc}]`))if(r.getAttribute(sc)===t)return!0;return!1}function Hm(e,t,r){if(!e.head)return;let o=ac(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(v1(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(sc,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function b1(e){let t=ac();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)Hm(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function Um(e,t){let r=ac();r.styles.set(e,t);for(let o of r.documents.keys())Hm(o,e,t)}typeof process>"u",Um("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var w1={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",Um("ed2c39ec90","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.b20cc1690085c2f0__skeleton{background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);display:block;@media (forced-colors:active){border:var(--wpds-border-width-xs,1px) solid CanvasText}}._9b143194fdb45f93__pulse{@media not (prefers-reduced-motion){animation:e2b9fe0690281bc8__skeleton-pulse 1.5s ease-in-out infinite}}@keyframes e2b9fe0690281bc8__skeleton-pulse{0%,to{opacity:1}50%{opacity:.4}}}}");var jm={skeleton:"b20cc1690085c2f0__skeleton",pulse:"_9b143194fdb45f93__pulse","skeleton-pulse":"e2b9fe0690281bc8__skeleton-pulse"},ui=(0,zm.forwardRef)(function({render:t,...r},o){return Vr({render:t,ref:o,props:It({className:We(jm.skeleton,jm.pulse,w1["box-sizing"]),"aria-hidden":!0},r)})});var Wm=f(Te(),1),Gm=f(Z(),1),Ym=(0,Wm.forwardRef)(({children:e,className:t,ariaLabel:r,as:o="div",...n},i)=>(0,Gm.jsx)(o,{ref:i,className:We("admin-ui-navigable-region",t),"aria-label":r,role:"region",tabIndex:"-1",...n,children:e}));Ym.displayName="NavigableRegion";var qm=Ym;var Zm=f(ge(),1);var bo=f(Z(),1),cc="data-wp-hash";function uc(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&S1(document)),e.__wpStyleRuntime}function x1(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${cc}]`))if(r.getAttribute(cc)===t)return!0;return!1}function Xm(e,t,r){if(!e.head)return;let o=uc(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(x1(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(cc,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function S1(e){let t=uc();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)Xm(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function C1(e,t){let r=uc();r.styles.set(e,t);for(let o of r.documents.keys())Xm(o,e,t)}typeof process>"u",C1("72ef022400",".bfb5a2dd8cceebd3__list{--focus-ring-size:calc(var(--wpds-border-width-focus, var(--wp-admin-border-width-focus, 2px))*2);list-style:none;margin:calc(var(--focus-ring-size)*-1);overflow-x:auto;padding:var(--focus-ring-size);scroll-padding:var(--focus-ring-size)}.a4759b4cb2c8bd92__li{flex-shrink:0}._07da506d3f2d9afe__item{align-items:center;color:var(--wpds-color-foreground-interactive-neutral-weak,#707070);display:flex;font-weight:var(--wpds-typography-font-weight-default,400);min-block-size:44px;min-inline-size:44px;text-decoration:none}._07da506d3f2d9afe__item:hover,._07da506d3f2d9afe__item[aria-current=page]{color:var(--wpds-color-foreground-interactive-neutral-weak-active,#1e1e1e)}._07da506d3f2d9afe__item[aria-current=page]{font-weight:var(--wpds-typography-font-weight-emphasis,600)}");var lc={list:"bfb5a2dd8cceebd3__list",li:"a4759b4cb2c8bd92__li",item:"_07da506d3f2d9afe__item"},_1=({items:e,currentHref:t,ariaLabel:r=(0,Zm.__)("Sections"),linkComponent:o,className:n})=>{if(!e.length)return null;let i=o??"a";return(0,bo.jsx)("nav",{"aria-label":r,className:n,children:(0,bo.jsx)(vo,{render:(0,bo.jsx)("ul",{role:"list"}),direction:"row",align:"center",gap:"md",className:lc.list,children:e.map(s=>(0,bo.jsx)("li",{className:lc.li,children:(0,bo.jsx)(wn,{variant:"body-md",className:lc.item,render:(0,bo.jsx)(ic,{variant:"unstyled","aria-current":s.href===t?"page":void 0,render:(0,bo.jsx)(i,{href:s.href})}),children:s.label})},s.href))})})},Km=_1;var Qm=f(ue(),1),{Fill:$m,Slot:eh}=(0,Qm.createSlotFill)("SidebarToggle");var ir=f(Z(),1),fc="data-wp-hash";function dc(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&E1(document)),e.__wpStyleRuntime}function R1(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${fc}]`))if(r.getAttribute(fc)===t)return!0;return!1}function th(e,t,r){if(!e.head)return;let o=dc(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(R1(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(fc,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function E1(e){let t=dc();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)th(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function T1(e,t){let r=dc();r.styles.set(e,t);for(let o of r.documents.keys())th(o,e,t)}typeof process>"u",T1("1f3750277d","._956b6df0898efed0__page{text-wrap:pretty;background-color:var(--wpds-color-background-surface-neutral,#fcfcfc);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);display:flex;flex-flow:column;height:100%;position:relative;z-index:1}._0625b55e82a0d93d__header{background:var(--wpds-color-background-surface-neutral-strong,#fff);border-block-end:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral-weak,#f0f0f0);inset-block-start:0;padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px);position:sticky;z-index:1}.a43c44d5ae28b2e8__header-content{min-height:var(--wpds-dimension-size-md,32px)}.b7cb5b9daf3a3b25__header-actions{flex-shrink:0}._8bcd33103b451f30__header-lockup{min-width:0}._8113be94e7caf73c__header-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._9a776c7f70996f61__header-visual{display:grid;flex-shrink:0;grid-template-columns:1fr;grid-template-rows:1fr;height:var(--wpds-dimension-size-sm,24px);width:var(--wpds-dimension-size-sm,24px);>*{grid-column:1/-1;grid-row:1/-1;max-height:100%;max-width:100%}}.d5e0920cd15d35bc__sidebar-toggle-slot:empty{display:none}._60fea2f6bf5319cd__header-subtitle{color:var(--wpds-color-foreground-content-neutral-weak,#707070);padding-block-end:var(--wpds-dimension-padding-xs,4px)}._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation,._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation ._60fea2f6bf5319cd__header-subtitle{padding-block-end:0}._673c99dcbfb58211__header-navigation{margin-block-start:var(--wpds-dimension-gap-md,12px)}.be5e57d029ec4036__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;&._128806d0b26e3a50__has-padding{padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px)}}");var Br={page:"_956b6df0898efed0__page",header:"_0625b55e82a0d93d__header","header-content":"a43c44d5ae28b2e8__header-content","header-actions":"b7cb5b9daf3a3b25__header-actions","header-lockup":"_8bcd33103b451f30__header-lockup","header-title":"_8113be94e7caf73c__header-title","header-visual":"_9a776c7f70996f61__header-visual","sidebar-toggle-slot":"d5e0920cd15d35bc__sidebar-toggle-slot","header-subtitle":"_60fea2f6bf5319cd__header-subtitle","has-navigation":"_4b0f17e503d11619__has-navigation","header-navigation":"_673c99dcbfb58211__header-navigation",content:"be5e57d029ec4036__content","has-padding":"_128806d0b26e3a50__has-padding"};function rh({headingLevel:e=1,breadcrumbs:t,badges:r,visual:o,title:n,subTitle:i,actions:s,navigation:a,components:u,showSidebarToggle:l=!0}){let c=`h${e}`,m=!!a?.items?.length;return(0,ir.jsxs)(vo,{direction:"column",className:We(Br.header,m&&Br["has-navigation"]),children:[(0,ir.jsxs)(vo,{className:Br["header-content"],direction:"row",gap:"sm",justify:"space-between",children:[(0,ir.jsxs)(vo,{direction:"row",gap:"sm",align:"center",justify:"start",className:Br["header-lockup"],children:[l&&(0,ir.jsx)(eh,{bubblesVirtually:!0,className:Br["sidebar-toggle-slot"]}),o&&(0,ir.jsx)("div",{className:Br["header-visual"],"aria-hidden":"true",children:o}),n&&(0,ir.jsx)(wn,{className:Br["header-title"],render:(0,ir.jsx)(c,{}),variant:"heading-lg",children:n}),t,r]}),s&&(0,ir.jsx)(vo,{align:"center",className:Br["header-actions"],direction:"row",gap:"sm",children:s})]}),i&&(0,ir.jsx)(wn,{render:(0,ir.jsx)("p",{}),variant:"body-md",className:Br["header-subtitle"],children:i}),m&&(0,ir.jsx)(Km,{...a,linkComponent:u?.link,className:Br["header-navigation"]})]})}var fi=f(Z(),1),mc="data-wp-hash";function hc(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&O1(document)),e.__wpStyleRuntime}function P1(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${mc}]`))if(r.getAttribute(mc)===t)return!0;return!1}function oh(e,t,r){if(!e.head)return;let o=hc(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(P1(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(mc,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function O1(e){let t=hc();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)oh(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function k1(e,t){let r=hc();r.styles.set(e,t);for(let o of r.documents.keys())oh(o,e,t)}typeof process>"u",k1("1f3750277d","._956b6df0898efed0__page{text-wrap:pretty;background-color:var(--wpds-color-background-surface-neutral,#fcfcfc);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);display:flex;flex-flow:column;height:100%;position:relative;z-index:1}._0625b55e82a0d93d__header{background:var(--wpds-color-background-surface-neutral-strong,#fff);border-block-end:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral-weak,#f0f0f0);inset-block-start:0;padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px);position:sticky;z-index:1}.a43c44d5ae28b2e8__header-content{min-height:var(--wpds-dimension-size-md,32px)}.b7cb5b9daf3a3b25__header-actions{flex-shrink:0}._8bcd33103b451f30__header-lockup{min-width:0}._8113be94e7caf73c__header-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._9a776c7f70996f61__header-visual{display:grid;flex-shrink:0;grid-template-columns:1fr;grid-template-rows:1fr;height:var(--wpds-dimension-size-sm,24px);width:var(--wpds-dimension-size-sm,24px);>*{grid-column:1/-1;grid-row:1/-1;max-height:100%;max-width:100%}}.d5e0920cd15d35bc__sidebar-toggle-slot:empty{display:none}._60fea2f6bf5319cd__header-subtitle{color:var(--wpds-color-foreground-content-neutral-weak,#707070);padding-block-end:var(--wpds-dimension-padding-xs,4px)}._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation,._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation ._60fea2f6bf5319cd__header-subtitle{padding-block-end:0}._673c99dcbfb58211__header-navigation{margin-block-start:var(--wpds-dimension-gap-md,12px)}.be5e57d029ec4036__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;&._128806d0b26e3a50__has-padding{padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px)}}");var pc={page:"_956b6df0898efed0__page",header:"_0625b55e82a0d93d__header","header-content":"a43c44d5ae28b2e8__header-content","header-actions":"b7cb5b9daf3a3b25__header-actions","header-lockup":"_8bcd33103b451f30__header-lockup","header-title":"_8113be94e7caf73c__header-title","header-visual":"_9a776c7f70996f61__header-visual","sidebar-toggle-slot":"d5e0920cd15d35bc__sidebar-toggle-slot","header-subtitle":"_60fea2f6bf5319cd__header-subtitle","has-navigation":"_4b0f17e503d11619__has-navigation","header-navigation":"_673c99dcbfb58211__header-navigation",content:"be5e57d029ec4036__content","has-padding":"_128806d0b26e3a50__has-padding"};function nh({headingLevel:e,breadcrumbs:t,badges:r,visual:o,title:n,subTitle:i,children:s,className:a,actions:u,navigation:l,components:c,ariaLabel:m,hasPadding:d=!1,showSidebarToggle:h=!0}){let g=We(pc.page,a);return(0,fi.jsxs)(qm,{className:g,ariaLabel:m??(typeof n=="string"?n:""),children:[(n||t||r||u||o||!!l?.items?.length)&&(0,fi.jsx)(rh,{headingLevel:e,breadcrumbs:t,badges:r,visual:o,title:n,subTitle:i,actions:u,navigation:l,components:c,showSidebarToggle:h}),d?(0,fi.jsx)("div",{className:We(pc.content,pc["has-padding"]),children:s}):s]})}nh.SidebarToggleFill=$m;var gc=nh;var zn=f(ge()),Vv=f(ue()),Dv=f(sh()),Ea=f(sr()),Bv=f(Kt()),jv=f(Te());var Lv=f(ue(),1),Nv=f(_n(),1),RE=f(Kt(),1),EE=f(Dt(),1),Au=f(Te(),1),TE=f(yo(),1);function Rn(e,t,r){t=Array.isArray(t)?[...t]:[t],e=Array.isArray(e)?[...e]:{...e};let o=t.pop(),n=e;for(let i of t){let s=n[i];n=n[i]=Array.isArray(s)?[...s]:{...s}}return n[o]=r,e}var ht=(e,t,r)=>{let o=Array.isArray(t)?t:t.split("."),n=e;return o.forEach(i=>{n=n?.[i]}),n??r};var F1=["appearanceTools","useRootPaddingAwareAlignments","background.backgroundImage","background.backgroundRepeat","background.backgroundSize","background.backgroundPosition","background.gradient","border.color","border.radius","border.radiusSizes","border.style","border.width","shadow.presets","shadow.defaultPresets","color.background","color.button","color.caption","color.custom","color.customDuotone","color.customGradient","color.defaultDuotone","color.defaultGradients","color.defaultPalette","color.duotone","color.gradients","color.heading","color.link","color.palette","color.text","custom","dimensions.aspectRatio","dimensions.height","dimensions.minHeight","dimensions.minWidth","dimensions.width","dimensions.dimensionSizes","layout.contentSize","layout.definitions","layout.wideSize","lightbox.enabled","lightbox.allowEditing","position.fixed","position.sticky","spacing.customSpacingSize","spacing.defaultSpacingSizes","spacing.spacingSizes","spacing.spacingScale","spacing.blockGap","spacing.margin","spacing.padding","spacing.units","typography.fluid","typography.customFontSize","typography.defaultFontSizes","typography.dropCap","typography.fontFamilies","typography.fontSizes","typography.fontStyle","typography.fontWeight","typography.letterSpacing","typography.lineHeight","typography.textAlign","typography.textColumns","typography.textDecoration","typography.textIndent","typography.textTransform","typography.writingMode","viewport.mobile","viewport.tablet"];function yc(e,t,r){let o=r?".blocks."+r:"",n=t?"."+t:"",i=`settings${o}${n}`,s=`settings${n}`;if(t)return ht(e,i)??ht(e,s);let a={};return F1.forEach(u=>{let l=ht(e,`settings${o}.${u}`)??ht(e,`settings.${u}`);l!==void 0&&(a=Rn(a,u.split("."),l))}),a}function vc(e,t,r,o){let n=o?".blocks."+o:"",i=t?"."+t:"",s=`settings${n}${i}`;return Rn(e,s.split("."),r)}var hh=f(dh(),1);var A1="1600px",I1="320px",L1=1,N1=.25,M1=.75,V1="14px";function ph({minimumFontSize:e,maximumFontSize:t,fontSize:r,minimumViewportWidth:o=I1,maximumViewportWidth:n=A1,scaleFactor:i=L1,minimumFontSizeLimit:s}){if(s=jr(s)?s:V1,r){let v=jr(r);if(!v?.unit||!v?.value)return null;let _=jr(s,{coerceTo:v.unit});if(_?.value&&!e&&!t&&v?.value<=_?.value)return null;if(t||(t=`${v.value}${v.unit}`),!e){let k=v.unit==="px"?v.value:v.value*16,E=Math.min(Math.max(1-.075*Math.log2(k),N1),M1),T=di(v.value*E,3);_?.value&&T<_?.value?e=`${_.value}${_.unit}`:e=`${T}${v.unit}`}}let a=jr(e),u=a?.unit||"rem",l=jr(t,{coerceTo:u});if(!a||!l)return null;let c=jr(e,{coerceTo:"rem"}),m=jr(n,{coerceTo:u}),d=jr(o,{coerceTo:u});if(!m||!d||!c)return null;let h=m.value-d.value;if(!h)return null;let g=di(d.value/100,3),b=di(g,3)+u,w=100*((l.value-a.value)/h),C=di((w||1)*i,3),x=`${c.value}${c.unit} + ((1vw - ${b}) * ${C})`;return`clamp(${e}, ${x}, ${t})`}function jr(e,t={}){if(typeof e!="string"&&typeof e!="number")return null;isFinite(e)&&(e=`${e}px`);let{coerceTo:r,rootSizeValue:o,acceptableUnits:n}={coerceTo:"",rootSizeValue:16,acceptableUnits:["rem","px","em"],...t},i=n?.join("|"),s=new RegExp(`^(\\d*\\.?\\d+)(${i}){1,1}$`),a=e.toString().match(s);if(!a||a.length<3)return null;let[,u,l]=a,c=parseFloat(u);return r==="px"&&(l==="em"||l==="rem")&&(c=c*o,l=r),l==="px"&&(r==="em"||r==="rem")&&(c=c/o,l=r),(r==="em"||r==="rem")&&(l==="em"||l==="rem")&&(l=r),l?{value:di(c,3),unit:l}:null}function di(e,t=3){let r=Math.pow(10,t);return Math.round(e*r)/r}function bc(e){let t=e?.fluid;return t===!0||t&&typeof t=="object"&&Object.keys(t).length>0}function D1(e){let t=e?.typography??{},r=e?.layout,o=jr(r?.wideSize)?r?.wideSize:null;return bc(t)&&o?{fluid:{maxViewportWidth:o,...typeof t.fluid=="object"?t.fluid:{}}}:{fluid:t?.fluid}}function mh(e,t){let{size:r}=e;if(!r||r==="0"||e?.fluid===!1||!bc(t?.typography)&&!bc(e))return r;let o=D1(t)?.fluid??{},n=ph({minimumFontSize:typeof e?.fluid=="boolean"?void 0:e?.fluid?.min,maximumFontSize:typeof e?.fluid=="boolean"?void 0:e?.fluid?.max,fontSize:r,minimumFontSizeLimit:typeof o=="object"?o?.minFontSize:void 0,maximumViewportWidth:typeof o=="object"?o?.maxViewportWidth:void 0,minimumViewportWidth:typeof o=="object"?o?.minViewportWidth:void 0});return n||r}var B1=[{path:["color","palette"],valueKey:"color",cssVarInfix:"color",classes:[{classSuffix:"color",propertyName:"color"},{classSuffix:"background-color",propertyName:"background-color"},{classSuffix:"border-color",propertyName:"border-color"}]},{path:["color","gradients"],valueKey:"gradient",cssVarInfix:"gradient",classes:[{classSuffix:"gradient-background",propertyName:"background"}]},{path:["color","duotone"],valueKey:"colors",cssVarInfix:"duotone",valueFunc:({slug:e})=>`url( '#wp-duotone-${e}' )`,classes:[]},{path:["shadow","presets"],valueKey:"shadow",cssVarInfix:"shadow",classes:[]},{path:["typography","fontSizes"],valueFunc:(e,t)=>mh(e,t),valueKey:"size",cssVarInfix:"font-size",classes:[{classSuffix:"font-size",propertyName:"font-size"}]},{path:["typography","fontFamilies"],valueKey:"fontFamily",cssVarInfix:"font-family",classes:[{classSuffix:"font-family",propertyName:"font-family"}]},{path:["spacing","spacingSizes"],valueKey:"size",cssVarInfix:"spacing",valueFunc:({size:e})=>e,classes:[]},{path:["border","radiusSizes"],valueKey:"size",cssVarInfix:"border-radius",classes:[]},{path:["dimensions","dimensionSizes"],valueKey:"size",cssVarInfix:"dimension",classes:[]}];function j1(e,t){if(!e||!t)return e;if(typeof e=="object"&&"ref"in e&&e?.ref){let r=(0,hh.getCSSValueFromRawStyle)(ht(t,e.ref));return typeof r=="object"&&r!==null&&"ref"in r&&r?.ref?void 0:r===void 0?e:r}return e}function z1(e,t){if(!e||!t||!Array.isArray(t))return e;let r=t.find(o=>o?.name===e);return r?.href?r?.href:e}function gh(e,t){if(!e||!t)return e;let r=j1(e,t);return typeof r=="object"&&r!==null&&"url"in r&&r?.url&&(r.url=z1(r.url,t?._links?.["wp:theme-file"])),r}function yh(e,t,r=[],o="slug",n){let i=[t?ht(e,["blocks",t,...r]):void 0,ht(e,r)].filter(Boolean);for(let s of i)if(s){let a=["custom","theme","default"];for(let u of a){let l=s[u];if(l){let c=l.find(m=>m[o]===n);if(c)return o==="slug"||yh(e,t,r,"slug",c.slug)[o]===c[o]?c:void 0}}}}function H1(e,t,r,[o,n]=[]){let i=B1.find(a=>a.cssVarInfix===o);if(!i||!e.settings)return r;let s=yh(e.settings,t,i.path,"slug",n);if(s){let{valueKey:a}=i,u=s[a];return Ms(e,t,u)}return r}function U1(e,t,r,o=[]){let n=(t?ht(e?.settings??{},["blocks",t,"custom",...o]):void 0)??ht(e?.settings??{},["custom",...o]);return n?Ms(e,t,n):r}function Ms(e,t,r){if(!r||typeof r!="string")if(typeof r=="object"&&r!==null&&"ref"in r&&typeof r.ref=="string"){let l=ht(e,r.ref);if(!l||typeof l=="object"&&"ref"in l)return l;r=l}else return r;let o="var:",n="var(--wp--",i=")",s;if(r.startsWith(o))s=r.slice(o.length).split("|");else if(r.startsWith(n)&&r.endsWith(i))s=r.slice(n.length,-i.length).split("--");else return r;let[a,...u]=s;return a==="preset"?H1(e,t,r,u):a==="custom"?U1(e,t,r,u):r}function Vs(e,t,r,o=!0){let n=t?"."+t:"",i=r?`styles.blocks.${r}${n}`:`styles${n}`;if(!e)return;let s=ht(e,i),a=void 0;if(s===void 0&&a){let l=!0,c=e;for(let m of i.split(".")){if(!c||typeof c!="object"||!Object.hasOwn(c,m)){l=!1;break}c=c[m]}l||(s=ht(e,a))}return o?Ms(e,r,s):s}function wc(e,t,r,o){let n=t?"."+t:"",i=o?`styles.blocks.${o}${n}`:`styles${n}`;return Rn(e,i.split("."),r)}var xc=f(bh(),1);function pi(e,t){return typeof e!="object"||typeof t!="object"?e===t:(0,xc.default)(e?.styles,t?.styles)&&(0,xc.default)(e?.settings,t?.settings)}var Eh=f(Ch(),1);function _h(e){return Object.prototype.toString.call(e)==="[object Object]"}function Rh(e){var t,r;return _h(e)===!1?!1:(t=e.constructor,t===void 0?!0:(r=t.prototype,!(_h(r)===!1||r.hasOwnProperty("isPrototypeOf")===!1)))}function Go(e,t){return(0,Eh.default)(e,t,{isMergeableObject:Rh,customMerge:r=>{if(r==="backgroundImage")return(o,n)=>n??o}})}var ox={grad:.9,turn:360,rad:360/(2*Math.PI)},Jr=function(e){return typeof e=="string"?e.length>0:typeof e=="number"},bt=function(e,t,r){return t===void 0&&(t=0),r===void 0&&(r=Math.pow(10,t)),Math.round(r*e)/r+0},dr=function(e,t,r){return t===void 0&&(t=0),r===void 0&&(r=1),e>r?r:e>t?e:t},Lh=function(e){return(e=isFinite(e)?e%360:0)>0?e:e+360},Th=function(e){return{r:dr(e.r,0,255),g:dr(e.g,0,255),b:dr(e.b,0,255),a:dr(e.a)}},Sc=function(e){return{r:bt(e.r),g:bt(e.g),b:bt(e.b),a:bt(e.a,3)}},nx=/^#([0-9a-f]{3,8})$/i,Ds=function(e){var t=e.toString(16);return t.length<2?"0"+t:t},Nh=function(e){var t=e.r,r=e.g,o=e.b,n=e.a,i=Math.max(t,r,o),s=i-Math.min(t,r,o),a=s?i===t?(r-o)/s:i===r?2+(o-t)/s:4+(t-r)/s:0;return{h:60*(a<0?a+6:a),s:i?s/i*100:0,v:i/255*100,a:n}},Mh=function(e){var t=e.h,r=e.s,o=e.v,n=e.a;t=t/360*6,r/=100,o/=100;var i=Math.floor(t),s=o*(1-r),a=o*(1-(t-i)*r),u=o*(1-(1-t+i)*r),l=i%6;return{r:255*[o,a,s,s,u,o][l],g:255*[u,o,o,a,s,s][l],b:255*[s,s,u,o,o,a][l],a:n}},Ph=function(e){return{h:Lh(e.h),s:dr(e.s,0,100),l:dr(e.l,0,100),a:dr(e.a)}},Oh=function(e){return{h:bt(e.h),s:bt(e.s),l:bt(e.l),a:bt(e.a,3)}},kh=function(e){return Mh((r=(t=e).s,{h:t.h,s:(r*=((o=t.l)<50?o:100-o)/100)>0?2*r/(o+r)*100:0,v:o+r,a:t.a}));var t,r,o},hi=function(e){return{h:(t=Nh(e)).h,s:(n=(200-(r=t.s))*(o=t.v)/100)>0&&n<200?r*o/100/(n<=100?n:200-n)*100:0,l:n/2,a:t.a};var t,r,o,n},ix=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s*,\s*([+-]?\d*\.?\d+)%\s*,\s*([+-]?\d*\.?\d+)%\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,sx=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s+([+-]?\d*\.?\d+)%\s+([+-]?\d*\.?\d+)%\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,ax=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,lx=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,Rc={string:[[function(e){var t=nx.exec(e);return t?(e=t[1]).length<=4?{r:parseInt(e[0]+e[0],16),g:parseInt(e[1]+e[1],16),b:parseInt(e[2]+e[2],16),a:e.length===4?bt(parseInt(e[3]+e[3],16)/255,2):1}:e.length===6||e.length===8?{r:parseInt(e.substr(0,2),16),g:parseInt(e.substr(2,2),16),b:parseInt(e.substr(4,2),16),a:e.length===8?bt(parseInt(e.substr(6,2),16)/255,2):1}:null:null},"hex"],[function(e){var t=ax.exec(e)||lx.exec(e);return t?t[2]!==t[4]||t[4]!==t[6]?null:Th({r:Number(t[1])/(t[2]?100/255:1),g:Number(t[3])/(t[4]?100/255:1),b:Number(t[5])/(t[6]?100/255:1),a:t[7]===void 0?1:Number(t[7])/(t[8]?100:1)}):null},"rgb"],[function(e){var t=ix.exec(e)||sx.exec(e);if(!t)return null;var r,o,n=Ph({h:(r=t[1],o=t[2],o===void 0&&(o="deg"),Number(r)*(ox[o]||1)),s:Number(t[3]),l:Number(t[4]),a:t[5]===void 0?1:Number(t[5])/(t[6]?100:1)});return kh(n)},"hsl"]],object:[[function(e){var t=e.r,r=e.g,o=e.b,n=e.a,i=n===void 0?1:n;return Jr(t)&&Jr(r)&&Jr(o)?Th({r:Number(t),g:Number(r),b:Number(o),a:Number(i)}):null},"rgb"],[function(e){var t=e.h,r=e.s,o=e.l,n=e.a,i=n===void 0?1:n;if(!Jr(t)||!Jr(r)||!Jr(o))return null;var s=Ph({h:Number(t),s:Number(r),l:Number(o),a:Number(i)});return kh(s)},"hsl"],[function(e){var t=e.h,r=e.s,o=e.v,n=e.a,i=n===void 0?1:n;if(!Jr(t)||!Jr(r)||!Jr(o))return null;var s=(function(a){return{h:Lh(a.h),s:dr(a.s,0,100),v:dr(a.v,0,100),a:dr(a.a)}})({h:Number(t),s:Number(r),v:Number(o),a:Number(i)});return Mh(s)},"hsv"]]},Fh=function(e,t){for(var r=0;r=.5},e.prototype.toHex=function(){return t=Sc(this.rgba),r=t.r,o=t.g,n=t.b,s=(i=t.a)<1?Ds(bt(255*i)):"","#"+Ds(r)+Ds(o)+Ds(n)+s;var t,r,o,n,i,s},e.prototype.toRgb=function(){return Sc(this.rgba)},e.prototype.toRgbString=function(){return t=Sc(this.rgba),r=t.r,o=t.g,n=t.b,(i=t.a)<1?"rgba("+r+", "+o+", "+n+", "+i+")":"rgb("+r+", "+o+", "+n+")";var t,r,o,n,i},e.prototype.toHsl=function(){return Oh(hi(this.rgba))},e.prototype.toHslString=function(){return t=Oh(hi(this.rgba)),r=t.h,o=t.s,n=t.l,(i=t.a)<1?"hsla("+r+", "+o+"%, "+n+"%, "+i+")":"hsl("+r+", "+o+"%, "+n+"%)";var t,r,o,n,i},e.prototype.toHsv=function(){return t=Nh(this.rgba),{h:bt(t.h),s:bt(t.s),v:bt(t.v),a:bt(t.a,3)};var t},e.prototype.invert=function(){return fr({r:255-(t=this.rgba).r,g:255-t.g,b:255-t.b,a:t.a});var t},e.prototype.saturate=function(t){return t===void 0&&(t=.1),fr(Cc(this.rgba,t))},e.prototype.desaturate=function(t){return t===void 0&&(t=.1),fr(Cc(this.rgba,-t))},e.prototype.grayscale=function(){return fr(Cc(this.rgba,-1))},e.prototype.lighten=function(t){return t===void 0&&(t=.1),fr(Ah(this.rgba,t))},e.prototype.darken=function(t){return t===void 0&&(t=.1),fr(Ah(this.rgba,-t))},e.prototype.rotate=function(t){return t===void 0&&(t=15),this.hue(this.hue()+t)},e.prototype.alpha=function(t){return typeof t=="number"?fr({r:(r=this.rgba).r,g:r.g,b:r.b,a:t}):bt(this.rgba.a,3);var r},e.prototype.hue=function(t){var r=hi(this.rgba);return typeof t=="number"?fr({h:t,s:r.s,l:r.l,a:r.a}):bt(r.h)},e.prototype.isEqual=function(t){return this.toHex()===fr(t).toHex()},e})(),fr=function(e){return e instanceof Ec?e:new Ec(e)},Ih=[],Vh=function(e){e.forEach(function(t){Ih.indexOf(t)<0&&(t(Ec,Rc),Ih.push(t))})};function ux(e=[]){let t={r:[],g:[],b:[],a:[]};return e.forEach(r=>{let o=fr(r).toRgb();t.r.push(o.r/255),t.g.push(o.g/255),t.b.push(o.b/255),t.a.push(o.a)}),t}function Dh(e){return`${e}{filter:none}`}function Bh(e,t){return`${e}{filter:url(#${t})}`}function jh(e,t){let r=ux(t);return` +var Dv=Object.create;var Oa=Object.defineProperty;var Bv=Object.getOwnPropertyDescriptor;var jv=Object.getOwnPropertyNames;var zv=Object.getPrototypeOf,Hv=Object.prototype.hasOwnProperty;var Wt=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof require<"u"?require:t)[r]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var tt=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),so=(e,t)=>{for(var r in t)Oa(e,r,{get:t[r],enumerable:!0})},Uv=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of jv(t))!Hv.call(e,n)&&n!==r&&Oa(e,n,{get:()=>t[n],enumerable:!(o=Bv(t,n))||o.enumerable});return e};var f=(e,t,r)=>(r=e!=null?Dv(zv(e)):{},Uv(t||!e||!e.__esModule?Oa(r,"default",{value:e,enumerable:!0}):r,e));var ge=tt((AE,Mu)=>{Mu.exports=window.wp.i18n});var Te=tt((LE,Du)=>{Du.exports=window.wp.element});var ve=tt((NE,Bu)=>{Bu.exports=window.React});var Z=tt((HE,Uu)=>{Uu.exports=window.ReactJSXRuntime});var lo=tt((MT,hf)=>{hf.exports=window.ReactDOM});var gd=tt(hd=>{"use strict";var fn=ve();function U0(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var W0=typeof Object.is=="function"?Object.is:U0,G0=fn.useState,Y0=fn.useEffect,q0=fn.useLayoutEffect,Z0=fn.useDebugValue;function X0(e,t){var r=t(),o=G0({inst:{value:r,getSnapshot:t}}),n=o[0].inst,i=o[1];return q0(function(){n.value=r,n.getSnapshot=t,fl(n)&&i({inst:n})},[e,r,t]),Y0(function(){return fl(n)&&i({inst:n}),e(function(){fl(n)&&i({inst:n})})},[e]),Z0(r),r}function fl(e){var t=e.getSnapshot;e=e.value;try{var r=t();return!W0(e,r)}catch{return!0}}function K0(e,t){return t()}var J0=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?K0:X0;hd.useSyncExternalStore=fn.useSyncExternalStore!==void 0?fn.useSyncExternalStore:J0});var ts=tt((TO,yd)=>{"use strict";yd.exports=gd()});var bd=tt(vd=>{"use strict";var rs=ve(),Q0=ts();function $0(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var ew=typeof Object.is=="function"?Object.is:$0,tw=Q0.useSyncExternalStore,rw=rs.useRef,ow=rs.useEffect,nw=rs.useMemo,iw=rs.useDebugValue;vd.useSyncExternalStoreWithSelector=function(e,t,r,o,n){var i=rw(null);if(i.current===null){var s={hasValue:!1,value:null};i.current=s}else s=i.current;i=nw(function(){function u(h){if(!l){if(l=!0,c=h,h=o(h),n!==void 0&&s.hasValue){var g=s.value;if(n(g,h))return m=g}return m=h}if(g=m,ew(c,h))return g;var b=o(h);return n!==void 0&&n(g,b)?(c=h,g):(c=h,m=b)}var l=!1,c,m,d=r===void 0?null:r;return[function(){return u(t())},d===null?void 0:function(){return u(d())}]},[t,r,o,n]);var a=tw(e,i[0],i[1]);return ow(function(){s.hasValue=!0,s.value=a},[a]),iw(a),a}});var xd=tt((OO,wd)=>{"use strict";wd.exports=bd()});var yo=tt((NA,Jp)=>{Jp.exports=window.wp.compose});var um=tt((WA,cm)=>{cm.exports=window.wp.theme});var ai=tt((GA,fm)=>{fm.exports=window.wp.privateApis});var _n=tt((C5,km)=>{km.exports=window.wp.primitives});var ue=tt((g4,Ym)=>{Ym.exports=window.wp.components});var th=tt((k4,eh)=>{eh.exports=window.wp.editor});var sr=tt((F4,rh)=>{rh.exports=window.wp.coreData});var Kt=tt((A4,oh)=>{oh.exports=window.wp.data});var Cn=tt((I4,nh)=>{nh.exports=window.wp.blocks});var Dt=tt((L4,ih)=>{ih.exports=window.wp.blockEditor});var ah=tt((j4,sh)=>{sh.exports=window.wp.styleEngine});var ph=tt((Q4,dh)=>{"use strict";dh.exports=function e(t,r){if(t===r)return!0;if(t&&r&&typeof t=="object"&&typeof r=="object"){if(t.constructor!==r.constructor)return!1;var o,n,i;if(Array.isArray(t)){if(o=t.length,o!=r.length)return!1;for(n=o;n--!==0;)if(!e(t[n],r[n]))return!1;return!0}if(t instanceof Map&&r instanceof Map){if(t.size!==r.size)return!1;for(n of t.entries())if(!r.has(n[0]))return!1;for(n of t.entries())if(!e(n[1],r.get(n[0])))return!1;return!0}if(t instanceof Set&&r instanceof Set){if(t.size!==r.size)return!1;for(n of t.entries())if(!r.has(n[0]))return!1;return!0}if(ArrayBuffer.isView(t)&&ArrayBuffer.isView(r)){if(o=t.length,o!=r.length)return!1;for(n=o;n--!==0;)if(t[n]!==r[n])return!1;return!0}if(t.constructor===RegExp)return t.source===r.source&&t.flags===r.flags;if(t.valueOf!==Object.prototype.valueOf)return t.valueOf()===r.valueOf();if(t.toString!==Object.prototype.toString)return t.toString()===r.toString();if(i=Object.keys(t),o=i.length,o!==Object.keys(r).length)return!1;for(n=o;n--!==0;)if(!Object.prototype.hasOwnProperty.call(r,i[n]))return!1;for(n=o;n--!==0;){var s=i[n];if(!e(t[s],r[s]))return!1}return!0}return t!==t&&r!==r}});var yh=tt((eI,gh)=>{"use strict";var B1=function(t){return j1(t)&&!z1(t)};function j1(e){return!!e&&typeof e=="object"}function z1(e){var t=Object.prototype.toString.call(e);return t==="[object RegExp]"||t==="[object Date]"||W1(e)}var H1=typeof Symbol=="function"&&Symbol.for,U1=H1?Symbol.for("react.element"):60103;function W1(e){return e.$$typeof===U1}function G1(e){return Array.isArray(e)?[]:{}}function mi(e,t){return t.clone!==!1&&t.isMergeableObject(e)?En(G1(e),e,t):e}function Y1(e,t,r){return e.concat(t).map(function(o){return mi(o,r)})}function q1(e,t){if(!t.customMerge)return En;var r=t.customMerge(e);return typeof r=="function"?r:En}function Z1(e){return Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(e).filter(function(t){return Object.propertyIsEnumerable.call(e,t)}):[]}function mh(e){return Object.keys(e).concat(Z1(e))}function hh(e,t){try{return t in e}catch{return!1}}function X1(e,t){return hh(e,t)&&!(Object.hasOwnProperty.call(e,t)&&Object.propertyIsEnumerable.call(e,t))}function K1(e,t,r){var o={};return r.isMergeableObject(e)&&mh(e).forEach(function(n){o[n]=mi(e[n],r)}),mh(t).forEach(function(n){X1(e,n)||(hh(e,n)&&r.isMergeableObject(t[n])?o[n]=q1(n,r)(e[n],t[n],r):o[n]=mi(t[n],r))}),o}function En(e,t,r){r=r||{},r.arrayMerge=r.arrayMerge||Y1,r.isMergeableObject=r.isMergeableObject||B1,r.cloneUnlessOtherwiseSpecified=mi;var o=Array.isArray(t),n=Array.isArray(e),i=o===n;return i?o?r.arrayMerge(e,t,r):K1(e,t,r):mi(t,r)}En.all=function(t,r){if(!Array.isArray(t))throw new Error("first argument should be an array");return t.reduce(function(o,n){return En(o,n,r)},{})};var J1=En;gh.exports=J1});var Zc=tt((WN,Pg)=>{Pg.exports=window.wp.keycodes});var Ag=tt((r8,Fg)=>{Fg.exports=window.wp.apiFetch});var gv=tt((X9,hv)=>{hv.exports=window.wp.date});function Vu(e){var t,r,o="";if(typeof e=="string"||typeof e=="number")o+=e;else if(typeof e=="object")if(Array.isArray(e)){var n=e.length;for(t=0;te();function Pe(e){let t=_t(qv).current;return t.next=e,Yv(t.effect),t.trampoline}function qv(){let e={next:void 0,callback:Zv,trampoline:(...t)=>e.callback?.(...t),effect:()=>{e.callback=e.next}};return e}function Zv(){}var Hu=f(ve(),1),Xv=()=>{},we=typeof document<"u"?Hu.useLayoutEffect:Xv;function Kv(e,t){return function(o,...n){let i=new URL(e);return i.searchParams.set("code",o.toString()),n.forEach(s=>i.searchParams.append("args[]",s)),`${t} error #${o}; visit ${i} for the full message.`}}var Jv=Kv("https://base-ui.com/production-error","Base UI"),lr=Jv;var Ao=f(ve(),1);function Fa(e,t,r,o){let n=_t(Gu).current;return Qv(n,e,t,r,o)&&Yu(n,[e,t,r,o]),n.callback}function Wu(e){let t=_t(Gu).current;return $v(t,e)&&Yu(t,e),t.callback}function Gu(){return{callback:null,cleanup:null,refs:[]}}function Qv(e,t,r,o,n){return e.refs[0]!==t||e.refs[1]!==r||e.refs[2]!==o||e.refs[3]!==n}function $v(e,t){return e.refs.length!==t.length||e.refs.some((r,o)=>r!==t[o])}function Yu(e,t){if(e.refs=t,t.every(r=>r==null)){e.callback=null;return}e.callback=r=>{if(e.cleanup&&(e.cleanup(),e.cleanup=null),r!=null){let o=Array(t.length).fill(null);for(let n=0;n{for(let n=0;n=e}function Aa(e){if(!Zu.isValidElement(e))return null;let t=e,r=t.props;return(rn(19)?r?.ref:t.ref)??null}function Yn(e,t){if(e&&!t)return e;if(!e&&t)return t;if(e||t)return{...e,...t}}function tr(){}var Xu=Object.freeze([]),nt=Object.freeze({});function Ku(e,t){let r={};for(let o in e){let n=e[o];if(t?.hasOwnProperty(o)){let i=t[o](n);i!=null&&Object.assign(r,i);continue}n===!0?r[`data-${o.toLowerCase()}`]="":n&&(r[`data-${o.toLowerCase()}`]=n.toString())}return r}function Ju(e,t){return typeof e=="function"?e(t):e}function Qu(e,t){return typeof e=="function"?e(t):e}var Ia={};function It(e,t,r,o,n){if(!r&&!o&&!n&&!e)return Ai(t);let i=Ai(e);return t&&(i=qn(i,t)),r&&(i=qn(i,r)),o&&(i=qn(i,o)),n&&(i=qn(i,n)),i}function $u(e){if(e.length===0)return Ia;if(e.length===1)return Ai(e[0]);let t=Ai(e[0]);for(let r=1;r=65&&n<=90&&(typeof t=="function"||typeof t>"u")}function La(e){return typeof e=="function"}function tf(e,t){return La(e)?e(t):e??Ia}function ob(e,t){return t?e?(...r)=>{let o=r[0];if(nf(o)){let i=o;of(i);let s=t(...r);return i.baseUIHandlerPrevented||e?.(...r),s}let n=t(...r);return e?.(...r),n}:rf(t):e}function rf(e){return e&&((...t)=>{let r=t[0];return nf(r)&&of(r),e(...t)})}function of(e){return e.preventBaseUIHandler=()=>{e.baseUIHandlerPrevented=!0},e}function Na(e,t){return t?e?t+" "+e:t:e}function nf(e){return e!=null&&typeof e=="object"&&"nativeEvent"in e}var Ma=f(ve(),1);function Gt(e,t,r={}){let o=t.render,n=nb(t,r);if(r.enabled===!1)return null;let i=r.state??nt;return ab(e,o,n,i)}function nb(e,t={}){let{className:r,style:o,render:n}=e,{state:i=nt,ref:s,props:a,stateAttributesMapping:u,enabled:l=!0}=t,c=l?Ju(r,i):void 0,m=l?Qu(o,i):void 0,d=l?Ku(i,u):nt,h=l&&a?ib(a):void 0,g=l?Yn(d,h)??{}:nt;return typeof document<"u"&&(l?Array.isArray(s)?g.ref=Wu([g.ref,Aa(n),...s]):g.ref=Fa(g.ref,Aa(n),s):Fa(null,null)),l?(c!==void 0&&(g.className=Na(g.className,c)),m!==void 0&&(g.style=Yn(g.style,m)),g):nt}function ib(e){return Array.isArray(e)?$u(e):It(void 0,e)}var sb=Symbol.for("react.lazy");function ab(e,t,r,o){if(t){if(typeof t=="function")return t(r,o);let n=It(r,t.props);n.ref=r.ref;let i=t;return i?.$$typeof===sb&&(i=Ao.Children.toArray(t)[0]),Ao.cloneElement(i,n)}if(e&&typeof e=="string")return lb(e,r);throw new Error(lr(8))}function lb(e,t){return e==="button"?(0,Ma.createElement)("button",{type:"button",...t,key:t.key}):e==="img"?(0,Ma.createElement)("img",{alt:"",...t,key:t.key}):Ao.createElement(e,t)}var Ii=f(ve(),1);var sf=0;function cb(e,t="mui"){let[r,o]=Ii.useState(e),n=e||r;return Ii.useEffect(()=>{r==null&&(sf+=1,o(`${t}-${sf}`))},[r,t]),n}var af=Gn.useId;function on(e,t){if(af!==void 0){let r=af();return e??(t?`${t}-${r}`:r)}return cb(e,t)}function lf(e){return on(e,"base-ui")}var Oe={};so(Oe,{cancelOpen:()=>Vb,chipRemovePress:()=>bb,clearPress:()=>vb,closePress:()=>gb,closeWatcher:()=>kb,decrementPress:()=>Sb,disabled:()=>Bb,drag:()=>Lb,escapeKey:()=>Ob,focusOut:()=>Pb,imperativeAction:()=>Hb,incrementPress:()=>xb,initial:()=>zb,inputBlur:()=>Rb,inputChange:()=>_b,inputClear:()=>Cb,inputPaste:()=>Eb,inputPress:()=>Tb,itemPress:()=>hb,keyboard:()=>Ab,linkPress:()=>yb,listNavigation:()=>Fb,missing:()=>jb,none:()=>ub,outsidePress:()=>mb,pointer:()=>Ib,scrub:()=>Mb,siblingOpen:()=>Db,swipe:()=>Ub,trackPress:()=>wb,triggerFocus:()=>pb,triggerHover:()=>db,triggerPress:()=>fb,wheel:()=>Nb,windowResize:()=>Wb});var ub="none",fb="trigger-press",db="trigger-hover",pb="trigger-focus",mb="outside-press",hb="item-press",gb="close-press",yb="link-press",vb="clear-press",bb="chip-remove-press",wb="track-press",xb="increment-press",Sb="decrement-press",_b="input-change",Cb="input-clear",Rb="input-blur",Eb="input-paste",Tb="input-press",Pb="focus-out",Ob="escape-key",kb="close-watcher",Fb="list-navigation",Ab="keyboard",Ib="pointer",Lb="drag",Nb="wheel",Mb="scrub",Vb="cancel-open",Db="sibling-open",Bb="disabled",jb="missing",zb="initial",Hb="imperative-action",Ub="swipe",Wb="window-resize";function Ve(e,t,r,o){let n=!1,i=!1,s=o??nt;return{reason:e,event:t??new Event("base-ui"),cancel(){n=!0},allowPropagation(){i=!0},get isCanceled(){return n},get isPropagationAllowed(){return i},trigger:r,...s}}var Da=f(ve(),1);var cf=f(ve(),1);function nn(e){cf.useEffect(e,Xu)}var Li=null,_T=globalThis.requestAnimationFrame,Va=class{callbacks=[];callbacksCount=0;nextId=1;startId=1;isScheduled=!1;tick=t=>{this.isScheduled=!1;let r=this.callbacks,o=this.callbacksCount;if(this.callbacks=[],this.callbacksCount=0,this.startId=this.nextId,o>0)for(let n=0;n=this.callbacks.length||(this.callbacks[r]=null,this.callbacksCount-=1)}},Ni=new Va;var Fr=class e{static create(){return new e}static request(t){return Ni.request(t)}static cancel(t){return Ni.cancel(t)}currentId=Li;request(t){this.cancel(),this.currentId=Ni.request(()=>{this.currentId=Li,t()})}cancel=()=>{this.currentId!==Li&&(Ni.cancel(this.currentId),this.currentId=Li)};disposeEffect=()=>this.cancel};function sn(){let e=_t(Fr.create).current;return nn(e.disposeEffect),e}function uf(e,t=!1,r=!1){let[o,n]=Da.useState(e&&t?"idle":void 0),[i,s]=Da.useState(e);return e&&!i&&(s(!0),n("starting")),!e&&i&&o!=="ending"&&!r&&n("ending"),!e&&!i&&o==="ending"&&n(void 0),we(()=>{if(!e&&i&&o!=="ending"&&r){let a=Fr.request(()=>{n("ending")});return()=>{Fr.cancel(a)}}},[e,i,o,r]),we(()=>{if(!e||t)return;let a=Fr.request(()=>{n(void 0)});return()=>{Fr.cancel(a)}},[t,e]),we(()=>{if(!e||!t)return;e&&i&&o!=="idle"&&n("starting");let a=Fr.request(()=>{n("idle")});return()=>{Fr.cancel(a)}},[t,e,i,o]),{mounted:i,setMounted:s,transitionStatus:o}}var Ba=(function(e){return e.startingStyle="data-starting-style",e.endingStyle="data-ending-style",e})({}),Gb={"data-starting-style":""},Yb={"data-ending-style":""},ff={transitionStatus(e){return e==="starting"?Gb:e==="ending"?Yb:null}};function Mi(){return typeof window<"u"}function Lo(e){return Vi(e)?(e.nodeName||"").toLowerCase():"#document"}function it(e){var t;return(e==null||(t=e.ownerDocument)==null?void 0:t.defaultView)||window}function Ir(e){var t;return(t=(Vi(e)?e.ownerDocument:e.document)||window.document)==null?void 0:t.documentElement}function Vi(e){return Mi()?e instanceof Node||e instanceof it(e).Node:!1}function Re(e){return Mi()?e instanceof Element||e instanceof it(e).Element:!1}function Ct(e){return Mi()?e instanceof HTMLElement||e instanceof it(e).HTMLElement:!1}function an(e){return!Mi()||typeof ShadowRoot>"u"?!1:e instanceof ShadowRoot||e instanceof it(e).ShadowRoot}function Zn(e){let{overflow:t,overflowX:r,overflowY:o,display:n}=Lt(e);return/auto|scroll|overlay|hidden|clip/.test(t+o+r)&&n!=="inline"&&n!=="contents"}function df(e){return/^(table|td|th)$/.test(Lo(e))}function Xn(e){try{if(e.matches(":popover-open"))return!0}catch{}try{return e.matches(":modal")}catch{return!1}}var qb=/transform|translate|scale|rotate|perspective|filter/,Zb=/paint|layout|strict|content/,Io=e=>!!e&&e!=="none",ja;function Di(e){let t=Re(e)?Lt(e):e;return Io(t.transform)||Io(t.translate)||Io(t.scale)||Io(t.rotate)||Io(t.perspective)||!Bi()&&(Io(t.backdropFilter)||Io(t.filter))||qb.test(t.willChange||"")||Zb.test(t.contain||"")}function pf(e){let t=Ar(e);for(;Ct(t)&&!Lr(t);){if(Di(t))return t;if(Xn(t))return null;t=Ar(t)}return null}function Bi(){return ja==null&&(ja=typeof CSS<"u"&&CSS.supports&&CSS.supports("-webkit-backdrop-filter","none")),ja}function Lr(e){return/^(html|body|#document)$/.test(Lo(e))}function Lt(e){return it(e).getComputedStyle(e)}function Kn(e){return Re(e)?{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}:{scrollLeft:e.scrollX,scrollTop:e.scrollY}}function Ar(e){if(Lo(e)==="html")return e;let t=e.assignedSlot||e.parentNode||an(e)&&e.host||Ir(e);return an(t)?t.host:t}function mf(e){let t=Ar(e);return Lr(t)?(e.ownerDocument||e).body:Ct(t)&&Zn(t)?t:mf(t)}function ao(e,t,r){var o;t===void 0&&(t=[]),r===void 0&&(r=!0);let n=mf(e),i=n===((o=e.ownerDocument)==null?void 0:o.body),s=it(n);if(i){let a=ji(s);return t.concat(s,s.visualViewport||[],Zn(n)?n:[],a&&r?ao(a):[])}else return t.concat(n,ao(n,[],r))}function ji(e){return e.parent&&Object.getPrototypeOf(e.parent)?e.frameElement:null}function Rt(e){return e?.ownerDocument||document}function ze(e,t,r,o){return e.addEventListener(t,r,o),()=>{e.removeEventListener(t,r,o)}}function Yt(e){let t=_t(Xb,e).current;return t.next=e,we(t.effect),t}function Xb(e){let t={current:e,next:e,effect:()=>{t.current=t.next}};return t}var vf=f(ve(),1);var yf=f(lo(),1);function gf(e){return e==null?e:"current"in e?e.current:e}function ln(e,t=!1){let r=sn();return Pe((o,n=null)=>{r.cancel();let i=gf(e);if(i==null)return;let s=i,a=()=>{yf.flushSync(o)};if(typeof s.getAnimations!="function"||globalThis.BASE_UI_ANIMATIONS_DISABLED){o();return}function u(){Promise.all(s.getAnimations().map(l=>l.finished)).then(()=>{n?.aborted||a()},()=>{if(n?.aborted)return;if(s.getAnimations().some(c=>c.pending||c.playState!=="finished")){u();return}a()})}if(t){let l="data-starting-style";if(!s.hasAttribute(l)){r.request(u);return}let c=new MutationObserver(()=>{s.hasAttribute(l)||(c.disconnect(),u())});c.observe(s,{attributes:!0,attributeFilter:[l]}),n?.addEventListener("abort",()=>c.disconnect(),{once:!0});return}r.request(u)})}function zi(e){let{enabled:t=!0,open:r,ref:o,onComplete:n}=e,i=Pe(n),s=ln(o,r);vf.useEffect(()=>{if(!t)return;let a=new AbortController;return s(i,a.signal),()=>{a.abort()}},[t,r,i,s])}var Zr={};so(Zr,{engine:()=>Ga,env:()=>qa,os:()=>Ua,screenReader:()=>Ya});var Ua={};so(Ua,{android:()=>xf,apple:()=>Ha,ios:()=>za,linux:()=>e0,mac:()=>Sf,windows:()=>$b});function Kb(){return typeof navigator>"u"?{userAgent:"",platform:"",maxTouchPoints:0}:{userAgent:navigator.userAgent,platform:navigator.platform??"",maxTouchPoints:navigator.maxTouchPoints??0}}var{userAgent:Jb,platform:Qb,maxTouchPoints:bf}=Kb(),No=Jb.toLowerCase(),Mo=Qb.toLowerCase();var za=/^i(os$|p)/.test(Mo)||Mo==="macintel"&&bf>1,wf="android",xf=Mo===wf||No.includes(wf),Sf=!za&&Mo.startsWith("mac"),$b=Mo.startsWith("win"),e0=!xf&&/^(linux|chrome os)/.test(Mo),Ha=Sf||za;var Ga={};so(Ga,{blink:()=>r0,gecko:()=>t0,webkit:()=>Wa});var Wa=typeof CSS<"u"&&!!CSS.supports?.("-webkit-backdrop-filter:none"),t0=!Wa&&No.includes("firefox"),r0=!Wa&&No.includes("chrom");var Ya={};so(Ya,{voiceOver:()=>o0});var o0=Ha;var qa={};so(qa,{jsdom:()=>n0});var n0=/jsdom|happydom/.test(No);var Jn=0,rr=class e{static create(){return new e}currentId=Jn;start(t,r){this.clear(),this.currentId=setTimeout(()=>{this.currentId=Jn,r()},t)}isStarted(){return this.currentId!==Jn}clear=()=>{this.currentId!==Jn&&(clearTimeout(this.currentId),this.currentId=Jn)};disposeEffect=()=>this.clear};function wr(){let e=_t(rr.create).current;return nn(e.disposeEffect),e}var Mt=f(ve(),1);function _f(e){return"nativeEvent"in e}function Xr(e,t){let r=["mouse","pen"];return t||r.push("",void 0),r.includes(e)}function Cf(e){let t=e.type;return t==="click"||t==="mousedown"||t==="keydown"||t==="keyup"}var Za="data-base-ui-focusable";var Xa="input:not([type='hidden']):not([disabled]),[contenteditable]:not([contenteditable='false']),textarea:not([disabled])";function Hi(e){let t=e.activeElement;for(;t?.shadowRoot?.activeElement!=null;)t=t.shadowRoot.activeElement;return t}function Ge(e,t){if(!e||!t)return!1;let r=t.getRootNode?.();if(e.contains(t))return!0;if(r&&an(r)){let o=t;for(;o;){if(e===o)return!0;o=o.parentNode||o.host}}return!1}function Nt(e){return"composedPath"in e?e.composedPath()[0]:e.target}function co(e,t){if(!Re(e))return!1;let r=e;if(t.hasElement(r))return!r.hasAttribute("data-trigger-disabled");for(let[,o]of t.entries())if(Ge(o,r))return!o.hasAttribute("data-trigger-disabled");return!1}function Ui(e,t){if(t==null)return!1;if("composedPath"in e)return e.composedPath().includes(t);let r=e;return r.target!=null&&t.contains(r.target)}function Rf(e){return e.matches("html,body")}function Ef(e){return Ct(e)&&e.matches(Xa)}function Ka(e){return e?.closest(`button,a[href],[role="button"],select,[tabindex]:not([tabindex="-1"]),${Xa}`)!=null}function Tf(e){if(!e||Zr.env.jsdom)return!0;try{return e.matches(":focus-visible")}catch{return!0}}function i0(e,t){return t!=null&&!Xr(t)?0:typeof e=="function"?e():e}function cr(e,t,r){let o=i0(e,r);return typeof o=="number"?o:o?.[t]}function Ja(e){return typeof e=="function"?e():e}function Wi(e,t){return t||e==="click"||e==="mousedown"}function Pf(e){return e?.includes("mouse")&&e!=="mousedown"}var Of=f(Z(),1),kf=Mt.createContext({hasProvider:!1,timeoutMs:0,delayRef:{current:0},initialDelayRef:{current:0},timeout:new rr,currentIdRef:{current:null},currentContextRef:{current:null}});function s0(e,t){e.current=t.current}function Qa(e){let{children:t,delay:r,timeoutMs:o=0}=e,n=Mt.useRef(r),i=Mt.useRef(r),s=Mt.useRef(null),a=Mt.useRef(null),u=wr();return we(()=>{if(i.current=r,!s.current){n.current=r;return}n.current={open:cr(n.current,"open"),close:cr(r,"close")}},[r,s,n,i]),(0,Of.jsx)(kf.Provider,{value:Mt.useMemo(()=>({hasProvider:!0,delayRef:n,initialDelayRef:i,currentIdRef:s,timeoutMs:o,currentContextRef:a,timeout:u}),[o,u]),children:t})}function $a(e,t={open:!1}){let{open:r}=t,o="rootStore"in e?e.rootStore:e,n=o.useState("floatingId"),i=Mt.useContext(kf),{currentIdRef:s,delayRef:a,timeoutMs:u,initialDelayRef:l,currentContextRef:c,hasProvider:m,timeout:d}=i,[h,g]=Mt.useState(!1),b=Mt.useRef(r);return we(()=>{b.current=r},[r]),we(()=>{function w(){c.current?.setIsInstantPhase(!1),s.current=null,c.current=null,a.current=l.current,d.clear()}if(s.current&&!r&&s.current===n){if(g(!1),u){let _=n;return d.start(u,()=>{o.select("open")||s.current&&s.current!==_||w()}),()=>{(b.current||s.current!==_)&&d.clear()}}w()}},[r,n,s,a,u,l,c,d,o]),we(()=>{if(!r)return;let w=c.current,_=s.current;d.clear(),c.current={onOpenChange:o.setOpen,setIsInstantPhase:g},s.current=n,a.current={open:0,close:cr(l.current,"close")},_!==null&&_!==n?(g(!0),w?.setIsInstantPhase(!0),w?.onOpenChange(!1,Ve(Oe.none))):(g(!1),w?.setIsInstantPhase(!1))},[r,n,o,s,a,l,c,d]),we(()=>()=>{if(s.current===n){if(c.current=null,!b.current)return;s.current=null,s0(a,l),d.clear()}},[c,s,a,n,l,d]),Mt.useMemo(()=>({hasProvider:m,delayRef:a,isInstantPhase:h}),[m,a,h])}function xr(...e){return()=>{for(let t=0;t({x:e,y:e}),a0={left:"right",right:"left",bottom:"top",top:"bottom"};function Yi(e,t,r){return Sr(e,uo(t,r))}function Mr(e,t){return typeof e=="function"?e(t):e}function Tt(e){return e.split("-")[0]}function _r(e){return e.split("-")[1]}function qi(e){return e==="x"?"y":"x"}function ei(e){return e==="y"?"height":"width"}function qt(e){let t=e[0];return t==="t"||t==="b"?"y":"x"}function ti(e){return qi(qt(e))}function If(e,t,r){r===void 0&&(r=!1);let o=_r(e),n=ti(e),i=ei(n),s=n==="x"?o===(r?"end":"start")?"right":"left":o==="start"?"bottom":"top";return t.reference[i]>t.floating[i]&&(s=Qn(s)),[s,Qn(s)]}function Lf(e){let t=Qn(e);return[Gi(e),t,Gi(t)]}function Gi(e){return e.includes("start")?e.replace("start","end"):e.replace("end","start")}var Ff=["left","right"],Af=["right","left"],l0=["top","bottom"],c0=["bottom","top"];function u0(e,t,r){switch(e){case"top":case"bottom":return r?t?Af:Ff:t?Ff:Af;case"left":case"right":return t?l0:c0;default:return[]}}function Nf(e,t,r,o){let n=_r(e),i=u0(Tt(e),r==="start",o);return n&&(i=i.map(s=>s+"-"+n),t&&(i=i.concat(i.map(Gi)))),i}function Qn(e){let t=Tt(e);return a0[t]+e.slice(t.length)}function f0(e){var t,r,o,n;return{top:(t=e.top)!=null?t:0,right:(r=e.right)!=null?r:0,bottom:(o=e.bottom)!=null?o:0,left:(n=e.left)!=null?n:0}}function Zi(e){return typeof e!="number"?f0(e):{top:e,right:e,bottom:e,left:e}}function Vo(e){let{x:t,y:r,width:o,height:n}=e;return{width:o,height:n,top:r,left:t,right:t+o,bottom:r+n,x:t,y:r}}function Kr(e,t,r=!0){return e.filter(n=>n.parentId===t).flatMap(n=>[...!r||n.context?.open?[n]:[],...Kr(e,n.id,r)])}function cn(e){return`data-base-ui-${e}`}var Vt=f(ve(),1),Df=f(lo(),1);var Mf={style:{transition:"none"}};var d0="data-base-ui-swipe-ignore",p0="data-swipe-ignore",SP=`[${d0}]`,_P=`[${p0}]`;var Vf={fallbackAxisSide:"end"};var Bf=f(Z(),1),m0=Vt.createContext(null),h0=()=>Vt.useContext(m0),g0=cn("portal");function jf(e={}){let{ref:t,container:r,componentProps:o=nt,elementProps:n}=e,i=on(),a=h0()?.portalNode,[u,l]=Vt.useState(null),[c,m]=Vt.useState(null),d=Pe(w=>{w!==null&&m(w)}),h=Vt.useRef(null);we(()=>{if(r===null){h.current&&(h.current=null,m(null),l(null));return}let w=(r&&(Vi(r)?r:r.current))??a??document.body;if(w==null){h.current&&(h.current=null,m(null),l(null));return}h.current!==w&&(h.current=w,m(null),l(w))},[r,a]);let g=Gt("div",o,{ref:[t,d],props:[{id:i,[g0]:""},n]}),b=u&&g?Df.createPortal(g,u):null;return{node:c,nodeId:Vt.isValidElement(g)?g.props.id:void 0,subtree:b}}var Do=f(ve(),1);function zf(){let e=new Map;return{emit(t,r){e.get(t)?.forEach(o=>o(r))},on(t,r){e.has(t)||e.set(t,new Set),e.get(t).add(r)},off(t,r){e.get(t)?.delete(r)}}}var y0=f(Z(),1),v0=Do.createContext(null),b0=Do.createContext(null),Xi=()=>Do.useContext(v0)?.id||null,po=e=>{let t=Do.useContext(b0);return e??t};var Zt=f(ve(),1);function w0(e,t){let r=null,o=null,n=!1;return{contextElement:e||void 0,getBoundingClientRect(){let i=e?.getBoundingClientRect()||{width:0,height:0,x:0,y:0},s=t.axis==="x"||t.axis==="both",a=t.axis==="y"||t.axis==="both",u=["mouseenter","mousemove"].includes(t.dataRef.current.openEvent?.type||"")&&t.pointerType!=="touch",l=i.width,c=i.height,m=i.x,d=i.y;return r==null&&t.x&&s&&(r=i.x-t.x),o==null&&t.y&&a&&(o=i.y-t.y),m-=r||0,d-=o||0,l=0,c=0,!n||u?(l=t.axis==="y"?i.width:0,c=t.axis==="x"?i.height:0,m=s&&t.x!=null?t.x:m,d=a&&t.y!=null?t.y:d):n&&!u&&(c=t.axis==="x"?i.height:c,l=t.axis==="y"?i.width:l),n=!0,{width:l,height:c,x:m,y:d,top:d,right:m+l,bottom:d+c,left:m}}}}function Hf(e){return e!=null&&e.clientX!=null}function el(e,t={}){let{enabled:r=!0,axis:o="both"}=t,n="rootStore"in e?e.rootStore:e,i=n.useState("open"),s=n.useState("floatingElement"),a=n.useState("domReferenceElement"),u=n.context.dataRef,l=Zt.useRef(!1),c=Zt.useRef(null),[m,d]=Zt.useState(),[h,g]=Zt.useState([]),b=Pe(C=>{n.set("positionReference",C)}),w=Pe((C,k,E)=>{l.current||u.current.openEvent&&!Hf(u.current.openEvent)||n.set("positionReference",w0(E??a,{x:C,y:k,axis:o,dataRef:u,pointerType:m}))}),_=Pe(C=>{i?c.current||(w(C.clientX,C.clientY,C.currentTarget),g([])):w(C.clientX,C.clientY,C.currentTarget)}),x=Xr(m)?s:i;Zt.useEffect(()=>{if(!r){b(a);return}if(!x)return;function C(){c.current?.(),c.current=null}let k=it(s);function E(T){let O=Nt(T);Ge(s,O)?C():w(T.clientX,T.clientY)}return!u.current.openEvent||Hf(u.current.openEvent)?c.current=ze(k,"mousemove",E):b(a),C},[x,r,s,u,a,n,w,b,h]),Zt.useEffect(()=>()=>{n.set("positionReference",null)},[n]),Zt.useEffect(()=>{r&&!s&&(l.current=!1)},[r,s]),Zt.useEffect(()=>{!r&&i&&(l.current=!0)},[r,i]);let v=Zt.useMemo(()=>{function C(k){d(k.pointerType)}return{onPointerDown:C,onPointerEnter:C,onMouseMove:_,onMouseEnter:_}},[_]);return Zt.useMemo(()=>r?{reference:v,trigger:v}:{},[r,v])}var or=f(ve(),1);function x0(){return!1}function S0(e){return{escapeKey:typeof e=="boolean"?e:e?.escapeKey??!1,outsidePress:typeof e=="boolean"?e:e?.outsidePress??!0}}function tl(e,t={}){let{enabled:r=!0,escapeKey:o=!0,outsidePress:n=!0,outsidePressEvent:i="sloppy",referencePress:s=x0,bubbles:a,externalTree:u}=t,l="rootStore"in e?e.rootStore:e,c=l.useState("open"),m=l.useState("floatingElement"),{dataRef:d}=l.context,h=po(u),g=Pe(typeof n=="function"?n:()=>!1),b=typeof n=="function"?g:n,w=b!==!1,_=Pe(()=>i),{escapeKey:x,outsidePress:v}=S0(a),C=or.useRef(!1),k=or.useRef(!1),E=or.useRef(!1),T=or.useRef(!1),O=or.useRef(""),I=or.useRef(null),J=wr(),D=wr(),S=Pe(()=>{D.clear(),d.current.insideReactTree=!1}),L=Pe(P=>{let W=d.current.floatingContext?.nodeId;return(h?Kr(h.nodesRef.current,W):[]).some(xe=>xe.context?.open&&!xe.context.dataRef.current[P])}),Y=Pe(P=>Ui(P,l.select("floatingElement"))||Ui(P,l.select("domReferenceElement"))),A=Pe(P=>{s()&&l.setOpen(!1,Ve(Oe.triggerPress,P.nativeEvent))}),N=Pe(P=>{if(!c||!r||!o||P.key!=="Escape"||T.current||!x&&L("__escapeKeyBubbles"))return;let W=_f(P)?P.nativeEvent:P,ne=Ve(Oe.escapeKey,W);l.setOpen(!1,ne),ne.isCanceled||P.preventDefault(),!x&&!ne.isPropagationAllowed&&P.stopPropagation()}),q=Pe(()=>{d.current.insideReactTree=!0,D.start(0,S)}),U=Pe(P=>{if(!c||!r||P.button!==0)return;let W=Nt(P.nativeEvent);Ge(l.select("floatingElement"),W)&&(C.current||(C.current=!0,k.current=!1))}),R=Pe(P=>{!c||!r||(P.defaultPrevented||P.nativeEvent.defaultPrevented)&&C.current&&(k.current=!0)});or.useEffect(()=>{if(!c||!r)return S;d.current.__escapeKeyBubbles=x,d.current.__outsidePressBubbles=v;let P=new rr,W=new rr;function ne(){P.clear(),T.current=!0}function xe(){P.start(Zr.engine.webkit?5:0,()=>{T.current=!1})}function se(){E.current=!0,W.start(0,()=>{E.current=!1})}function be(){C.current=!1,k.current=!1}function ye(){let V=O.current,te=V==="pen"||!V?"mouse":V,Ne=_(),He=typeof Ne=="function"?Ne():Ne;return typeof He=="string"?He:He[te]}function $(V){let te=ye();return te==="intentional"&&V.type!=="click"||te==="sloppy"&&V.type==="click"}function Ce(V){let te=d.current.floatingContext?.nodeId,Ne=h&&Kr(h.nodesRef.current,te).some(He=>Ui(V,He.context?.elements.floating));return Y(V)||Ne}function Fe(V){if($(V)){V.type!=="click"&&!Y(V)&&(W.clear(),E.current=!1),S();return}if(d.current.insideReactTree){S();return}let te=Nt(V),Ne=`[${cn("inert")}]`,He=Re(te)?te.getRootNode():null,ot=Array.from((an(He)?He:Rt(l.select("floatingElement"))).querySelectorAll(Ne)),Ze=l.context.triggerElements;if(te&&(Ze.hasElement(te)||Ze.hasMatchingElement(Ue=>Ge(Ue,te))))return;let Be=Re(te)?te:null;for(;Be&&!Lr(Be);){let Ue=Ar(Be);if(Lr(Ue)||!Re(Ue))break;Be=Ue}if(!(ot.length&&Re(te)&&!Rf(te)&&!Ge(te,l.select("floatingElement"))&&ot.every(Ue=>!Ge(Be,Ue)))){if(Ct(te)&&!("touches"in V)){let Ue=Lr(te),ct=Lt(te),Se=/auto|scroll/,Or=Ue||Se.test(ct.overflowX),$t=Ue||Se.test(ct.overflowY),Ye=Or&&te.clientWidth>0&&te.scrollWidth>te.clientWidth,Yr=$t&&te.clientHeight>0&&te.scrollHeight>te.clientHeight,St=ct.direction==="rtl",kt=Yr&&(St?V.offsetX<=te.offsetWidth-te.clientWidth:V.offsetX>te.clientWidth),vt=Ye&&V.offsetY>te.clientHeight;if(kt||vt)return}if(!Ce(V)){if(ye()==="intentional"&&E.current){W.clear(),E.current=!1;return}typeof b=="function"&&!b(V)||L("__outsidePressBubbles")||(l.setOpen(!1,Ve(Oe.outsidePress,V)),S())}}}function xt(V){ye()!=="sloppy"||V.pointerType==="touch"||!l.select("open")||!r||Y(V)||Fe(V)}function Le(V){if(ye()!=="sloppy"||!l.select("open")||!r||Y(V))return;let te=V.touches[0];te&&(I.current={startTime:Date.now(),startX:te.clientX,startY:te.clientY,dismissOnTouchEnd:!1,dismissOnMouseDown:!0},J.start(1e3,()=>{I.current&&(I.current.dismissOnTouchEnd=!1,I.current.dismissOnMouseDown=!1)}))}function X(V,te){let Ne=Nt(V);if(!Ne)return;let He=ze(Ne,V.type,()=>{te(V),He()})}function M(V){O.current="touch",X(V,Le)}function K(V){J.clear(),V.type==="pointerdown"&&(O.current=V.pointerType),!(V.type==="mousedown"&&I.current&&!I.current.dismissOnMouseDown)&&X(V,te=>{te.type==="pointerdown"?xt(te):Fe(te)})}function H(V){if(!C.current)return;let te=k.current;if(be(),ye()==="intentional"){if(V.type==="pointercancel"){te&&se();return}if(!Ce(V)){if(te){se();return}typeof b=="function"&&!b(V)||(W.clear(),E.current=!0,S())}}}function Q(V){if(ye()!=="sloppy"||!I.current||Y(V))return;let te=V.touches[0];if(!te)return;let Ne=Math.abs(te.clientX-I.current.startX),He=Math.abs(te.clientY-I.current.startY),ot=Math.sqrt(Ne*Ne+He*He);ot>5&&(I.current.dismissOnTouchEnd=!0),ot>10&&(Fe(V),J.clear(),I.current=null)}function pe(V){X(V,Q)}function le(V){ye()!=="sloppy"||!I.current||Y(V)||(I.current.dismissOnTouchEnd&&Fe(V),J.clear(),I.current=null)}function fe(V){X(V,le)}let me=Rt(m),he=xr(o&&xr(ze(me,"keydown",N),ze(me,"compositionstart",ne),ze(me,"compositionend",xe)),w&&xr(ze(me,"click",K,!0),ze(me,"pointerdown",K,!0),ze(me,"pointerup",H,!0),ze(me,"pointercancel",H,!0),ze(me,"mousedown",K,!0),ze(me,"mouseup",H,!0),ze(me,"touchstart",M,!0),ze(me,"touchmove",pe,!0),ze(me,"touchend",fe,!0)));return()=>{he(),P.clear(),W.clear(),be(),E.current=!1,S()}},[d,m,o,w,b,c,r,x,v,N,S,_,L,Y,h,l,J]);let B=or.useMemo(()=>({onKeyDown:N,onPointerDown:A,onClick:A}),[N,A]),re=or.useMemo(()=>({onKeyDown:N,onPointerDown:R,onMouseDown:R,onClickCapture:q,onMouseDownCapture(P){q(),U(P)},onPointerDownCapture(P){q(),U(P)},onMouseUpCapture:q,onTouchEndCapture:q,onTouchMoveCapture:q}),[N,q,U,R]);return or.useMemo(()=>r?{reference:B,floating:re,trigger:B}:{},[r,B,re])}var Pt=f(ve(),1);function Uf(e,t,r){let{reference:o,floating:n}=e,i=qt(t),s=ti(t),a=ei(s),u=Tt(t),l=i==="y",c=o.x+o.width/2-n.width/2,m=o.y+o.height/2-n.height/2,d=o[a]/2-n[a]/2,h;switch(u){case"top":h={x:c,y:o.y-n.height};break;case"bottom":h={x:c,y:o.y+o.height};break;case"right":h={x:o.x+o.width,y:m};break;case"left":h={x:o.x-n.width,y:m};break;default:h={x:o.x,y:o.y}}let g=_r(t);return g&&(h[s]+=d*(g==="end"?1:-1)*(r&&l?-1:1)),h}async function Wf(e,t){var r;t===void 0&&(t={});let{x:o,y:n,platform:i,rects:s,elements:a,strategy:u}=e,{boundary:l="clippingAncestors",rootBoundary:c="viewport",elementContext:m="floating",altBoundary:d=!1,padding:h=0}=Mr(t,e),g=Zi(h),w=a[d?m==="floating"?"reference":"floating":m],_=Vo(await i.getClippingRect({element:(r=await(i.isElement==null?void 0:i.isElement(w)))==null||r?w:w.contextElement||await(i.getDocumentElement==null?void 0:i.getDocumentElement(a.floating)),boundary:l,rootBoundary:c,strategy:u})),x=m==="floating"?{x:o,y:n,width:s.floating.width,height:s.floating.height}:s.reference,v=await(i.getOffsetParent==null?void 0:i.getOffsetParent(a.floating)),C=await(i.isElement==null?void 0:i.isElement(v))&&await(i.getScale==null?void 0:i.getScale(v))||{x:1,y:1},k=Vo(i.convertOffsetParentRelativeRectToViewportRelativeRect?await i.convertOffsetParentRelativeRectToViewportRelativeRect({elements:a,rect:x,offsetParent:v,strategy:u}):x);return{top:(_.top-k.top+g.top)/C.y,bottom:(k.bottom-_.bottom+g.bottom)/C.y,left:(_.left-k.left+g.left)/C.x,right:(k.right-_.right+g.right)/C.x}}var _0=50,Gf=async(e,t,r)=>{let{placement:o="bottom",strategy:n="absolute",middleware:i=[],platform:s}=r,a=s.detectOverflow?s:{...s,detectOverflow:Wf},u=await(s.isRTL==null?void 0:s.isRTL(t)),l=await s.getElementRects({reference:e,floating:t,strategy:n}),{x:c,y:m}=Uf(l,o,u),d=o,h=0,g={};for(let b=0;bY<=0)){var D,S;let Y=(((D=i.flip)==null?void 0:D.index)||0)+1,A=T[Y];if(A&&(!(m==="alignment"?x!==qt(A):!1)||J.every(U=>qt(U.placement)===x?U.overflows[0]>0:!0)))return{data:{index:Y,overflows:J},reset:{placement:A}};let N=(S=J.filter(q=>q.overflows[0]<=0).sort((q,U)=>q.overflows[1]-U.overflows[1])[0])==null?void 0:S.placement;if(!N)switch(h){case"bestFit":{var L;let q=(L=J.filter(U=>{if(E){let R=qt(U.placement);return R===x||R==="y"}return!0}).map(U=>[U.placement,U.overflows.filter(R=>R>0).reduce((R,B)=>R+B,0)]).sort((U,R)=>U[1]-R[1])[0])==null?void 0:L[0];q&&(N=q);break}case"initialPlacement":N=a;break}if(n!==N)return{reset:{placement:N}}}return{}}}};var qf=new Set(["left","top"]);async function C0(e,t){let{placement:r,platform:o,elements:n}=e,i=await(o.isRTL==null?void 0:o.isRTL(n.floating)),s=Tt(r),a=_r(r),u=qt(r)==="y",l=qf.has(s)?-1:1,c=i&&u?-1:1,m=Mr(t,e),{mainAxis:d,crossAxis:h,alignmentAxis:g}=typeof m=="number"?{mainAxis:m,crossAxis:0,alignmentAxis:null}:{mainAxis:m.mainAxis||0,crossAxis:m.crossAxis||0,alignmentAxis:m.alignmentAxis};return a&&typeof g=="number"&&(h=a==="end"?g*-1:g),u?{x:h*c,y:d*l}:{x:d*l,y:h*c}}var Zf=function(e){return e===void 0&&(e=0),{name:"offset",options:e,async fn(t){var r,o;let{x:n,y:i,placement:s,middlewareData:a}=t,u=await C0(t,e);return s===((r=a.offset)==null?void 0:r.placement)&&(o=a.arrow)!=null&&o.alignmentOffset?{}:{x:n+u.x,y:i+u.y,data:{...u,placement:s}}}}},Xf=function(e){return e===void 0&&(e={}),{name:"shift",options:e,async fn(t){let{x:r,y:o,placement:n,platform:i}=t,{mainAxis:s=!0,crossAxis:a=!1,limiter:u={fn:x=>{let{x:v,y:C}=x;return{x:v,y:C}}},...l}=Mr(e,t),c={x:r,y:o},m=await i.detectOverflow(t,l),d=qt(n),h=qi(d),g=c[h],b=c[d],w=(x,v)=>Yi(v+m[x==="y"?"top":"left"],v,v-m[x==="y"?"bottom":"right"]);s&&(g=w(h,g)),a&&(b=w(d,b));let _=u.fn({...t,[h]:g,[d]:b});return{..._,data:{x:_.x-r,y:_.y-o,enabled:{[h]:s,[d]:a}}}}}},Kf=function(e){return e===void 0&&(e={}),{options:e,fn(t){var r,o;let{x:n,y:i,placement:s,rects:a,middlewareData:u}=t,{offset:l=0,mainAxis:c=!0,crossAxis:m=!0}=Mr(e,t),d={x:n,y:i},h=qt(s),g=qi(h),b=d[g],w=d[h],_=Mr(l,t),x=typeof _=="number"?{mainAxis:_,crossAxis:0}:{mainAxis:(r=_.mainAxis)!=null?r:0,crossAxis:(o=_.crossAxis)!=null?o:0};if(c){let k=g==="y"?"height":"width",E=a.reference[g]-a.floating[k]+x.mainAxis,T=a.reference[g]+a.reference[k]-x.mainAxis;bT&&(b=T)}if(m){var v,C;let k=g==="y"?"width":"height",E=qf.has(Tt(s)),T=a.reference[h]-a.floating[k]+(E&&((v=u.offset)==null?void 0:v[h])||0)+(E?0:x.crossAxis),O=a.reference[h]+a.reference[k]+(E?0:((C=u.offset)==null?void 0:C[h])||0)-(E?x.crossAxis:0);wO&&(w=O)}return{[g]:b,[h]:w}}}},Jf=function(e){return e===void 0&&(e={}),{name:"size",options:e,async fn(t){let{placement:r,rects:o,platform:n,elements:i}=t,{apply:s=()=>{},...a}=Mr(e,t),u=await n.detectOverflow(t,a),l=Tt(r),c=_r(r),m=qt(r)==="y",{width:d,height:h}=o.floating,g,b;l==="top"||l==="bottom"?(g=l,b=c===(await(n.isRTL==null?void 0:n.isRTL(i.floating))?"start":"end")?"left":"right"):(b=l,g=c==="end"?"top":"bottom");let w=h-u.top-u.bottom,_=d-u.left-u.right,x=uo(h-u[g],w),v=uo(d-u[b],_),C=t.middlewareData.shift,k=!C,E=x,T=v;C!=null&&C.enabled.x&&(T=_),C!=null&&C.enabled.y&&(E=w),k&&!c&&(m?T=d-2*Sr(u.left,u.right):E=h-2*Sr(u.top,u.bottom)),await s({...t,availableWidth:T,availableHeight:E});let O=await n.getDimensions(i.floating);return d!==O.width||h!==O.height?{reset:{rects:!0}}:{}}}};function ed(e){let t=Lt(e),r=parseFloat(t.width)||0,o=parseFloat(t.height)||0,n=Ct(e),i=n?e.offsetWidth:r,s=n?e.offsetHeight:o,a=fo(r)!==i||fo(o)!==s;return a&&(r=i,o=s),{width:r,height:o,$:a}}function ol(e){return Re(e)?e:e.contextElement}function un(e){let t=ol(e);if(!Ct(t))return Nr(1);let r=t.getBoundingClientRect(),{width:o,height:n,$:i}=ed(t),s=(i?fo(r.width):r.width)/o,a=(i?fo(r.height):r.height)/n;return(!s||!Number.isFinite(s))&&(s=1),(!a||!Number.isFinite(a))&&(a=1),{x:s,y:a}}var R0=Nr(0);function td(e){let t=it(e);return!Bi()||!t.visualViewport?R0:{x:t.visualViewport.offsetLeft,y:t.visualViewport.offsetTop}}function E0(e,t,r){return t===void 0&&(t=!1),!!r&&t&&r===it(e)}function Bo(e,t,r,o){t===void 0&&(t=!1),r===void 0&&(r=!1);let n=e.getBoundingClientRect(),i=ol(e),s=Nr(1);t&&(o?Re(o)&&(s=un(o)):s=un(e));let a=E0(i,r,o)?td(i):Nr(0),u=(n.left+a.x)/s.x,l=(n.top+a.y)/s.y,c=n.width/s.x,m=n.height/s.y;if(i&&o){let d=it(i),h=Re(o)?it(o):o,g=d,b=ji(g);for(;b&&h!==g;){let w=un(b),_=b.getBoundingClientRect(),x=Lt(b),v=_.left+(b.clientLeft+parseFloat(x.paddingLeft))*w.x,C=_.top+(b.clientTop+parseFloat(x.paddingTop))*w.y;u*=w.x,l*=w.y,c*=w.x,m*=w.y,u+=v,l+=C,g=it(b),b=ji(g)}}return Vo({width:c,height:m,x:u,y:l})}function Ki(e,t){let r=Kn(e).scrollLeft;return t?t.left+r:Bo(Ir(e)).left+r}function rd(e,t){let r=e.getBoundingClientRect(),o=r.left+t.scrollLeft-Ki(e,r),n=r.top+t.scrollTop;return{x:o,y:n}}function T0(e){let{elements:t,rect:r,offsetParent:o,strategy:n}=e,i=n==="fixed",s=Ir(o),a=t?Xn(t.floating):!1;if(o===s||a&&i)return r;let u={scrollLeft:0,scrollTop:0},l=Nr(1),c=Nr(0),m=Ct(o);if((m||!i)&&((Lo(o)!=="body"||Zn(s))&&(u=Kn(o)),m)){let h=Bo(o);l=un(o),c.x=h.x+o.clientLeft,c.y=h.y+o.clientTop}let d=s&&!m&&!i?rd(s,u):Nr(0);return{width:r.width*l.x,height:r.height*l.y,x:r.x*l.x-u.scrollLeft*l.x+c.x+d.x,y:r.y*l.y-u.scrollTop*l.y+c.y+d.y}}function P0(e){return e.getClientRects?Array.from(e.getClientRects()):[]}function O0(e){let t=Kn(e),r=e.ownerDocument.body,o=Sr(e.scrollWidth,e.clientWidth,r.scrollWidth,r.clientWidth),n=Sr(e.scrollHeight,e.clientHeight,r.scrollHeight,r.clientHeight),i=-t.scrollLeft+Ki(e),s=-t.scrollTop;return Lt(r).direction==="rtl"&&(i+=Sr(e.clientWidth,r.clientWidth)-o),{width:o,height:n,x:i,y:s}}var k0=25;function F0(e,t,r){r===void 0&&(r="viewport");let o=r==="layoutViewport",n=it(e),i=Ir(e),s=n.visualViewport,a=i.clientWidth,u=i.clientHeight,l=0,c=0;if(s){let d=!Bi()||t==="fixed";o?d||(l=-s.offsetLeft,c=-s.offsetTop):(a=s.width,u=s.height,d&&(l=s.offsetLeft,c=s.offsetTop))}if(Ki(i)<=0){let d=i.ownerDocument,h=d.body,g=getComputedStyle(h),b=d.compatMode==="CSS1Compat"&&parseFloat(g.marginLeft)+parseFloat(g.marginRight)||0,w=Math.abs(i.clientWidth-h.clientWidth-b),_=getComputedStyle(i).scrollbarGutter==="stable both-edges"?w/2:w;_<=k0&&(a-=_)}return{width:a,height:u,x:l,y:c}}function A0(e,t){let r=Bo(e,!0,t==="fixed"),o=r.top+e.clientTop,n=r.left+e.clientLeft,i=un(e),s=e.clientWidth*i.x,a=e.clientHeight*i.y,u=n*i.x,l=o*i.y;return{width:s,height:a,x:u,y:l}}function Qf(e,t,r){let o;if(t==="viewport"||t==="layoutViewport")o=F0(e,r,t);else if(t==="document")o=O0(Ir(e));else if(Re(t))o=A0(t,r);else{let n=td(e);o={x:t.x-n.x,y:t.y-n.y,width:t.width,height:t.height}}return Vo(o)}function I0(e,t){let r=t.get(e);if(r)return r;let o=ao(e,[],!1).filter(a=>Re(a)&&Lo(a)!=="body"),n=null,i=Lt(e).position==="fixed",s=i?Ar(e):e;for(;Re(s)&&!Lr(s);){let a=Lt(s),u=Di(s),l=n?n.position:i?"fixed":"";!u&&(l==="fixed"||l==="absolute"&&a.position==="static")?o=o.filter(m=>m!==s):n=a,s=Ar(s)}return t.set(e,o),o}function L0(e){let{element:t,boundary:r,rootBoundary:o,strategy:n}=e,s=[...r==="clippingAncestors"?Xn(t)?[]:I0(t,this._c):[].concat(r),o],a=Qf(t,s[0],n),u=a.top,l=a.right,c=a.bottom,m=a.left;for(let d=1;d{a(!1,1e-7)},1e3)}T=!1}try{o=new IntersectionObserver(O,{...E,root:i.ownerDocument})}catch{o=new IntersectionObserver(O,E)}o.observe(e)}let u=it(e),l=()=>a(r);return u.addEventListener("resize",l),a(!0),()=>{u.removeEventListener("resize",l),s()}}function ri(e,t,r,o){o===void 0&&(o={});let{ancestorScroll:n=!0,ancestorResize:i=!0,elementResize:s=typeof ResizeObserver=="function",layoutShift:a=typeof IntersectionObserver=="function",animationFrame:u=!1}=o,l=ol(e),c=n||i?[...l?ao(l):[],...t?ao(t):[]]:[];c.forEach(_=>{n&&_.addEventListener("scroll",r),i&&_.addEventListener("resize",r)});let m=l&&a?B0(l,r,i):null,d=-1,h=null;s&&(h=new ResizeObserver(_=>{let[x]=_;x&&x.target===l&&h&&t&&(h.unobserve(t),cancelAnimationFrame(d),d=requestAnimationFrame(()=>{var v;(v=h)==null||v.observe(t)})),r()}),l&&!u&&h.observe(l),t&&h.observe(t));let g,b=u?Bo(e):null;u&&w();function w(){let _=Bo(e);b&&!nd(b,_)&&r(),b=_,g=requestAnimationFrame(w)}return r(),()=>{var _;c.forEach(x=>{n&&x.removeEventListener("scroll",r),i&&x.removeEventListener("resize",r)}),m?.(),(_=h)==null||_.disconnect(),h=null,u&&cancelAnimationFrame(g)}}var id=Zf;var sd=Xf,ad=Yf,ld=Jf;var cd=Kf,Ji=(e,t,r)=>{let o=new Map,n=r??{},i={...nl,...n.platform,_c:o};return Gf(e,t,{...n,platform:i})};var mt=f(ve(),1),fd=f(ve(),1),dd=f(lo(),1),z0=typeof document<"u",H0=function(){},Qi=z0?fd.useLayoutEffect:H0;function $i(e,t){if(e===t)return!0;if(typeof e!=typeof t)return!1;if(typeof e=="function"&&e.toString()===t.toString())return!0;let r,o,n;if(e&&t&&typeof e=="object"){if(Array.isArray(e)){if(r=e.length,r!==t.length)return!1;for(o=r;o--!==0;)if(!$i(e[o],t[o]))return!1;return!0}if(n=Object.keys(e),r=n.length,r!==Object.keys(t).length)return!1;for(o=r;o--!==0;)if(!{}.hasOwnProperty.call(t,n[o]))return!1;for(o=r;o--!==0;){let i=n[o];if(!(i==="_owner"&&e.$$typeof)&&!$i(e[i],t[i]))return!1}return!0}return e!==e&&t!==t}function pd(e){return typeof window>"u"?1:(e.ownerDocument.defaultView||window).devicePixelRatio||1}function ud(e,t){let r=pd(e);return Math.round(t*r)/r}function il(e){let t=mt.useRef(e);return Qi(()=>{t.current=e}),t}function md(e){e===void 0&&(e={});let{placement:t="bottom",strategy:r="absolute",middleware:o=[],platform:n,elements:{reference:i,floating:s}={},transform:a=!0,whileElementsMounted:u,open:l}=e,[c,m]=mt.useState({x:0,y:0,strategy:r,placement:t,middlewareData:{},isPositioned:!1}),[d,h]=mt.useState(o);$i(d,o)||h(o);let[g,b]=mt.useState(null),[w,_]=mt.useState(null),x=mt.useCallback(U=>{U!==E.current&&(E.current=U,b(U))},[]),v=mt.useCallback(U=>{U!==T.current&&(T.current=U,_(U))},[]),C=i||g,k=s||w,E=mt.useRef(null),T=mt.useRef(null),O=mt.useRef(c),I=u!=null,J=il(u),D=il(n),S=il(l),L=mt.useCallback(()=>{if(!E.current||!T.current)return;let U={placement:t,strategy:r,middleware:d};D.current&&(U.platform=D.current),Ji(E.current,T.current,U).then(R=>{let B={...R,isPositioned:S.current!==!1};Y.current&&!$i(O.current,B)&&(O.current=B,dd.flushSync(()=>{m(B)}))})},[d,t,r,D,S]);Qi(()=>{l===!1&&O.current.isPositioned&&(O.current.isPositioned=!1,m(U=>({...U,isPositioned:!1})))},[l]);let Y=mt.useRef(!1);Qi(()=>(Y.current=!0,()=>{Y.current=!1}),[]),Qi(()=>{if(C&&(E.current=C),k&&(T.current=k),C&&k){if(J.current)return J.current(C,k,L);L()}},[C,k,L,J,I]);let A=mt.useMemo(()=>({reference:E,floating:T,setReference:x,setFloating:v}),[x,v]),N=mt.useMemo(()=>({reference:C,floating:k}),[C,k]),q=mt.useMemo(()=>{let U={position:r,left:0,top:0};if(!N.floating)return U;let R=ud(N.floating,c.x),B=ud(N.floating,c.y);return a?{...U,transform:"translate("+R+"px, "+B+"px)",...pd(N.floating)>=1.5&&{willChange:"transform"}}:{position:r,left:R,top:B}},[r,a,N.floating,c.x,c.y]);return mt.useMemo(()=>({...c,update:L,refs:A,elements:N,floatingStyles:q}),[c,L,A,N,q])}var sl=(e,t)=>{let r=id(e);return{name:r.name,fn:r.fn,options:[e,t]}},al=(e,t)=>{let r=sd(e);return{name:r.name,fn:r.fn,options:[e,t]}},ll=(e,t)=>({fn:cd(e).fn,options:[e,t]}),cl=(e,t)=>{let r=ad(e);return{name:r.name,fn:r.fn,options:[e,t]}},ul=(e,t)=>{let r=ld(e);return{name:r.name,fn:r.fn,options:[e,t]}};var es=class{attachedStores=[];attachedStoreValue=null;storeListeners=new Set;constructor(t,r,o=!0){this.fallbackStore=t,this.componentName=r,this.throwOnMissingTrigger=o}get attachedStore(){return this.attachedStoreValue}get store(){return this.attachedStoreValue??this.fallbackStore}get serverStore(){return this.fallbackStore}subscribeStore(t){return this.storeListeners.add(t),()=>{this.storeListeners.delete(t)}}attachStore(t){return this.attachedStores.push(t),this.setActiveStore(t),()=>{let r=this.attachedStores.lastIndexOf(t);r!==-1&&this.attachedStores.splice(r,1),this.setActiveStore(this.attachedStores[this.attachedStores.length-1]??null)}}setActiveStore(t){this.attachedStoreValue!==t&&(this.attachedStoreValue=t,this.storeListeners.forEach(r=>{r()}))}openByTrigger(t){let r=this.attachedStore;if(r===null)return;let o;if(t){for(let n=this.attachedStores.length-1;n>=0&&!o;n-=1)o=this.attachedStores[n].context.triggerElements.getById(t);o??=this.fallbackStore.context.triggerElements.getById(t)}if(t&&!o&&this.throwOnMissingTrigger)throw new Error(lr(99,this.componentName,t,this.componentName));r.setOpen(!0,Ve(Oe.imperativeAction,void 0,o))}closePopup(){let t=this.attachedStore;t!==null&&t.setOpen(!1,Ve(Oe.imperativeAction))}};var zo=f(ve(),1),kd=f(lo(),1);var Pd=f(ve(),1);var Ed=f(ve(),1),hl=f(ts(),1),Td=f(xd(),1);var Sd=f(ve(),1);var dl=[],pl;function _d(){return pl}function Cd(e){dl.push(e)}function ml(e){let t=(r,o)=>{let n=_t(sw).current,i;try{pl=n;for(let s of dl)s.before(n);i=e(r,o);for(let s of dl)s.after(n);n.didInitialize=!0}finally{pl=void 0}return i};return t.displayName=e.displayName||e.name,t}function Rd(e){return Sd.forwardRef(ml(e))}function sw(){return{didInitialize:!1}}var aw=rn(19),lw=aw?uw:fw;function os(e,t,r,o,n){return lw(e,t,r,o,n)}function cw(e,t,r,o,n){let i=Ed.useCallback(()=>t(e.getSnapshot(),r,o,n),[e,t,r,o,n]);return(0,hl.useSyncExternalStore)(e.subscribe,i,i)}Cd({before(e){e.syncIndex=0,e.didInitialize||(e.syncTick=1,e.syncHooks=[],e.didChangeStore=!0,e.getSnapshot=()=>{let t=!1;for(let r=0;r0&&(e.didChangeStore&&(e.didChangeStore=!1,e.subscribe=t=>{let r=new Set;for(let n of e.syncHooks)r.add(n.store);let o=[];for(let n of r)o.push(n.subscribe(t));return()=>{for(let n of o)n()}}),(0,hl.useSyncExternalStore)(e.subscribe,e.getSnapshot,e.getSnapshot))}});function uw(e,t,r,o,n){let i=_d();if(!i)return cw(e,t,r,o,n);let s=i.syncIndex;i.syncIndex+=1;let a;return i.didInitialize?(a=i.syncHooks[s],(a.store!==e||a.selector!==t||!Object.is(a.a1,r)||!Object.is(a.a2,o)||!Object.is(a.a3,n))&&(a.store!==e&&(i.didChangeStore=!0),a.store=e,a.selector=t,a.a1=r,a.a2=o,a.a3=n,a.value=t(e.getSnapshot(),r,o,n))):(a={store:e,selector:t,a1:r,a2:o,a3:n,value:t(e.getSnapshot(),r,o,n)},i.syncHooks.push(a)),a.value}function fw(e,t,r,o,n){return(0,Td.useSyncExternalStoreWithSelector)(e.subscribe,e.getSnapshot,e.getSnapshot,i=>t(i,r,o,n))}var ns=class{constructor(t){this.state=t,this.listeners=new Set,this.updateTick=0}subscribe=t=>(this.listeners.add(t),()=>{this.listeners.delete(t)});getSnapshot=()=>this.state;setState(t){if(this.state===t)return;this.state=t,this.updateTick+=1;let r=this.updateTick;for(let o of this.listeners){if(r!==this.updateTick)return;o(t)}}update(t){for(let r in t)if(!Object.is(this.state[r],t[r])){this.setState({...this.state,...t});return}}set(t,r){Object.is(this.state[t],r)||this.setState({...this.state,[t]:r})}notifyAll(){let t={...this.state};this.setState(t)}use(t,r,o,n){return os(this,t,r,o,n)}};var jo=f(ve(),1);var mo=class extends ns{constructor(t,r={},o){super(t),this.context=r,this.selectors=o}useSyncedValue(t,r){jo.useDebugValue(t);let o=this;we(()=>{o.state[t]!==r&&o.set(t,r)},[o,t,r])}useSyncedValueWithCleanup(t,r){let o=this;we(()=>(o.state[t]!==r&&o.set(t,r),()=>{o.set(t,void 0)}),[o,t,r])}useSyncedValues(t){let r=this,o=Object.values(t);we(()=>{r.update(t)},[r,...o])}useControlledProp(t,r){jo.useDebugValue(t);let o=this,n=r!==void 0;we(()=>{n&&!Object.is(o.state[t],r)&&o.setState({...o.state,[t]:r})},[o,t,r,n])}select(t,r,o,n){let i=this.selectors[t];return i(this.state,r,o,n)}useState(t,r,o,n){return jo.useDebugValue(t),os(this,this.selectors[t],r,o,n)}useContextCallback(t,r){jo.useDebugValue(t);let o=Pe(r??tr);this.context[t]=o}useStateSetter(t){let r=jo.useRef(void 0);return r.current===void 0&&(r.current=o=>{this.set(t,o)}),r.current}observe(t,r){let o;typeof t=="function"?o=t:o=this.selectors[t];let n=o(this.state);return r(n,n,this),this.subscribe(i=>{let s=o(i);if(!Object.is(n,s)){let a=n;n=s,r(s,a,this)}})}};var dw={open:e=>e.open,transitionStatus:e=>e.transitionStatus,domReferenceElement:e=>e.domReferenceElement,referenceElement:e=>e.positionReference??e.referenceElement,floatingElement:e=>e.floatingElement,floatingId:e=>e.floatingId},ho=class extends mo{constructor(t){let{syncOnly:r,nested:o,onOpenChange:n,triggerElements:i,...s}=t;super({...s,positionReference:s.referenceElement,domReferenceElement:s.referenceElement},{onOpenChange:n,dataRef:{current:{}},events:zf(),nested:o,triggerElements:i},dw),this.syncOnly=r}syncOpenEvent=(t,r)=>{(!t||!this.state.open||r!=null&&Cf(r))&&(this.context.dataRef.current.openEvent=t?r:void 0)};dispatchOpenChange=(t,r)=>{this.syncOpenEvent(t,r.event);let o={open:t,reason:r.reason,nativeEvent:r.event,nested:this.context.nested,triggerElement:r.trigger};this.context.events.emit("openchange",o)};setOpen=(t,r)=>{if(this.syncOnly){this.context.onOpenChange?.(t,r);return}this.dispatchOpenChange(t,r),this.context.onOpenChange?.(t,r)}};function Od(e){let{popupStore:t,treatPopupAsFloatingElement:r=!1,floatingRootContext:o,floatingId:n,nested:i,onOpenChange:s}=e,a=t.useState("open"),u=t.useState("activeTriggerElement"),l=t.useState(r?"popupElement":"positionerElement"),c=t.context.triggerElements,m=s,d=Pd.useRef(null);o===void 0&&d.current===null&&(d.current=new ho({open:a,transitionStatus:void 0,referenceElement:u,floatingElement:l,triggerElements:c,onOpenChange:m,floatingId:n,syncOnly:!0,nested:i}));let h=o??d.current;return t.useSyncedValue("floatingId",n),we(()=>{let g={open:a,floatingId:n,referenceElement:u,floatingElement:l};Re(u)&&(g.domReferenceElement=u),h.state.positionReference===h.state.referenceElement&&(g.positionReference=u),h.update(g)},[a,n,u,l,h]),h.context.onOpenChange=m,h.context.nested=i,h}var Fd={tabIndex:-1,[Za]:""};function Ad(e,t=!1){let r=on(),o=Xi()!=null,n=_t(()=>e(r,o)).current;return Od({popupStore:n,treatPopupAsFloatingElement:t,floatingRootContext:n.state.floatingRootContext,floatingId:r,nested:o,onOpenChange:n.setOpen}),n}function Id({handle:e,store:t}){return we(()=>e.attachStore(t),[e,t]),null}function pw(e,t){let r=zo.useRef(null),o=zo.useRef(null);return zo.useCallback(n=>{if(e===void 0)return;let i=!1;if(r.current!==null){let s=r.current,a=o.current,u=t.context.triggerElements.getById(s);a&&u===a&&(t.context.triggerElements.delete(s),i=!0),r.current=null,o.current=null}if(n!==null&&(r.current=e,o.current=n,t.context.triggerElements.add(e,n),i=!0),i){let s=t.context.triggerElements.size;t.select("open")&&t.state.triggerCount!==s&&t.set("triggerCount",s)}},[t,e])}function mw(e,t,r,o=!1){t?e.preventUnmountingOnClose=!1:o&&(e.preventUnmountingOnClose=!0);let n=r?.id??null;(n||t)&&(e.activeTriggerId=n,e.activeTriggerElement=r??null)}function hw(e){let t=!1;return e.preventUnmountOnClose=()=>{t=!0},()=>t}function Ld(e,t,r,o={}){let n=r.reason,i=n===Oe.triggerHover,s=t&&n===Oe.triggerFocus,a=!t&&(n===Oe.triggerPress||n===Oe.escapeKey),u=hw(r);if(e.context.onOpenChange?.(t,r),r.isCanceled)return;o.onBeforeDispatch?.(),e.state.floatingRootContext.dispatchOpenChange(t,r);let l=()=>{let c={...o.extraState,open:t};s?c.instantType="focus":a?c.instantType="dismiss":i&&(c.instantType=void 0),mw(c,t,r.trigger,u()),e.update(c)};i?kd.flushSync(l):l()}function Nd(e,t,r,o){let n=r.useState("isMountedByTrigger",e),i=pw(e,r),s=Pe(u=>{let l=r.select("open"),c=r.select("activeTriggerId");if(c===e){r.update({activeTriggerElement:u,...l?o:null});return}c==null&&l&&r.update({activeTriggerId:e,activeTriggerElement:u,...o})}),a=zo.useCallback(u=>{i(u),u&&s(u)},[i,s]);return we(()=>{n&&r.update({activeTriggerElement:t.current,...o})},[n,r,t,...Object.values(o)]),{registerTrigger:a,isMountedByThisTrigger:n}}function Md(e,t={}){let{closeOnActiveTriggerUnmount:r=!1}=t,o=zo.useRef(null),n=e.useState("open"),i=e.useState("triggerCount"),s=e.useState("activeTriggerId"),a=e.useState("activeTriggerElement");we(()=>{if(!n){o.current=null,e.state.triggerCount!==0&&e.set("triggerCount",0);return}let u=e.context.triggerElements.size,l={};e.state.triggerCount!==u&&(l.triggerCount=u);let c=e.select("activeTriggerId"),m=null;if(c){let d=e.context.triggerElements.getById(c);if(d)o.current=c,d!==e.state.activeTriggerElement&&(l.activeTriggerElement=d);else{for(let[h,g]of e.context.triggerElements.entries())if(g===e.state.activeTriggerElement){l.activeTriggerId=h,l.activeTriggerElement=g,o.current=h;break}l.activeTriggerId===void 0&&(o.current===c?m=c:o.current=null)}}else o.current=null;if(!m&&!c&&u===1){let d=e.context.triggerElements.entries().next();if(!d.done){let[h,g]=d.value;l.activeTriggerId=h,l.activeTriggerElement=g,o.current=h}}(l.triggerCount!==void 0||l.activeTriggerId!==void 0||l.activeTriggerElement!==void 0)&&e.update(l),m&&r&&queueMicrotask(()=>{if(e.select("open")&&e.select("activeTriggerId")===m&&!e.context.triggerElements.getById(m)){let d=Ve(Oe.none);e.setOpen(!1,d),d.isCanceled||e.update({activeTriggerId:null,activeTriggerElement:null})}})},[n,e,i,s,a,r])}function Vd(e,t,r){let{mounted:o,setMounted:n,transitionStatus:i}=uf(e),s=t.useState("preventUnmountingOnClose"),a=e?!1:s;t.useSyncedValues({mounted:o,transitionStatus:i,preventUnmountingOnClose:a});let u=Pe(()=>{n(!1),t.update({activeTriggerId:null,activeTriggerElement:null,mounted:!1,preventUnmountingOnClose:!1}),r?.(),t.context.onOpenChangeComplete?.(!1)});return zi({enabled:o&&!e&&!a,open:e,ref:t.context.popupRef,onComplete(){e||u()}}),{forceUnmount:u,transitionStatus:i}}function Dd(e,t){e.useSyncedValues(t),we(()=>()=>{e.update({activeTriggerProps:nt,inactiveTriggerProps:nt,popupProps:nt})},[e])}var Ho=class{constructor(){this.idMap=new Map}add(t,r){this.idMap.set(t,r)}delete(t){this.idMap.delete(t)}hasElement(t){for(let r of this.idMap.values())if(r===t)return!0;return!1}hasMatchingElement(t){for(let r of this.idMap.values())if(t(r))return!0;return!1}getById(t){return this.idMap.get(t)}entries(){return this.idMap.entries()}elements(){return this.idMap.values()}get size(){return this.idMap.size}};function Bd(){return new ho({open:!1,transitionStatus:void 0,floatingElement:null,referenceElement:null,triggerElements:new Ho,floatingId:void 0,syncOnly:!1,nested:!1,onOpenChange:void 0})}function zd(){return{open:!1,openProp:void 0,mounted:!1,transitionStatus:void 0,floatingRootContext:Bd(),floatingId:void 0,triggerCount:0,preventUnmountingOnClose:!1,payload:void 0,activeTriggerId:null,activeTriggerElement:null,triggerIdProp:void 0,popupElement:null,positionerElement:null,activeTriggerProps:nt,inactiveTriggerProps:nt,popupProps:nt}}function Hd(e,t,r=!1){return new ho({open:!1,transitionStatus:void 0,floatingElement:null,referenceElement:null,triggerElements:e,floatingId:t,syncOnly:!0,nested:r,onOpenChange:void 0})}var oi=e=>e.triggerIdProp??e.activeTriggerId,gl=e=>e.openProp??e.open,jd=e=>(e.popupElement?.id??e.floatingId)||void 0;function Ud(e,t){return t!==void 0&&gl(e)&&oi(e)===t}function gw(e,t){return Ud(e,t)?!0:t!==void 0&&gl(e)&&oi(e)==null&&e.triggerCount===1}var Wd={open:gl,mounted:e=>e.mounted,transitionStatus:e=>e.transitionStatus,floatingRootContext:e=>e.floatingRootContext,triggerCount:e=>e.triggerCount,preventUnmountingOnClose:e=>e.preventUnmountingOnClose,payload:e=>e.payload,activeTriggerId:oi,activeTriggerElement:e=>e.mounted?e.activeTriggerElement:null,popupId:jd,isTriggerActive:(e,t)=>t!==void 0&&oi(e)===t,isOpenedByTrigger:(e,t)=>Ud(e,t),isMountedByTrigger:(e,t)=>t!==void 0&&oi(e)===t&&e.mounted,triggerProps:(e,t)=>t?e.activeTriggerProps:e.inactiveTriggerProps,triggerPopupId:(e,t)=>gw(e,t)?jd(e):void 0,popupProps:e=>e.popupProps,popupElement:e=>e.popupElement,positionerElement:e=>e.positionerElement};var yl=f(ve(),1),Gd=f(ts(),1);function Yd(e){let t=yl.useCallback(o=>e===void 0?tr:e.subscribeStore(o),[e]),r=yl.useCallback(()=>e===void 0?void 0:e.store,[e]);return(0,Gd.useSyncExternalStore)(t,r,()=>e?.serverStore)}function qd(e){return yw(e,e.rootContext)}function yw(e,t){let{nodeId:r,externalTree:o}=e,n=t.useState("referenceElement"),i=t.useState("floatingElement"),s=t.useState("domReferenceElement"),a=t.useState("open"),u=t.useState("floatingId"),[l,c]=Pt.useState(null),[m,d]=Pt.useState(void 0),[h,g]=Pt.useState(void 0),b=Pt.useRef(null),w=po(o),_=Pt.useMemo(()=>({reference:n,floating:i,domReference:s}),[n,i,s]),x=md({...e,elements:{..._,...l&&{reference:l}}}),v=Re(m)?m:null,C=h===void 0?t.state.floatingElement:h;t.useSyncedValue("referenceElement",m??null),t.useSyncedValue("domReferenceElement",m===void 0?s:v),t.useSyncedValue("floatingElement",C);let k=Pt.useCallback(D=>{let S=Re(D)?{getBoundingClientRect:()=>D.getBoundingClientRect(),getClientRects:()=>D.getClientRects(),contextElement:D}:D;c(S),x.refs.setReference(S)},[x.refs]),E=Pt.useCallback(D=>{(Re(D)||D===null)&&(b.current=D,d(D)),(Re(x.refs.reference.current)||x.refs.reference.current===null||D!==null&&!Re(D))&&x.refs.setReference(D)},[x.refs,d]),T=Pt.useCallback(D=>{g(D),x.refs.setFloating(D)},[x.refs]),O=Pt.useMemo(()=>({...x.refs,setReference:E,setFloating:T,setPositionReference:k,domReference:b}),[x.refs,E,T,k]),I=Pt.useMemo(()=>({...x.elements,domReference:s}),[x.elements,s]),J=Pt.useMemo(()=>({...x,dataRef:t.context.dataRef,open:a,onOpenChange:t.setOpen,events:t.context.events,floatingId:u,refs:O,elements:I,nodeId:r,rootStore:t}),[x,O,I,r,t,a,u]);return we(()=>{s&&(b.current=s)},[s]),we(()=>{t.context.dataRef.current.floatingContext=J;let D=w?.nodesRef.current.find(S=>S.id===r);D&&(D.context=J)}),Pt.useMemo(()=>({...x,context:J,refs:O,elements:I,rootStore:t}),[x,O,I,J,t])}var Vr=f(ve(),1);var vl=Zr.os.mac&&Zr.engine.webkit;function bl(e,t={}){let{enabled:r=!0,delay:o}=t,n="rootStore"in e?e.rootStore:e,{events:i,dataRef:s}=n.context,a=Vr.useRef(!1),u=Vr.useRef(null),l=Vr.useRef(!0),c=wr();Vr.useEffect(()=>{let d=n.select("domReferenceElement");if(!r)return;let h=it(d);function g(){let _=n.select("domReferenceElement");!n.select("open")&&Ct(_)&&_===Hi(Rt(_))&&(a.current=!0)}function b(){l.current=!0}function w(){l.current=!1}return xr(ze(h,"blur",g),vl&&ze(h,"keydown",b,!0),vl&&ze(h,"pointerdown",w,!0))},[n,r]),Vr.useEffect(()=>{if(!r)return;function d(h){if(h.reason===Oe.triggerPress||h.reason===Oe.escapeKey){let g=n.select("domReferenceElement");Re(g)&&(u.current=g,a.current=!0)}}return i.on("openchange",d),()=>{i.off("openchange",d)}},[i,r,n]);let m=Vr.useMemo(()=>{function d(){a.current=!1,u.current=null}return{onMouseLeave(){d()},onFocus(h){let g=h.currentTarget;if(a.current){if(u.current===g)return;d()}let b=Nt(h.nativeEvent);if(Re(b)){if(vl&&!h.relatedTarget){if(!l.current&&!Ef(b))return}else if(!Tf(b))return}let w=co(h.relatedTarget,n.context.triggerElements),{nativeEvent:_,currentTarget:x}=h,v=typeof o=="function"?o():o;if(n.select("open")&&w||v===0||v===void 0){n.setOpen(!0,Ve(Oe.triggerFocus,_,x));return}c.start(v,()=>{a.current||n.setOpen(!0,Ve(Oe.triggerFocus,_,x))})},onBlur(h){d();let g=h.relatedTarget,b=h.nativeEvent,w=Re(g)&&g.hasAttribute(cn("focus-guard"))&&g.getAttribute("data-type")==="outside";c.start(0,()=>{let _=n.select("domReferenceElement"),x=Hi(Rt(_));!g&&x===_||Ge(s.current.floatingContext?.refs.floating.current,x)||Ge(_,x)||w||co(g??x,n.context.triggerElements)||n.setOpen(!1,Ve(Oe.triggerFocus,b))})}}},[s,o,n,c]);return Vr.useMemo(()=>r?{reference:m,trigger:m}:{},[r,m])}var xl=f(ve(),1);var wl=class e{constructor(){this.pointerType=void 0,this.interactedInside=!1,this.handler=void 0,this.blockMouseMove=!0,this.performedPointerEventsMutation=!1,this.pointerEventsScopeElement=null,this.pointerEventsReferenceElement=null,this.pointerEventsFloatingElement=null,this.restTimeoutPending=!1,this.openChangeTimeout=new rr,this.restTimeout=new rr,this.handleCloseOptions=void 0}static create(){return new e}dispose=()=>{this.openChangeTimeout.clear(),this.restTimeout.clear()};disposeEffect=()=>this.dispose},is=new WeakMap;function dn(e){if(!e.performedPointerEventsMutation)return;let t=e.pointerEventsScopeElement;t&&is.get(t)===e&&(e.pointerEventsScopeElement?.style.removeProperty("pointer-events"),e.pointerEventsReferenceElement?.style.removeProperty("pointer-events"),e.pointerEventsFloatingElement?.style.removeProperty("pointer-events"),is.delete(t)),e.performedPointerEventsMutation=!1,e.pointerEventsScopeElement=null,e.pointerEventsReferenceElement=null,e.pointerEventsFloatingElement=null}function ss(e,t){let{scopeElement:r,referenceElement:o,floatingElement:n}=t,i=is.get(r);i&&i!==e&&dn(i),dn(e),e.performedPointerEventsMutation=!0,e.pointerEventsScopeElement=r,e.pointerEventsReferenceElement=o,e.pointerEventsFloatingElement=n,is.set(r,e),r.style.pointerEvents="none",o.style.pointerEvents="auto",n.style.pointerEvents="auto"}function pn(e){let t=e.context.dataRef.current,r=_t(()=>t.hoverInteractionState??wl.create()).current;return t.hoverInteractionState||(t.hoverInteractionState=r),nn(t.hoverInteractionState.disposeEffect),t.hoverInteractionState}function Sl(e,t={}){let{enabled:r=!0,closeDelay:o=0,nodeId:n}=t,i="rootStore"in e?e.rootStore:e,s=i.useState("open"),a=i.useState("floatingElement"),u=i.useState("domReferenceElement"),{dataRef:l}=i.context,c=po(),m=Xi(),d=pn(i),h=wr(),g=Pe(()=>Wi(l.current.openEvent?.type,d.interactedInside)),b=Pe(()=>Pf(l.current.openEvent?.type)),w=Pe(()=>{dn(d)});we(()=>{s||(d.pointerType=void 0,d.restTimeoutPending=!1,d.interactedInside=!1,w())},[s,d,w]),xl.useEffect(()=>w,[w]),we(()=>{if(r&&s&&d.handleCloseOptions?.blockPointerEvents&&b()&&Re(u)&&a){let _=u,x=a,v=Rt(a),C=c?.nodesRef.current.find(O=>O.id===m)?.context?.elements.floating;C&&(C.style.pointerEvents="");let k=d.pointerEventsScopeElement!==x?d.pointerEventsScopeElement:null,E=C!==x?C:null,T=d.handleCloseOptions?.getScope?.()??k??E??_.closest("[data-rootownerid]")??v.body;return ss(d,{scopeElement:T,referenceElement:_,floatingElement:x}),()=>{w()}}},[r,s,u,a,d,b,c,m,w]),xl.useEffect(()=>{if(!r)return;function _(){return!!(c&&m&&Kr(c.nodesRef.current,m).length>0)}function x(O){let I=cr(o,"close",d.pointerType),J=()=>{i.setOpen(!1,Ve(Oe.triggerHover,O)),c?.events.emit("floating.closed",O)};I?d.openChangeTimeout.start(I,J):(d.openChangeTimeout.clear(),J())}function v(O){let I=Nt(O);if(!Ka(I)){d.interactedInside=!1;return}d.interactedInside=I?.closest("[aria-haspopup]")!=null}function C(){d.openChangeTimeout.clear(),h.clear(),c?.events.off("floating.closed",E),w()}function k(O){if(_()&&c){c.events.on("floating.closed",E);return}if(co(O.relatedTarget,i.context.triggerElements))return;let I=l.current.floatingContext?.nodeId??n,J=O.relatedTarget;if(!(c&&I&&Re(J)&&Kr(c.nodesRef.current,I,!1).some(S=>Ge(S.context?.elements.floating,J)))){if(d.handler){d.handler(O);return}w(),b()&&!g()&&x(O)}}function E(O){!c||!m||_()||h.start(0,()=>{c.events.off("floating.closed",E),i.setOpen(!1,Ve(Oe.triggerHover,O)),c.events.emit("floating.closed",O)})}let T=a;return xr(T&&ze(T,"mouseenter",C),T&&ze(T,"mouseleave",k),T&&ze(T,"pointerdown",v,!0),()=>{c?.events.off("floating.closed",E)})},[r,a,i,l,o,n,b,g,w,d,c,m,h])}var go=f(ve(),1),Zd=f(lo(),1);var vw={current:null};function _l(e,t={}){let{enabled:r=!0,delay:o=0,handleClose:n=null,mouseOnly:i=!1,restMs:s=0,move:a=!0,triggerElementRef:u=vw,externalTree:l,isActiveTrigger:c=!0,getHandleCloseContext:m,isClosing:d,shouldOpen:h,guardStaleOpen:g=!1}=t,b="rootStore"in e?e.rootStore:e,{dataRef:w,events:_}=b.context,x=po(l),v=pn(b),C=go.useRef(!1),k=Yt(n),E=Yt(o),T=Yt(s),O=Yt(r),I=Yt(h),J=Yt(d),D=Pe(()=>Wi(w.current.openEvent?.type,v.interactedInside)),S=Pe(()=>I.current?.()!==!1),L=Pe((N,q,U)=>{let R=b.context.triggerElements;if(R.hasElement(q))return!N||!Ge(N,q);if(!Re(U))return!1;let B=U;return R.hasMatchingElement(re=>Ge(re,B))&&(!N||!Ge(N,B))}),Y=Pe(()=>{if(!v.handler)return;Rt(b.select("domReferenceElement")).removeEventListener("mousemove",v.handler),v.handler=void 0}),A=Pe(()=>{dn(v)});return c&&(v.handleCloseOptions=k.current?.__options),go.useEffect(()=>Y,[Y]),go.useEffect(()=>{if(!r)return;function N(q){q.open?C.current=!1:(C.current=q.reason===Oe.triggerHover,Y(),v.openChangeTimeout.clear(),v.restTimeout.clear(),v.blockMouseMove=!0,v.restTimeoutPending=!1)}return _.on("openchange",N),()=>{_.off("openchange",N)}},[r,_,v,Y]),go.useEffect(()=>{if(!r)return;function N(P,W=!0){let ne=cr(E.current,"close",v.pointerType);ne?v.openChangeTimeout.start(ne,()=>{b.setOpen(!1,Ve(Oe.triggerHover,P)),x?.events.emit("floating.closed",P)}):W&&(v.openChangeTimeout.clear(),b.setOpen(!1,Ve(Oe.triggerHover,P)),x?.events.emit("floating.closed",P))}let q=u.current??(c?b.select("domReferenceElement"):null);if(!Re(q))return;function U(P){if(v.openChangeTimeout.clear(),v.blockMouseMove=!1,i&&!Xr(v.pointerType))return;let W=Ja(T.current),ne=cr(E.current,"open",v.pointerType),xe=Nt(P),se=P.currentTarget??null,be=b.select("domReferenceElement"),ye=se;if(Re(xe)&&!b.context.triggerElements.hasElement(xe)){for(let H of b.context.triggerElements.elements())if(Ge(H,xe)){ye=H;break}}Re(se)&&Re(be)&&!b.context.triggerElements.hasElement(se)&&Ge(se,be)&&(ye=be);let $=ye==null?!1:L(be,ye,xe),Ce=b.select("open"),Fe=J.current?.()??b.select("transitionStatus")==="ending",xt=!Ce&&Fe&&C.current,Le=!$&&Re(ye)&&Re(be)&&Ge(be,ye)&&xt,X=W>0&&!ne,M=$&&(Ce||xt)||Le,K=!Ce||$;if(M){S()&&b.setOpen(!0,Ve(Oe.triggerHover,P,ye));return}X||(ne?v.openChangeTimeout.start(ne,()=>{K&&S()&&b.setOpen(!0,Ve(Oe.triggerHover,P,ye))}):K&&S()&&b.setOpen(!0,Ve(Oe.triggerHover,P,ye)))}function R(P){if(D()){A();return}Y();let W=b.select("domReferenceElement"),ne=Rt(W);v.restTimeout.clear(),v.restTimeoutPending=!1;let xe=w.current.floatingContext??m?.();if(co(P.relatedTarget,b.context.triggerElements))return;if(k.current&&xe){b.select("open")||v.openChangeTimeout.clear();let be=u.current;v.handler=k.current({...xe,tree:x,x:P.clientX,y:P.clientY,onClose(){A(),Y(),O.current&&!D()&&be===b.select("domReferenceElement")&&N(P,!0)}}),ne.addEventListener("mousemove",v.handler),v.handler(P);return}(v.pointerType!=="touch"||!Ge(b.select("floatingElement"),P.relatedTarget))&&N(P)}function B(P){Ge(q,P.relatedTarget)||(v.openChangeTimeout.clear(),v.restTimeout.clear(),v.restTimeoutPending=!1)}let re=g?ze(q,"mouseout",B):void 0;return a?xr(ze(q,"mousemove",U,{once:!0}),ze(q,"mouseenter",U),ze(q,"mouseleave",R),re):xr(ze(q,"mouseenter",U),ze(q,"mouseleave",R),re)},[Y,A,w,E,b,r,k,v,c,L,D,i,a,T,u,x,O,m,J,S,g]),go.useMemo(()=>{if(!r)return;function N(q){v.pointerType=q.pointerType}return{onPointerDown:N,onPointerEnter:N,onMouseMove(q){let{nativeEvent:U}=q,R=q.currentTarget,B=b.select("domReferenceElement"),re=b.select("open"),P=L(B,R,q.target);if(i&&!Xr(v.pointerType))return;if(re&&P&&v.handleCloseOptions?.blockPointerEvents){let xe=b.select("floatingElement");if(xe){let se=v.handleCloseOptions?.getScope?.()??R.ownerDocument.body;ss(v,{scopeElement:se,referenceElement:R,floatingElement:xe})}}let W=Ja(T.current);if(re&&!P||W===0||!P&&v.restTimeoutPending&&q.movementX**2+q.movementY**2<2)return;v.restTimeout.clear();function ne(){if(v.restTimeoutPending=!1,D())return;let xe=b.select("open");!v.blockMouseMove&&(!xe||P)&&S()&&b.setOpen(!0,Ve(Oe.triggerHover,U,R))}v.pointerType==="touch"?Zd.flushSync(()=>{ne()}):P&&re?ne():(v.restTimeoutPending=!0,v.restTimeout.start(W,ne))}}},[r,v,D,L,i,b,T,S])}var Xd=.1,bw=Xd*Xd,Xe=.5;function as(e,t,r,o,n,i){return o>=t!=i>=t&&e<=(n-r)*(t-o)/(i-o)+r}function ls(e,t,r,o,n,i,s,a,u,l){let c=!1;return as(e,t,r,o,n,i)&&(c=!c),as(e,t,n,i,s,a)&&(c=!c),as(e,t,s,a,u,l)&&(c=!c),as(e,t,u,l,r,o)&&(c=!c),c}function ww(e,t,r){return e>=r.x&&e<=r.x+r.width&&t>=r.y&&t<=r.y+r.height}function cs(e,t,r,o,n,i){let s=Math.min(r,n),a=Math.max(r,n),u=Math.min(o,i),l=Math.max(o,i);return e>=s&&e<=a&&t>=u&&t<=l}function Cl(e={}){let{blockPointerEvents:t=!1}=e,r=new rr,o=({x:n,y:i,placement:s,elements:a,onClose:u,nodeId:l,tree:c})=>{let m=s?.split("-")[0],d=!1,h=null,g=null,b=typeof performance<"u"?performance.now():0;function w(x,v){let C=performance.now(),k=C-b;if(h===null||g===null||k===0)return h=x,g=v,b=C,!1;let E=x-h,T=v-g,O=E*E+T*T,I=k*k*bw;return h=x,g=v,b=C,O0)}function L(){S()||_()}if(S())return;let Y=C.getBoundingClientRect(),A=k.getBoundingClientRect(),N=n>A.right-A.width/2,q=i>A.bottom-A.height/2,U=A.width>Y.width,R=A.height>Y.height,B=(U?Y:A).left,re=(U?Y:A).right,P=(R?Y:A).top,W=(R?Y:A).bottom;if(m==="top"&&i>=Y.bottom-1||m==="bottom"&&i<=Y.top+1||m==="left"&&n>=Y.right-1||m==="right"&&n<=Y.left+1){L();return}let ne=!1;switch(m){case"top":ne=cs(E,T,B,Y.top+1,re,A.bottom-1);break;case"bottom":ne=cs(E,T,B,A.top+1,re,Y.bottom-1);break;case"left":ne=cs(E,T,A.right-1,W,Y.left+1,P);break;case"right":ne=cs(E,T,Y.right-1,W,A.left+1,P);break;default:}if(ne)return;if(d&&!ww(E,T,Y)){L();return}if(!I&&w(E,T)){L();return}let xe=!1;switch(m){case"top":{let se=U?Xe/2:Xe*4,be=U||N?n+se:n-se,ye=U?n-se:N?n+se:n-se,$=i+Xe+1,Ce=N||U?A.bottom-Xe:A.top,Fe=N?U?A.bottom-Xe:A.top:A.bottom-Xe;xe=ls(E,T,be,$,ye,$,A.left,Ce,A.right,Fe);break}case"bottom":{let se=U?Xe/2:Xe*4,be=U||N?n+se:n-se,ye=U?n-se:N?n+se:n-se,$=i-Xe,Ce=N||U?A.top+Xe:A.bottom,Fe=N?U?A.top+Xe:A.bottom:A.top+Xe;xe=ls(E,T,be,$,ye,$,A.left,Ce,A.right,Fe);break}case"left":{let se=R?Xe/2:Xe*4,be=R||q?i+se:i-se,ye=R?i-se:q?i+se:i-se,$=n+Xe+1,Ce=q||R?A.right-Xe:A.left,Fe=q?R?A.right-Xe:A.left:A.right-Xe;xe=ls(E,T,Ce,A.top,Fe,A.bottom,$,be,$,ye);break}case"right":{let se=R?Xe/2:Xe*4,be=R||q?i+se:i-se,ye=R?i-se:q?i+se:i-se,$=n-Xe,Ce=q||R?A.left+Xe:A.right,Fe=q?R?A.left+Xe:A.right:A.left+Xe;xe=ls(E,T,$,be,$,ye,Ce,A.top,Fe,A.bottom);break}default:}xe?d||r.start(40,L):L()}};return o.__options={...e,blockPointerEvents:t},o}var us=class extends mo{setState(t){}update(t){}set(t,r){}notifyAll(){}};var V6=(function(e){return e.open="data-open",e.closed="data-closed",e[e.startingStyle=Ba.startingStyle]="startingStyle",e[e.endingStyle=Ba.endingStyle]="endingStyle",e.anchorHidden="data-anchor-hidden",e.side="data-side",e.align="data-align",e})({});var xw={"data-popup-open":""};var Sw={"data-open":""},_w={"data-closed":""},Cw={"data-anchor-hidden":""},Kd={open(e){return e?xw:null}};var ni={open(e){return e?Sw:_w},anchorHidden(e){return e?Cw:null}},Jd={...ni,...ff};function Qd(e){return rn(19)?e:e?"true":void 0}var fs=f(ve(),1),Rl=fs.createContext(void 0);function mn(){return fs.useContext(Rl)?.direction??"ltr"}var nr=f(ve(),1);var Rw=e=>({name:"arrow",options:e,async fn(t){let{x:r,y:o,placement:n,rects:i,platform:s,elements:a,middlewareData:u}=t,{element:l,padding:c=0,offsetParent:m="real"}=Mr(e,t)||{};if(l==null)return{};let d=Zi(c),h={x:r,y:o},g=ti(n),b=ei(g),w=await s.getDimensions(l),_=g==="y",x=_?"top":"left",v=_?"bottom":"right",C=_?"clientHeight":"clientWidth",k=i.reference[b]+i.reference[g]-h[g]-i.floating[b],E=h[g]-i.reference[g],T=m==="real"?await s.getOffsetParent?.(l):a.floating,O=a.floating[C]||i.floating[b];(!O||!await s.isElement?.(T))&&(O=a.floating[C]||i.floating[b]);let I=k/2-E/2,J=O/2-w[b]/2-1,D=Math.min(d[x],J),S=Math.min(d[v],J),L=D,Y=O-w[b]-S,A=O/2-w[b]/2+I,N=Yi(L,A,Y),q=!u.arrow&&_r(n)!=null&&A!==N&&i.reference[b]/2-(A({...Rw(e),options:[e,t]});var ep={name:"hide",async fn(e){let{width:t,height:r,x:o,y:n}=e.rects.reference,i=t===0&&r===0&&o===0&&n===0,s=await e.platform.detectOverflow(e,{elementContext:"reference"});return{data:{referenceHidden:s.top-r>=0||s.right-t>=0||s.bottom-r>=0||s.left-t>=0||i}}}};var hn={sideX:"left",sideY:"top"};var tp="--available-width",rp="--available-height";function ip(e,t,r){let o=e==="inline-start"||e==="inline-end";return{top:"top",right:o?r?"inline-start":"inline-end":"right",bottom:"bottom",left:o?r?"inline-end":"inline-start":"left"}[t]}function op(e,t,r){let{rects:o,placement:n}=e;return{side:ip(t,Tt(n),r),align:_r(n)||"center",anchor:{width:o.reference.width,height:o.reference.height},positioner:{width:o.floating.width,height:o.floating.height}}}function sp(e){return Ew(e,qd)}function Ew(e,t){let{anchor:r,positionMethod:o="absolute",side:n="bottom",sideOffset:i=0,align:s="center",alignOffset:a=0,collisionBoundary:u,collisionPadding:l=5,sticky:c=!1,arrowPadding:m=5,disableAnchorTracking:d=!1,inline:h,keepMounted:g=!1,floatingRootContext:b,mounted:w,collisionAvoidance:_,shift:x,nodeId:v,adaptiveOrigin:C,lazyFlip:k=!1,externalTree:E}=e,[T,O]=nr.useState(null);!w&&T!==null&&O(null);let I=_.side||"flip",J=_.align||"flip",D=_.fallbackAxisSide||"end",S=x?.crossAxis??!1,L=x?.rootBoundary,Y=typeof r=="function"?r:void 0,A=Pe(Y),N=Y?A:r,q=Yt(r),U=Yt(w),B=mn()==="rtl",re=T||{top:"top",right:"right",bottom:"bottom",left:"left","inline-end":B?"left":"right","inline-start":B?"right":"left"}[n],P=s==="center"?re:`${re}-${s}`,W=l;typeof W=="number"?W={top:W,right:W,bottom:W,left:W}:W&&(W={top:W.top||0,right:W.right||0,bottom:W.bottom||0,left:W.left||0});let ne=1,xe=n==="bottom"?ne:0,se=n==="top"?ne:0,be=n==="right"?ne:0,ye=n==="left"?ne:0,$={boundary:u==="clipping-ancestors"?"clippingAncestors":u,padding:W},Ce=nr.useRef(null),Fe=Yt(i),xt=Yt(a),Le=typeof i!="function"?i:0,X=typeof a!="function"?a:0,M=[];h&&M.push(h),M.push(sl(G=>{let y=op(G,n,B),oe=typeof Fe.current=="function"?Fe.current(y):Fe.current,Ae=typeof xt.current=="function"?xt.current(y):xt.current;return{mainAxis:oe,crossAxis:Ae,alignmentAxis:Ae}},[Le,X,B,n]));let K=J==="none"&&I!=="shift",H=!K&&(c||S||I==="shift"),Q=I==="none"?null:cl({...$,padding:{top:W.top+ne+xe,right:W.right+ne+ye,bottom:W.bottom+ne+se,left:W.left+ne+be},mainAxis:!S&&I==="flip",crossAxis:J==="flip"?"alignment":!1,fallbackAxisSideDirection:D}),pe=K?null:al({...$,rootBoundary:L,mainAxis:J!=="none",crossAxis:H,limiter:c||S?void 0:ll(G=>{if(!Ce.current)return{};let{width:y,height:oe}=Ce.current.getBoundingClientRect(),Ae=qt(Tt(G.placement)),ee=Ae==="y"?y:oe,Qe=Ae==="y"?W.left+W.right:W.top+W.bottom;return{offset:ee/2+Qe/2}})},[$,c,S,L,W,J]);I==="shift"||J==="shift"||s==="center"?M.push(pe,Q):M.push(Q,pe),M.push(ul({...$,apply({elements:{floating:G},availableWidth:y,availableHeight:oe,rects:Ae}){if(!U.current)return;let ee=G.style;ee.setProperty(tp,`${y}px`),ee.setProperty(rp,`${oe}px`);let Qe=it(G).devicePixelRatio||1,{x:ie,y:Je,width:j,height:z}=Ae.reference,yr=(Math.round((ie+j)*Qe)-Math.round(ie*Qe))/Qe,je=(Math.round((Je+z)*Qe)-Math.round(Je*Qe))/Qe;ee.setProperty("--anchor-width",`${yr}px`),ee.setProperty("--anchor-height",`${je}px`)}}),$d(G=>({element:Ce.current||Rt(G.elements.floating).createElement("div"),padding:m,offsetParent:"floating"}),[m]),{name:"transformOrigin",fn(G){let{elements:y,middlewareData:oe,placement:Ae,rects:ee,y:Qe}=G,ie=Tt(Ae),Je=qt(ie),j=Ce.current,z=oe.arrow?.x||0,yr=oe.arrow?.y||0,je=j?.clientWidth||0,ce=j?.clientHeight||0,vr=z+je/2,kr=yr+ce/2,et=Math.abs(oe.shift?.y||0),Me=ee.reference.height/2,$e=typeof i=="function"?i(op(G,n,B)):i,ut=et>$e,pt={top:`${vr}px calc(100% + ${$e}px)`,bottom:`${vr}px ${-$e}px`,left:`calc(100% + ${$e}px) ${kr}px`,right:`${-$e}px ${kr}px`}[ie],br=`${vr}px ${ee.reference.y+Me-Qe}px`;return y.floating.style.setProperty("--transform-origin",H&&Je==="y"&&ut?br:pt),{}}},ep,C),we(()=>{!w&&b&&b.update({referenceElement:null,floatingElement:null,domReferenceElement:null,positionReference:null})},[w,b]);let le=nr.useMemo(()=>({elementResize:!d&&typeof ResizeObserver<"u",layoutShift:!d&&typeof IntersectionObserver<"u"}),[d]),{refs:fe,elements:me,x:he,y:V,middlewareData:te,update:Ne,placement:He,context:ot,isPositioned:Ze,floatingStyles:Be}=t({rootContext:b,open:g?w:void 0,placement:P,middleware:M,strategy:o,whileElementsMounted:g?void 0:(...G)=>ri(...G,le),nodeId:v,externalTree:E}),{sideX:Ue,sideY:ct}=te.adaptiveOrigin||hn,Se=Ze?o:"fixed",Or=nr.useMemo(()=>{let G;return Ze?C?G={position:Se,[Ue]:he,[ct]:V}:G={...Be,position:Se}:G={position:Se,top:0,left:0},G[tp]="100vw",G[rp]="100vh",Ze||(G.opacity=0),G},[C,Se,Ue,he,ct,V,Be,Ze]),$t=nr.useRef(null);we(()=>{if(!w)return;let G=q.current,y=typeof G=="function"?G():G,Ae=(np(y)?y.current:y)||null||null;Ae!==$t.current&&(fe.setPositionReference(Ae),$t.current=Ae)},[w,fe,N,q]),nr.useEffect(()=>{if(!w)return;let G=q.current;typeof G!="function"&&np(G)&&G.current!==$t.current&&(fe.setPositionReference(G.current),$t.current=G.current)},[w,fe,N,q]),nr.useEffect(()=>{if(g&&w&&me.reference&&me.floating)return ri(me.reference,me.floating,Ne,le)},[g,w,me,Ne,le]);let Ye=Tt(He),Yr=ip(n,Ye,B),St=_r(He)||"center",kt=!!te.hide?.referenceHidden;we(()=>{k&&w&&Ze&&Ye!==re&&O(Ye)},[k,w,Ze,Ye,re]);let vt=nr.useMemo(()=>({position:"absolute",top:te.arrow?.y,left:te.arrow?.x}),[te.arrow]),F=te.arrow?.centerOffset!==0;return nr.useMemo(()=>({positionerStyles:Or,arrowStyles:vt,arrowRef:Ce,arrowUncentered:F,side:Yr,align:St,physicalSide:Ye,anchorHidden:kt,refs:fe,context:ot,isPositioned:Ze,update:Ne}),[Or,vt,Ce,F,Yr,St,Ye,kt,fe,ot,Ze,Ne])}function np(e){return e!=null&&"current"in e}function ds(e){return e==="starting"?Mf:nt}function ap(e,t,{styles:r,transitionStatus:o,props:n,refs:i,hidden:s,inert:a=!1}){let u={...r};return a&&(u.pointerEvents="none"),Gt("div",e,{state:t,ref:i,props:[{role:"presentation",hidden:s,style:u},ds(o),n],stateAttributesMapping:ni})}var Et=f(ve(),1),gp=f(lo(),1);var lp=f(ve(),1);function cp(e){let[t,r]=lp.useState({current:e,previous:null});return Object.is(e,t.current)||r({current:e,previous:t.current}),t.previous}var gn=f(ve(),1);function El(e){let t=Lt(e),r=parseFloat(t.width)||0,o=parseFloat(t.height)||0,n=Ct(e),i=n?e.offsetWidth:r,s=n?e.offsetHeight:o;return(fo(r)!==i||fo(o)!==s)&&(r=i,o=s),{width:r,height:o}}function fp(e){let{popupElement:t,positionerElement:r,content:o,mounted:n,onMeasureLayout:i,onMeasureLayoutComplete:s,side:a,direction:u}=e,l=ln(t,!0),c=sn(),m=gn.useRef(null),d=gn.useRef(!0),h=gn.useRef(tr),g=Pe(i),b=Pe(s),w=gn.useMemo(()=>Tw(a,u),[a,u]);we(()=>{if(!n){h.current=tr,d.current=!0,m.current=null;return}if(!t||!r)return;h.current=up(t,w),Tl(t,"auto");let _=ms(t,"position","static"),x=ms(t,"transform","none"),v=ms(t,"scale","1"),C=up(r,{"--available-width":"max-content","--available-height":"max-content"});function k(){_(),x(),C()}function E(){k(),v()}if(g?.(),d.current||m.current===null){ps(r,"max-content");let J=El(t);return m.current=J,ps(r,J),E(),b?.(null,J),d.current=!1,()=>{h.current(),h.current=tr}}ps(r,"max-content");let T=m.current,O=El(t);m.current=O,Tl(t,T),E(),b?.(T,O),ps(r,O);let I=new AbortController;return c.request(()=>{Tl(t,O),l(()=>{t.style.setProperty("--popup-width","auto"),t.style.setProperty("--popup-height","auto")},I.signal)}),()=>{I.abort(),c.cancel(),h.current(),h.current=tr}},[o,t,r,l,c,n,g,b,w])}function Tw(e,t){let r=e==="top",o=e==="left"||e===(t==="rtl"?"inline-end":"inline-start");return!r&&!o?nt:{position:"absolute",[r?"bottom":"top"]:"0",[o?"right":"left"]:"0"}}function ms(e,t,r){let o=e.style.getPropertyValue(t);return e.style.setProperty(t,r),()=>{e.style.setProperty(t,o)}}function up(e,t){let r=[];for(let[o,n]of Object.entries(t))r.push(ms(e,o,n));return r.length?()=>{r.forEach(o=>o())}:tr}function Tl(e,t){let r=t==="auto"?"auto":`${t.width}px`,o=t==="auto"?"auto":`${t.height}px`;e.style.setProperty("--popup-width",r),e.style.setProperty("--popup-height",o)}function ps(e,t){let r=t==="max-content"?"max-content":`${t.width}px`,o=t==="max-content"?"max-content":`${t.height}px`;e.style.setProperty("--positioner-width",r),e.style.setProperty("--positioner-height",o)}var dp=f(ve(),1);var pp=f(Z(),1),hs=function(t){let{direction:r="ltr"}=t,o=dp.useMemo(()=>({direction:r}),[r]);return(0,pp.jsx)(Rl.Provider,{value:o,children:t.children})};var mp={name:"adaptiveOrigin",async fn(e){let{x:t,y:r,rects:{floating:o},elements:{floating:n},platform:i,strategy:s,placement:a}=e,u=it(n),l=u.getComputedStyle(n);if(!(l.transitionDuration!=="0s"&&l.transitionDuration!==""))return{x:t,y:r,data:hn};let m=await i.getOffsetParent?.(n),d={width:0,height:0};if(s==="fixed"&&u?.visualViewport)d={width:u.visualViewport.width,height:u.visualViewport.height};else if(m===u){let x=Rt(n);d={width:x.documentElement.clientWidth,height:x.documentElement.clientHeight}}else await i.isElement?.(m)&&(d=await i.getDimensions(m));let h=Tt(a),g=t,b=r;h==="left"&&(g=d.width-(t+o.width)),h==="top"&&(b=d.height-(r+o.height));let w=h==="left"?"right":hn.sideX,_=h==="top"?"bottom":hn.sideY;return{x:g,y:b,data:{sideX:w,sideY:_}}}};var yn=f(Z(),1),yp={activationDirection:e=>e?{"data-activation-direction":e}:null};function vp(e){let{store:t,side:r,children:o}=e,n=mn(),i=t.useState("activeTriggerElement"),s=t.useState("activeTriggerId"),a=t.useState("open"),u=t.useState("payload"),l=t.useState("mounted"),c=t.useState("popupElement"),m=t.useState("positionerElement"),d=cp(a?i:null),h=kw(s,u),g=Et.useRef(null),[b,w]=Et.useState(null),[_,x]=Et.useState(null),v=Et.useRef(null),C=Et.useRef(null),k=ln(v,!0),E=sn(),T=Et.useRef(null),[O,I]=Et.useState(null),[J,D]=Et.useState(!1);we(()=>(t.set("adaptiveOrigin",mp),()=>{t.set("adaptiveOrigin",void 0)}),[t]);let S=Pe(()=>{v.current?.style.setProperty("animation","none"),v.current?.style.setProperty("transition","none"),C.current?.style.setProperty("display","none")}),L=Pe(R=>{v.current?.style.removeProperty("animation"),v.current?.style.removeProperty("transition"),C.current?.style.removeProperty("display"),R&&I(R)}),Y=Pe(()=>{T.current?.abort();let R=new AbortController;T.current=R,k(()=>{w(null),I(null),g.current=null},R.signal)}),A=Et.useRef(null);we(()=>{(!a||!l)&&(A.current=null)},[a,l]),we(()=>{if(i&&d&&i!==d&&A.current!==i&&g.current){w(g.current),D(!0);let R=Ow(d,i);x(R),A.current=i}},[i,d]),we(()=>{b!=null&&(T.current?.abort(),D(!0),E.request(()=>{gp.flushSync(()=>{D(!1)}),Y()}))},[h,b,Y,E]),we(()=>{let R=v.current;if(!R)return;let B=Rt(R).createElement("div");for(let re of Array.from(R.childNodes))B.appendChild(re.cloneNode(!0));g.current=B});let N=b!=null,q;N?q=(0,yn.jsxs)(Et.Fragment,{children:[(0,yn.jsx)("div",{"data-previous":!0,inert:Qd(!0),ref:C,style:{...O?{"--popup-width":`${O.width}px`,"--popup-height":`${O.height}px`}:null,position:"absolute"},"data-ending-style":J?void 0:""},"previous"),(0,yn.jsx)("div",{"data-current":!0,ref:v,"data-starting-style":J?"":void 0,children:o},h)]}):q=(0,yn.jsx)("div",{"data-current":!0,ref:v,children:o},h),we(()=>{let R=C.current;!R||!b||R.replaceChildren(...Array.from(b.childNodes))},[b]),fp({popupElement:c,positionerElement:m,mounted:l,content:u,onMeasureLayout:S,onMeasureLayoutComplete:L,side:r,direction:n});let U={activationDirection:Pw(_),transitioning:N};return{children:q,state:U}}function Pw(e){if(e)return`${hp(e.horizontal,5,"right","left")} ${hp(e.vertical,5,"down","up")}`}function hp(e,t,r,o){return e>t?r:e<-t?o:""}function Ow(e,t){let r=e.getBoundingClientRect(),o=t.getBoundingClientRect(),n={x:r.left+r.width/2,y:r.top+r.height/2},i={x:o.left+o.width/2,y:o.top+o.height/2};return{horizontal:i.x-n.x,vertical:i.y-n.y}}function kw(e,t){let[r,o]=Et.useState(0),n=Et.useRef(e),i=Et.useRef(t),s=Et.useRef(!1);return we(()=>{let a=n.current,u=i.current,l=e!==a,c=t!==u;l?(o(m=>m+1),s.current=!c):s.current&&c&&(o(m=>m+1),s.current=!1),n.current=e,i.current=t},[e,t]),`${e??"current"}-${r}`}var gs=f(ve(),1),bp=f(lo(),1);var wp=f(Z(),1),xp=gs.forwardRef(function(t,r){let{children:o,container:n,className:i,render:s,style:a,...u}=t,{node:l,subtree:c}=jf({container:n,ref:r,componentProps:t,elementProps:u});return!c&&!l?null:(0,wp.jsxs)(gs.Fragment,{children:[c,l&&bp.createPortal(o,l)]})});var Xt={};so(Xt,{Arrow:()=>jp,Handle:()=>si,Popup:()=>Dp,Portal:()=>Lp,Positioner:()=>Mp,Provider:()=>Hp,Root:()=>Tp,Trigger:()=>Fp,Viewport:()=>Wp,createHandle:()=>Gp});var vn=f(ve(),1);var ys=f(ve(),1),Pl=ys.createContext(void 0);function ur(e){let t=ys.useContext(Pl);if(t===void 0&&!e)throw new Error(lr(72));return t}var Sp=f(ve(),1);var _p={...Wd,disabled:e=>e.disabled,instantType:e=>e.instantType,isInstantPhase:e=>e.isInstantPhase,trackCursorAxis:e=>e.trackCursorAxis,disableHoverablePopup:e=>e.disableHoverablePopup,lastOpenChangeReason:e=>e.openChangeReason,closeOnClick:e=>e.closeOnClick,closeDelay:e=>e.closeDelay,adaptiveOrigin:e=>e.adaptiveOrigin},vs=class extends mo{constructor(t,r,o){let n=new Ho;super(Rp(t,n,r,o),Ep(n),_p)}setOpen=(t,r)=>{Ld(this,t,r,{extraState:{openChangeReason:r.reason}})};cancelPendingOpen(t){this.state.floatingRootContext.dispatchOpenChange(!1,Ve(Oe.triggerPress,t))}};function Cp(){let e=new Ho,t=new us(Object.freeze(Rp(void 0,e)),Object.freeze(Ep(e)),_p);return Object.assign(t,{setOpen:tr,cancelPendingOpen:tr})}function Rp(e,t,r,o=!1){let n={...zd(),disabled:!1,instantType:void 0,isInstantPhase:!1,trackCursorAxis:"none",disableHoverablePopup:!1,openChangeReason:null,closeOnClick:!0,closeDelay:0,adaptiveOrigin:void 0,...e};return n.floatingRootContext=Hd(t,r,o),n}function Ep(e){return{popupRef:Sp.createRef(),onOpenChange:void 0,onOpenChangeComplete:void 0,triggerElements:e}}var ii=f(Z(),1),Tp=ml(function(t){let{disabled:r=!1,defaultOpen:o=!1,open:n,disableHoverablePopup:i=!1,trackCursorAxis:s="none",actionsRef:a,onOpenChange:u,onOpenChangeComplete:l,handle:c,triggerId:m,defaultTriggerId:d=null,children:h}=t,g=Ad((D,S)=>new vs({open:o,openProp:n,activeTriggerId:d,triggerIdProp:m},D,S));g.useControlledProp("openProp",n),g.useControlledProp("triggerIdProp",m),g.useContextCallback("onOpenChange",u),g.useContextCallback("onOpenChangeComplete",l);let b=g.useState("open"),w=!r&&b,_=g.useState("activeTriggerId"),x=g.useState("mounted"),v=g.useState("payload");g.useSyncedValues({trackCursorAxis:s,disableHoverablePopup:i,disabled:r}),Md(g,{closeOnActiveTriggerUnmount:!0});let{forceUnmount:C,transitionStatus:k}=Vd(w,g),E=g.useState("isInstantPhase"),T=g.useState("instantType"),O=g.useState("lastOpenChangeReason"),I=vn.useRef(null);we(()=>{b&&r&&g.setOpen(!1,Ve(Oe.disabled))},[b,r,g]),we(()=>{k==="ending"&&O===Oe.none||k!=="ending"&&E?(T!=="delay"&&(I.current=T),g.set("instantType","delay")):I.current!==null&&(g.set("instantType",I.current),I.current=null)},[k,E,O,T,g]),we(()=>{w&&_==null&&g.set("payload",void 0)},[g,_,w]),vn.useImperativeHandle(a,()=>({unmount:C,close:()=>g.setOpen(!1,Ve(Oe.imperativeAction))}),[C,g]);let J=w||x||!r&&s!=="none";return(0,ii.jsxs)(Pl.Provider,{value:g,children:[c&&(0,ii.jsx)(Id,{handle:c,store:g}),J&&(0,ii.jsx)(Fw,{store:g,disabled:r,trackCursorAxis:s}),typeof h=="function"?h({payload:v}):h]})});function Fw({store:e,disabled:t,trackCursorAxis:r}){let o=e.useState("floatingRootContext"),n=tl(o,{enabled:!t,referencePress:()=>e.select("closeOnClick")}),i=el(o,{enabled:!t&&r!=="none",axis:r==="none"?void 0:r}),s=vn.useMemo(()=>It(i.reference,n.reference),[i.reference,n.reference]);return Dd(e,{activeTriggerProps:s,inactiveTriggerProps:s,popupProps:n.floating??nt}),null}var ws=f(ve(),1);var bs=f(ve(),1),Ol=bs.createContext(void 0);function Pp(){return bs.useContext(Ol)}var kp="data-base-ui-tooltip-trigger";function Op(e){if("composedPath"in e){let r=e.composedPath();for(let o=0;ow.select("transitionStatus")==="ending",shouldOpen(){return!B.current}}),be=bl(C,{enabled:!N}).reference,ye=Le=>{let X=B.current,M=Op(Le),K=xe(M),H=k.current,Q=H&&M&&Ge(H,M);if(K&&w.select("open")&&w.select("lastOpenChangeReason")===Oe.triggerHover){w.setOpen(!1,Ve(Oe.triggerHover,Le));return}if(X&&!K&&Q&&!q.current&&!w.select("open")&&H&&Xr(P.current)){let pe=()=>{!B.current&&!q.current&&!w.select("open")&&w.setOpen(!0,Ve(Oe.triggerHover,Le,H))},le=W();le===0?(re.clear(),pe()):re.start(le,pe)}},$=w.useState("triggerProps",I);return Gt("button",t,{state:{open:v},ref:[r,O,k],props:[se,be,I||U!=="none"?$:void 0,{onMouseOver(Le){ye(Le.nativeEvent)},onFocus(Le){ne(Op(Le.nativeEvent))&&Le.preventBaseUIHandler()},onMouseLeave(){B.current=!1,re.clear(),P.current=void 0},onPointerEnter(Le){P.current=Le.pointerType},onPointerDown(Le){P.current=Le.pointerType,w.set("closeOnClick",c),c&&!w.select("open")&&w.cancelPendingOpen(Le.nativeEvent)},onClick(Le){c&&!w.select("open")&&w.cancelPendingOpen(Le.nativeEvent)},id:_,"data-trigger-disabled":N?"":void 0,[kp]:N?void 0:""},h],stateAttributesMapping:Kd})});var Ip=f(ve(),1);var xs=f(ve(),1),kl=xs.createContext(void 0);function Ap(){let e=xs.useContext(kl);if(e===void 0)throw new Error(lr(70));return e}var Fl=f(Z(),1),Lp=Ip.forwardRef(function(t,r){let{keepMounted:o=!1,...n}=t;return ur().useState("mounted")||o?(0,Fl.jsx)(kl.Provider,{value:o,children:(0,Fl.jsx)(xp,{ref:r,...n})}):null});var _s=f(ve(),1);var Ss=f(ve(),1),Al=Ss.createContext(void 0);function bn(){let e=Ss.useContext(Al);if(e===void 0)throw new Error(lr(71));return e}var Np=f(Z(),1),Mp=_s.forwardRef(function(t,r){let{render:o,className:n,anchor:i,positionMethod:s="absolute",side:a="top",align:u="center",sideOffset:l=0,alignOffset:c=0,collisionBoundary:m="clipping-ancestors",collisionPadding:d=5,arrowPadding:h=5,sticky:g=!1,disableAnchorTracking:b=!1,collisionAvoidance:w=Vf,style:_,...x}=t,v=ur(),C=Ap(),k=v.useState("open"),E=v.useState("mounted"),T=v.useState("trackCursorAxis"),O=v.useState("disableHoverablePopup"),I=v.useState("floatingRootContext"),J=v.useState("instantType"),D=v.useState("transitionStatus"),S=v.useState("adaptiveOrigin"),L=sp({anchor:i,positionMethod:s,floatingRootContext:I,mounted:E,side:a,sideOffset:l,align:u,alignOffset:c,collisionBoundary:m,collisionPadding:d,sticky:g,arrowPadding:h,disableAnchorTracking:b,keepMounted:C,collisionAvoidance:w,adaptiveOrigin:S}),Y=_s.useMemo(()=>({open:k,side:L.side,align:L.align,anchorHidden:L.anchorHidden,instant:T!=="none"?"tracking-cursor":J}),[k,L.side,L.align,L.anchorHidden,T,J]),A=ap(t,Y,{styles:L.positionerStyles,transitionStatus:D,props:x,refs:[r,v.useStateSetter("positionerElement")],hidden:!E,inert:!k||T==="both"||O});return(0,Np.jsx)(Al.Provider,{value:L,children:A})});var Vp=f(ve(),1);var Dp=Vp.forwardRef(function(t,r){let{render:o,className:n,style:i,...s}=t,a=ur(),{side:u,align:l}=bn(),c=a.useState("open"),m=a.useState("instantType"),d=a.useState("transitionStatus"),h=a.useState("popupProps"),g=a.useState("floatingRootContext"),b=a.useState("disabled"),w=a.useState("closeDelay");zi({open:c,ref:a.context.popupRef,onComplete(){c&&a.context.onOpenChangeComplete?.(!0)}}),Sl(g,{enabled:!b,closeDelay:w});let _=a.useStateSetter("popupElement");return Gt("div",t,{state:{open:c,side:u,align:l,instant:m,transitionStatus:d},ref:[r,a.context.popupRef,_],props:[Fd,h,ds(d),s],stateAttributesMapping:Jd})});var Bp=f(ve(),1);var jp=Bp.forwardRef(function(t,r){let{render:o,className:n,style:i,...s}=t,a=ur(),{arrowRef:u,side:l,align:c,arrowUncentered:m,arrowStyles:d}=bn(),h=a.useState("open"),g=a.useState("instantType");return Gt("div",t,{state:{open:h,side:l,align:c,uncentered:m,instant:g},ref:[r,u],props:[{style:d,"aria-hidden":!0},s],stateAttributesMapping:ni})});var zp=f(ve(),1);var Il=f(Z(),1),Hp=function(t){let{delay:r,closeDelay:o,timeout:n=400}=t,i=zp.useMemo(()=>({open:r,close:o}),[r,o]);return(0,Il.jsx)(Ol.Provider,{value:r,children:(0,Il.jsx)(Qa,{delay:i,timeoutMs:n,children:t.children})})};var Up=f(ve(),1);var Wp=Up.forwardRef(function(t,r){let{render:o,className:n,style:i,children:s,...a}=t,u=ur(),l=bn(),c=u.useState("instantType"),{children:m,state:d}=vp({store:u,side:l.side,children:s}),h={activationDirection:d.activationDirection,transitioning:d.transitioning,instant:c};return Gt("div",t,{state:h,ref:r,props:[a,{children:m}],stateAttributesMapping:yp})});var si=class extends es{constructor(){super(Cp(),"Tooltip")}open(t){this.openByTrigger(t)}close(){this.closePopup()}get isOpen(){return this.attachedStore?.select("open")??!1}};function Gp(){return new si}function Dr(e){return Gt(e.defaultTagName??"div",e,e)}var Zp=f(Te(),1),Ll="data-wp-hash";function Nl(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Nw(document)),e.__wpStyleRuntime}function Lw(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${Ll}]`))if(r.getAttribute(Ll)===t)return!0;return!1}function Xp(e,t,r){if(!e.head)return;let o=Nl(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(Lw(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(Ll,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function Nw(e){let t=Nl();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)Xp(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function Kp(e,t){let r=Nl();r.styles.set(e,t);for(let o of r.documents.keys())Xp(o,e,t)}typeof process>"u",Kp("3167e7d116",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._83ed8a8da5dd50ea__text{text-wrap:pretty;margin:0}._14437cfb77831647__heading-2xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-2xl,32px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-2xl,32px);--_gcd-p-line-height:var(--wpds-typography-line-height-2xl,40px);font-size:var(--wpds-typography-font-size-2xl,32px);line-height:var(--wpds-typography-line-height-2xl,40px)}._14437cfb77831647__heading-2xl,._3c78b7fa9b4072dd__heading-xl{font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-emphasis,600)}._3c78b7fa9b4072dd__heading-xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-p-line-height:var(--wpds-typography-line-height-md,24px);font-size:var(--wpds-typography-font-size-xl,20px);line-height:var(--wpds-typography-line-height-md,24px)}.aa58f227716bcde2__heading-lg{--_gcd-heading-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-lg,15px)}.aa58f227716bcde2__heading-lg,.fc4da56d8dfe52c4__heading-md{font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:var(--wpds-typography-line-height-sm,20px)}.fc4da56d8dfe52c4__heading-md{--_gcd-heading-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-md,13px)}.a9b78c7c82e8dff7__heading-sm{--_gcd-heading-font-size:var(--wpds-typography-font-size-xs,11px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-emphasis,600);--_gcd-p-font-size:var(--wpds-typography-font-size-xs,11px);--_gcd-p-line-height:var(--wpds-typography-line-height-xs,16px);font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-xs,11px);font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:var(--wpds-typography-line-height-xs,16px);text-transform:uppercase}._305ff559e52180d5__body-xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-p-line-height:var(--wpds-typography-line-height-xl,32px);font-size:var(--wpds-typography-font-size-xl,20px);line-height:var(--wpds-typography-line-height-xl,32px)}._305ff559e52180d5__body-xl,.ca1aa3fc2029e958__body-lg{font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-default,400)}.ca1aa3fc2029e958__body-lg{--_gcd-heading-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-p-line-height:var(--wpds-typography-line-height-md,24px);font-size:var(--wpds-typography-font-size-lg,15px);line-height:var(--wpds-typography-line-height-md,24px)}._131101940be12424__body-md{--_gcd-heading-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-md,13px);line-height:var(--wpds-typography-line-height-sm,20px)}._0e8d87a42c1f75fa__body-sm,._131101940be12424__body-md{font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-weight:var(--wpds-typography-font-weight-default,400)}._0e8d87a42c1f75fa__body-sm{--_gcd-heading-font-size:var(--wpds-typography-font-size-sm,12px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-default,400);--_gcd-p-font-size:var(--wpds-typography-font-size-sm,12px);--_gcd-p-line-height:var(--wpds-typography-line-height-xs,16px);font-size:var(--wpds-typography-font-size-sm,12px);line-height:var(--wpds-typography-line-height-xs,16px)}}}');var Yp={text:"_83ed8a8da5dd50ea__text","heading-2xl":"_14437cfb77831647__heading-2xl","heading-xl":"_3c78b7fa9b4072dd__heading-xl","heading-lg":"aa58f227716bcde2__heading-lg","heading-md":"fc4da56d8dfe52c4__heading-md","heading-sm":"a9b78c7c82e8dff7__heading-sm","body-xl":"_305ff559e52180d5__body-xl","body-lg":"ca1aa3fc2029e958__body-lg","body-md":"_131101940be12424__body-md","body-sm":"_0e8d87a42c1f75fa__body-sm"};typeof process>"u",Kp("e8e31009f5","._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-weak,#707070))}&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}.c59a0ebebd71fa4a__ol{list-style:var(--_gcd-ol-list-style,none);margin:var(--_gcd-ol-margin,0);padding-block:var(--_gcd-ol-padding-block,0);padding-inline:var(--_gcd-ol-padding-inline,0)}._46b5cb0c8e24e8c9__li{margin:var(--_gcd-li-margin,0)}");var qp={button:"_6defc79820e382c6__button",input:"d2cff2e5dea83bd1__input",textarea:"_547d86373d02e108__textarea",div:"_8c15fd0ed9f28ba4__div",p:"_43cec3e1eec1066d__p",heading:"e97669c6d9a38497__heading",a:"_2c0831b0499dbd6e__a",ol:"c59a0ebebd71fa4a__ol",li:"_46b5cb0c8e24e8c9__li"},wn=(0,Zp.forwardRef)(function({variant:t="body-md",render:r,className:o,...n},i){return Dr({render:r,defaultTagName:"span",ref:i,props:It(n,{className:We(Yp.text,qp.heading,qp.p,Yp[t],o)})})});var xn={};so(xn,{Popup:()=>ym,Portal:()=>Cs,Positioner:()=>Rs,Provider:()=>Em,Root:()=>Cm,Trigger:()=>wm});var hm=f(Te(),1);var rm=f(Te(),1);var Vl="data-wp-hash";function Dl(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Vw(document)),e.__wpStyleRuntime}function Mw(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${Vl}]`))if(r.getAttribute(Vl)===t)return!0;return!1}function $p(e,t,r){if(!e.head)return;let o=Dl(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(Mw(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(Vl,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function Vw(e){let t=Dl();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)$p(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function Dw(e,t){let r=Dl();r.styles.set(e,t);for(let o of r.documents.keys())$p(o,e,t)}typeof process>"u",Dw("be37f31c1e","._11fc52b637ff8a7e__slot{inset:0;isolation:isolate;pointer-events:none;position:fixed;z-index:1000000003}@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._11fc52b637ff8a7e__slot>*{pointer-events:auto}}}");var Qp={slot:"_11fc52b637ff8a7e__slot"},em="data-wp-compat-overlay-slot";function Bw(){return typeof document>"u"?null:document}function jw(){let e;try{e=window.top?.wp}catch{}let t=e??window.wp;return typeof t?.components=="object"&&t.components!==null}var Br=null;function Ml(e){return e.setAttribute("aria-hidden","false"),e}function zw(e){let t=e.createElement("div");return t.setAttribute(em,""),Qp.slot&&t.classList.add(Qp.slot),e.body.appendChild(t),t}function tm(){if(typeof window>"u"||!jw()&&window.__wpUiCompatOverlaySlotEnabled!==!0)return;let e=Bw();if(!e||!e.body)return;if(Br&&Br.ownerDocument===e&&Br.isConnected)return Ml(Br);let t=e.querySelector(`[${em}]`);return t instanceof HTMLDivElement?(Br=Ml(t),Br):(Br?.isConnected&&Br.remove(),Br=Ml(zw(e)),Br)}var om=f(Z(),1),Cs=(0,rm.forwardRef)(function({container:t,...r},o){return(0,om.jsx)(Xt.Portal,{container:t??tm(),...r,ref:o})});var nm=f(Te(),1),am=f(Z(),1),Bl="data-wp-hash";function jl(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Uw(document)),e.__wpStyleRuntime}function Hw(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${Bl}]`))if(r.getAttribute(Bl)===t)return!0;return!1}function im(e,t,r){if(!e.head)return;let o=jl(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(Hw(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(Bl,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function Uw(e){let t=jl();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)im(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function sm(e,t){let r=jl();r.styles.set(e,t);for(let o of r.documents.keys())im(o,e,t)}typeof process>"u",sm("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var Ww={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",sm("19fcc06039",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}');var Gw={positioner:"_480b748dd3510e64__positioner",popup:"_50096b232db7709d__popup"},Rs=(0,nm.forwardRef)(function({align:t="center",className:r,side:o="top",sideOffset:n=4,...i},s){return(0,am.jsx)(Xt.Positioner,{ref:s,align:t,side:o,sideOffset:n,...i,className:We(Ww["box-sizing"],Gw.positioner,r)})});var lm=f(Te(),1);function zl(e,t,r){return(0,lm.cloneElement)(e??t,{children:r})}var Yw=f(um(),1);var dm=f(ai(),1),{lock:YA,unlock:pm}=(0,dm.__dangerousOptInToUnstableAPIsOnlyForCoreModules)("I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.","@wordpress/ui");function qw(){let e=Yw;if(e.ThemeProvider)return e.ThemeProvider;if(!e.privateApis)throw new Error("@wordpress/ui: @wordpress/theme must expose `ThemeProvider` or `privateApis.ThemeProvider`.");return pm(e.privateApis).ThemeProvider}var mm=qw();var li=f(Z(),1),Hl="data-wp-hash";function Ul(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&Xw(document)),e.__wpStyleRuntime}function Zw(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${Hl}]`))if(r.getAttribute(Hl)===t)return!0;return!1}function gm(e,t,r){if(!e.head)return;let o=Ul(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(Zw(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(Hl,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function Xw(e){let t=Ul();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)gm(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function Kw(e,t){let r=Ul();r.styles.set(e,t);for(let o of r.documents.keys())gm(o,e,t)}typeof process>"u",Kw("19fcc06039",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._480b748dd3510e64__positioner{z-index:var(--wp-ui-tooltip-z-index,initial)}._50096b232db7709d__popup{--_wp-ui-elevation-sm:0 1px 2px rgba(0,0,0,.05),0 2px 3px rgba(0,0,0,.04),0 6px 6px rgba(0,0,0,.03),0 8px 8px rgba(0,0,0,.02);background-color:var(--wpds-color-background-surface-neutral-strong,#fff);border-radius:var(--wpds-border-radius-md,4px);box-shadow:var(--_wp-ui-elevation-sm);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif);font-size:var(--wpds-typography-font-size-sm,12px);line-height:1.4;padding:var(--wpds-dimension-padding-xs,4px) var(--wpds-dimension-padding-sm,8px);@media (forced-colors:active){border-bottom-color:CanvasText;border-bottom-style:solid;border-bottom-width:1px;border-left-color:CanvasText;border-left-style:solid;border-left-width:1px;border-right-color:CanvasText;border-right-style:solid;border-right-width:1px;border-top-color:CanvasText;border-top-style:solid;border-top-width:1px}}}}');var Jw={positioner:"_480b748dd3510e64__positioner",popup:"_50096b232db7709d__popup"},Qw={background:"#1e1e1e"},ym=(0,hm.forwardRef)(function({portal:t,positioner:r,children:o,className:n,...i},s){let a=(0,li.jsx)(mm,{color:Qw,children:(0,li.jsx)(Xt.Popup,{ref:s,className:We(Jw.popup,n),...i,children:o})}),u=zl(r,(0,li.jsx)(Rs,{}),a);return zl(t,(0,li.jsx)(Cs,{}),u)});var vm=f(Te(),1),bm=f(Z(),1),wm=(0,vm.forwardRef)(function(t,r){return(0,bm.jsx)(Xt.Trigger,{ref:r,...t})});var xm=f(ge(),1),Sm=f(Z(),1);function _m({children:e}){return(0,Sm.jsx)(hs,{direction:(0,xm.isRTL)()?"rtl":"ltr",children:e})}var Wl=f(Z(),1);function Cm(e){return(0,Wl.jsx)(_m,{children:(0,Wl.jsx)(Xt.Root,{...e})})}var Rm=f(Z(),1);function Em({...e}){return(0,Rm.jsx)(Xt.Provider,{...e})}var Tm=f(Te(),1),Pm=f(ge(),1),Sn=f(Z(),1),Gl="data-wp-hash";function Yl(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&e1(document)),e.__wpStyleRuntime}function $w(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${Gl}]`))if(r.getAttribute(Gl)===t)return!0;return!1}function Om(e,t,r){if(!e.head)return;let o=Yl(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if($w(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(Gl,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function e1(e){let t=Yl();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)Om(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function Ts(e,t){let r=Yl();r.styles.set(e,t);for(let o of r.documents.keys())Om(o,e,t)}typeof process>"u",Ts("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var t1={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",Ts("08122b3d53","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{.af79fb116edb0dd7__outset-ring--focus:focus,.dfcfdc28396e5d98__outset-ring--focus-visible:focus-visible,.e5cd9ee879f6403a__outset-ring--focus-within:focus-within,:focus-visible ._81935a08e952f267__outset-ring--focus-parent-visible{--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within,.abc777e9713fa711__outset-ring--focus-except-active:focus{outline:none}._3c9f5ee9fc9c136d__outset-ring--focus-within-except-active:focus-within:not(:has(:active)),.abc777e9713fa711__outset-ring--focus-except-active:focus:not(:active){--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--focus-color,var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9)));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}}}");var r1={"outset-ring--focus":"af79fb116edb0dd7__outset-ring--focus","outset-ring--focus-visible":"dfcfdc28396e5d98__outset-ring--focus-visible","outset-ring--focus-within":"e5cd9ee879f6403a__outset-ring--focus-within","outset-ring--focus-parent-visible":"_81935a08e952f267__outset-ring--focus-parent-visible","outset-ring--focus-except-active":"abc777e9713fa711__outset-ring--focus-except-active","outset-ring--focus-within-except-active":"_3c9f5ee9fc9c136d__outset-ring--focus-within-except-active"};typeof process>"u",Ts("e8e6a9be37",'@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.d4250949359b05ce__link{text-decoration-thickness:from-font;text-underline-offset:.2em}.c6055659b8e2cd2c__is-brand,.c6055659b8e2cd2c__is-brand:visited{--_gcd-a-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9))}.c6055659b8e2cd2c__is-brand:active,.c6055659b8e2cd2c__is-brand:hover{--_gcd-a-color:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));color:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000))}._92e0dfcaeee15b88__is-neutral,._92e0dfcaeee15b88__is-neutral:visited{--_gcd-a-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);text-decoration-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d)}._92e0dfcaeee15b88__is-neutral:active,._92e0dfcaeee15b88__is-neutral:hover{--_gcd-a-color:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);color:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e)}.cf122a9bf1035d42__is-unstyled{--_gcd-a-color:inherit;color:inherit;text-decoration:none}._0cb411afac4c86c7__link-icon{display:inline-block;font-weight:var(--wpds-typography-font-weight-default,400);line-height:1;margin-inline-start:var(--wpds-dimension-padding-xs,4px);text-decoration:none}._0cb411afac4c86c7__link-icon:after{content:"\\2197"}._0cb411afac4c86c7__link-icon:dir(rtl):after{content:"\\2196"}}}');var Es={link:"d4250949359b05ce__link","is-brand":"c6055659b8e2cd2c__is-brand","is-neutral":"_92e0dfcaeee15b88__is-neutral","is-unstyled":"cf122a9bf1035d42__is-unstyled","link-icon":"_0cb411afac4c86c7__link-icon"};typeof process>"u",Ts("e8e31009f5","._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-weak,#707070))}&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-emphasis,600));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}.c59a0ebebd71fa4a__ol{list-style:var(--_gcd-ol-list-style,none);margin:var(--_gcd-ol-margin,0);padding-block:var(--_gcd-ol-padding-block,0);padding-inline:var(--_gcd-ol-padding-inline,0)}._46b5cb0c8e24e8c9__li{margin:var(--_gcd-li-margin,0)}");var o1={button:"_6defc79820e382c6__button",input:"d2cff2e5dea83bd1__input",textarea:"_547d86373d02e108__textarea",div:"_8c15fd0ed9f28ba4__div",p:"_43cec3e1eec1066d__p",heading:"e97669c6d9a38497__heading",a:"_2c0831b0499dbd6e__a",ol:"c59a0ebebd71fa4a__ol",li:"_46b5cb0c8e24e8c9__li"},ql=(0,Tm.forwardRef)(function({children:t,variant:r="default",tone:o="brand",openInNewTab:n=!1,target:i,render:s,className:a,...u},l){let c=n||/^_blank$/i.test(i??"");return Dr({render:s,defaultTagName:"a",ref:l,props:It(u,{className:We(o1.a,t1["box-sizing"],r1["outset-ring--focus-except-active"],r!=="unstyled"&&Es.link,r!=="unstyled"&&Es[`is-${o}`],r==="unstyled"&&Es["is-unstyled"],a),target:i??(n?"_blank":void 0),children:(0,Sn.jsxs)(Sn.Fragment,{children:[t,c&&(0,Sn.jsx)("span",{className:Es["link-icon"],role:"img","aria-label":(0,Pm.__)("(opens in a new tab)")})]})})})});var Ps=f(Te(),1),ci=(0,Ps.forwardRef)(({icon:e,size:t=24,style:r,...o},n)=>{let i=e.props.style,s=i||r?{...i,...r}:void 0;return(0,Ps.cloneElement)(e,{width:t,height:t,...o,...s?{style:s}:{},ref:n})});var Os=f(_n(),1),Zl=f(Z(),1),Uo=(0,Zl.jsx)(Os.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",style:{fill:"none"},stroke:"currentColor",strokeWidth:"1.5",children:(0,Zl.jsx)(Os.Path,{d:"M14 6.5L9 12L14 17.5",vectorEffect:"non-scaling-stroke"})});var ks=f(_n(),1),Xl=f(Z(),1),Wo=(0,Xl.jsx)(ks.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",style:{fill:"none"},stroke:"currentColor",strokeWidth:"1.5",children:(0,Xl.jsx)(ks.Path,{d:"M10 6.5L15 12L10 17.5",vectorEffect:"non-scaling-stroke"})});var Fs=f(_n(),1),Kl=f(Z(),1),Jl=(0,Kl.jsx)(Fs.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",children:(0,Kl.jsx)(Fs.Path,{d:"M13 19h-2v-2h2v2zm0-6h-2v-2h2v2zm0-6h-2V5h2v2z"})});var As=f(_n(),1),Ql=f(Z(),1),Is=(0,Ql.jsx)(As.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",style:{fill:"none"},stroke:"currentColor",strokeWidth:"1.5",children:(0,Ql.jsx)(As.Path,{d:"M7 17.5L12 12L7 6.5M13 17.5L18 12L13 6.5",vectorEffect:"non-scaling-stroke"})});var Ls=f(_n(),1),$l=f(Z(),1),Ns=(0,$l.jsx)(Ls.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",style:{fill:"none"},stroke:"currentColor",strokeWidth:"1.5",children:(0,$l.jsx)(Ls.Path,{d:"M17 6.5L12 12L17 17.5M11 6.5L6 12L11 17.5",vectorEffect:"non-scaling-stroke"})});var Fm=f(Te(),1),ec="data-wp-hash";function tc(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&i1(document)),e.__wpStyleRuntime}function n1(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${ec}]`))if(r.getAttribute(ec)===t)return!0;return!1}function Am(e,t,r){if(!e.head)return;let o=tc(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(n1(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(ec,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function i1(e){let t=tc();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)Am(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function s1(e,t){let r=tc();r.styles.set(e,t);for(let o of r.documents.keys())Am(o,e,t)}typeof process>"u",s1("fa606a57ae","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.f37b9e2e191ebd66__visually-hidden{word-wrap:normal;border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-break:normal}}}");var a1={"visually-hidden":"f37b9e2e191ebd66__visually-hidden"},rc=(0,Fm.forwardRef)(function({render:t,...r},o){return Dr({render:t,ref:o,props:It({className:a1["visually-hidden"]},r,{"data-visually-hidden":""})})});var Im=f(Te(),1),oc="data-wp-hash";function nc(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&c1(document)),e.__wpStyleRuntime}function l1(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${oc}]`))if(r.getAttribute(oc)===t)return!0;return!1}function Lm(e,t,r){if(!e.head)return;let o=nc(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(l1(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(oc,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function c1(e){let t=nc();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)Lm(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function u1(e,t){let r=nc();r.styles.set(e,t);for(let o of r.documents.keys())Lm(o,e,t)}typeof process>"u",u1("32aba35fe1","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._19ce0419607e1896__stack{display:flex}}}");var f1={stack:"_19ce0419607e1896__stack"},d1={xs:"var(--wpds-dimension-gap-xs, 4px)",sm:"var(--wpds-dimension-gap-sm, 8px)",md:"var(--wpds-dimension-gap-md, 12px)",lg:"var(--wpds-dimension-gap-lg, 16px)",xl:"var(--wpds-dimension-gap-xl, 24px)","2xl":"var(--wpds-dimension-gap-2xl, 32px)","3xl":"var(--wpds-dimension-gap-3xl, 40px)"},vo=(0,Im.forwardRef)(function({direction:t,gap:r,align:o,justify:n,wrap:i,render:s,...a},u){let l={gap:r&&d1[r],alignItems:o,justifyContent:n,flexDirection:t,flexWrap:i};return Dr({render:s,ref:u,props:It(a,{style:l,className:f1.stack})})});var Mm=f(Te(),1),ic="data-wp-hash";function sc(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&m1(document)),e.__wpStyleRuntime}function p1(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${ic}]`))if(r.getAttribute(ic)===t)return!0;return!1}function Vm(e,t,r){if(!e.head)return;let o=sc(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(p1(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(ic,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function m1(e){let t=sc();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)Vm(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function Dm(e,t){let r=sc();r.styles.set(e,t);for(let o of r.documents.keys())Vm(o,e,t)}typeof process>"u",Dm("10f3806643","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");var h1={"box-sizing":"_336cd3e4e743482f__box-sizing"};typeof process>"u",Dm("ed2c39ec90","@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{.b20cc1690085c2f0__skeleton{background-color:var(--wpds-color-background-surface-neutral-weak,#f4f4f4);display:block;@media (forced-colors:active){border:var(--wpds-border-width-xs,1px) solid CanvasText}}._9b143194fdb45f93__pulse{@media not (prefers-reduced-motion){animation:e2b9fe0690281bc8__skeleton-pulse 1.5s ease-in-out infinite}}@keyframes e2b9fe0690281bc8__skeleton-pulse{0%,to{opacity:1}50%{opacity:.4}}}}");var Nm={skeleton:"b20cc1690085c2f0__skeleton",pulse:"_9b143194fdb45f93__pulse","skeleton-pulse":"e2b9fe0690281bc8__skeleton-pulse"},ui=(0,Mm.forwardRef)(function({render:t,...r},o){return Dr({render:t,ref:o,props:It({className:We(Nm.skeleton,Nm.pulse,h1["box-sizing"]),"aria-hidden":!0},r)})});var Bm=f(Te(),1),jm=f(Z(),1),zm=(0,Bm.forwardRef)(({children:e,className:t,ariaLabel:r,as:o="div",...n},i)=>(0,jm.jsx)(o,{ref:i,className:We("admin-ui-navigable-region",t),"aria-label":r,role:"region",tabIndex:"-1",...n,children:e}));zm.displayName="NavigableRegion";var Hm=zm;var Um=f(ge(),1);var bo=f(Z(),1),lc="data-wp-hash";function cc(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&y1(document)),e.__wpStyleRuntime}function g1(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${lc}]`))if(r.getAttribute(lc)===t)return!0;return!1}function Wm(e,t,r){if(!e.head)return;let o=cc(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(g1(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(lc,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function y1(e){let t=cc();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)Wm(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function v1(e,t){let r=cc();r.styles.set(e,t);for(let o of r.documents.keys())Wm(o,e,t)}typeof process>"u",v1("72ef022400",".bfb5a2dd8cceebd3__list{--focus-ring-size:calc(var(--wpds-border-width-focus, var(--wp-admin-border-width-focus, 2px))*2);list-style:none;margin:calc(var(--focus-ring-size)*-1);overflow-x:auto;padding:var(--focus-ring-size);scroll-padding:var(--focus-ring-size)}.a4759b4cb2c8bd92__li{flex-shrink:0}._07da506d3f2d9afe__item{align-items:center;color:var(--wpds-color-foreground-interactive-neutral-weak,#707070);display:flex;font-weight:var(--wpds-typography-font-weight-default,400);min-block-size:44px;min-inline-size:44px;text-decoration:none}._07da506d3f2d9afe__item:hover,._07da506d3f2d9afe__item[aria-current=page]{color:var(--wpds-color-foreground-interactive-neutral-weak-active,#1e1e1e)}._07da506d3f2d9afe__item[aria-current=page]{font-weight:var(--wpds-typography-font-weight-emphasis,600)}");var ac={list:"bfb5a2dd8cceebd3__list",li:"a4759b4cb2c8bd92__li",item:"_07da506d3f2d9afe__item"},b1=({items:e,currentHref:t,ariaLabel:r=(0,Um.__)("Sections"),linkComponent:o,className:n})=>{if(!e.length)return null;let i=o??"a";return(0,bo.jsx)("nav",{"aria-label":r,className:n,children:(0,bo.jsx)(vo,{render:(0,bo.jsx)("ul",{role:"list"}),direction:"row",align:"center",gap:"md",className:ac.list,children:e.map(s=>(0,bo.jsx)("li",{className:ac.li,children:(0,bo.jsx)(wn,{variant:"body-md",className:ac.item,render:(0,bo.jsx)(ql,{variant:"unstyled","aria-current":s.href===t?"page":void 0,render:(0,bo.jsx)(i,{href:s.href})}),children:s.label})},s.href))})})},Gm=b1;var qm=f(ue(),1),{Fill:Zm,Slot:Xm}=(0,qm.createSlotFill)("SidebarToggle");var ir=f(Z(),1),uc="data-wp-hash";function fc(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&x1(document)),e.__wpStyleRuntime}function w1(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${uc}]`))if(r.getAttribute(uc)===t)return!0;return!1}function Km(e,t,r){if(!e.head)return;let o=fc(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(w1(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(uc,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function x1(e){let t=fc();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)Km(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function S1(e,t){let r=fc();r.styles.set(e,t);for(let o of r.documents.keys())Km(o,e,t)}typeof process>"u",S1("1f3750277d","._956b6df0898efed0__page{text-wrap:pretty;background-color:var(--wpds-color-background-surface-neutral,#fcfcfc);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);display:flex;flex-flow:column;height:100%;position:relative;z-index:1}._0625b55e82a0d93d__header{background:var(--wpds-color-background-surface-neutral-strong,#fff);border-block-end:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral-weak,#f0f0f0);inset-block-start:0;padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px);position:sticky;z-index:1}.a43c44d5ae28b2e8__header-content{min-height:var(--wpds-dimension-size-md,32px)}.b7cb5b9daf3a3b25__header-actions{flex-shrink:0}._8bcd33103b451f30__header-lockup{min-width:0}._8113be94e7caf73c__header-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._9a776c7f70996f61__header-visual{display:grid;flex-shrink:0;grid-template-columns:1fr;grid-template-rows:1fr;height:var(--wpds-dimension-size-sm,24px);width:var(--wpds-dimension-size-sm,24px);>*{grid-column:1/-1;grid-row:1/-1;max-height:100%;max-width:100%}}.d5e0920cd15d35bc__sidebar-toggle-slot:empty{display:none}._60fea2f6bf5319cd__header-subtitle{color:var(--wpds-color-foreground-content-neutral-weak,#707070);padding-block-end:var(--wpds-dimension-padding-xs,4px)}._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation,._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation ._60fea2f6bf5319cd__header-subtitle{padding-block-end:0}._673c99dcbfb58211__header-navigation{margin-block-start:var(--wpds-dimension-gap-md,12px)}.be5e57d029ec4036__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;&._128806d0b26e3a50__has-padding{padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px)}}");var jr={page:"_956b6df0898efed0__page",header:"_0625b55e82a0d93d__header","header-content":"a43c44d5ae28b2e8__header-content","header-actions":"b7cb5b9daf3a3b25__header-actions","header-lockup":"_8bcd33103b451f30__header-lockup","header-title":"_8113be94e7caf73c__header-title","header-visual":"_9a776c7f70996f61__header-visual","sidebar-toggle-slot":"d5e0920cd15d35bc__sidebar-toggle-slot","header-subtitle":"_60fea2f6bf5319cd__header-subtitle","has-navigation":"_4b0f17e503d11619__has-navigation","header-navigation":"_673c99dcbfb58211__header-navigation",content:"be5e57d029ec4036__content","has-padding":"_128806d0b26e3a50__has-padding"};function Jm({headingLevel:e=1,breadcrumbs:t,badges:r,visual:o,title:n,subTitle:i,actions:s,navigation:a,components:u,showSidebarToggle:l=!0}){let c=`h${e}`,m=!!a?.items?.length;return(0,ir.jsxs)(vo,{direction:"column",className:We(jr.header,m&&jr["has-navigation"]),children:[(0,ir.jsxs)(vo,{className:jr["header-content"],direction:"row",gap:"sm",justify:"space-between",children:[(0,ir.jsxs)(vo,{direction:"row",gap:"sm",align:"center",justify:"start",className:jr["header-lockup"],children:[l&&(0,ir.jsx)(Xm,{bubblesVirtually:!0,className:jr["sidebar-toggle-slot"]}),o&&(0,ir.jsx)("div",{className:jr["header-visual"],"aria-hidden":"true",children:o}),n&&(0,ir.jsx)(wn,{className:jr["header-title"],render:(0,ir.jsx)(c,{}),variant:"heading-lg",children:n}),t,r]}),s&&(0,ir.jsx)(vo,{align:"center",className:jr["header-actions"],direction:"row",gap:"sm",children:s})]}),i&&(0,ir.jsx)(wn,{render:(0,ir.jsx)("p",{}),variant:"body-md",className:jr["header-subtitle"],children:i}),m&&(0,ir.jsx)(Gm,{...a,linkComponent:u?.link,className:jr["header-navigation"]})]})}var fi=f(Z(),1),pc="data-wp-hash";function mc(){let e=globalThis;return e.__wpStyleRuntime||(e.__wpStyleRuntime={documents:new Map,styles:new Map,injectedStyles:new WeakMap},typeof document<"u"&&C1(document)),e.__wpStyleRuntime}function _1(e,t){if(!e.head)return!1;for(let r of e.head.querySelectorAll(`style[${pc}]`))if(r.getAttribute(pc)===t)return!0;return!1}function Qm(e,t,r){if(!e.head)return;let o=mc(),n=o.injectedStyles.get(e);if(n||(n=new Set,o.injectedStyles.set(e,n)),n.has(t))return;if(_1(e,t)){n.add(t);return}let i=e.createElement("style");i.setAttribute(pc,t),i.appendChild(e.createTextNode(r)),e.head.appendChild(i),n.add(t)}function C1(e){let t=mc();t.documents.set(e,(t.documents.get(e)??0)+1);for(let[r,o]of t.styles)Qm(e,r,o);return()=>{let r=t.documents.get(e);if(r!==void 0){if(r<=1){t.documents.delete(e);return}t.documents.set(e,r-1)}}}function R1(e,t){let r=mc();r.styles.set(e,t);for(let o of r.documents.keys())Qm(o,e,t)}typeof process>"u",R1("1f3750277d","._956b6df0898efed0__page{text-wrap:pretty;background-color:var(--wpds-color-background-surface-neutral,#fcfcfc);color:var(--wpds-color-foreground-content-neutral,#1e1e1e);display:flex;flex-flow:column;height:100%;position:relative;z-index:1}._0625b55e82a0d93d__header{background:var(--wpds-color-background-surface-neutral-strong,#fff);border-block-end:var(--wpds-border-width-xs,1px) solid var(--wpds-color-stroke-surface-neutral-weak,#f0f0f0);inset-block-start:0;padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px);position:sticky;z-index:1}.a43c44d5ae28b2e8__header-content{min-height:var(--wpds-dimension-size-md,32px)}.b7cb5b9daf3a3b25__header-actions{flex-shrink:0}._8bcd33103b451f30__header-lockup{min-width:0}._8113be94e7caf73c__header-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._9a776c7f70996f61__header-visual{display:grid;flex-shrink:0;grid-template-columns:1fr;grid-template-rows:1fr;height:var(--wpds-dimension-size-sm,24px);width:var(--wpds-dimension-size-sm,24px);>*{grid-column:1/-1;grid-row:1/-1;max-height:100%;max-width:100%}}.d5e0920cd15d35bc__sidebar-toggle-slot:empty{display:none}._60fea2f6bf5319cd__header-subtitle{color:var(--wpds-color-foreground-content-neutral-weak,#707070);padding-block-end:var(--wpds-dimension-padding-xs,4px)}._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation,._0625b55e82a0d93d__header._4b0f17e503d11619__has-navigation ._60fea2f6bf5319cd__header-subtitle{padding-block-end:0}._673c99dcbfb58211__header-navigation{margin-block-start:var(--wpds-dimension-gap-md,12px)}.be5e57d029ec4036__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;&._128806d0b26e3a50__has-padding{padding:var(--wpds-dimension-padding-lg,16px) var(--wpds-dimension-padding-2xl,24px)}}");var dc={page:"_956b6df0898efed0__page",header:"_0625b55e82a0d93d__header","header-content":"a43c44d5ae28b2e8__header-content","header-actions":"b7cb5b9daf3a3b25__header-actions","header-lockup":"_8bcd33103b451f30__header-lockup","header-title":"_8113be94e7caf73c__header-title","header-visual":"_9a776c7f70996f61__header-visual","sidebar-toggle-slot":"d5e0920cd15d35bc__sidebar-toggle-slot","header-subtitle":"_60fea2f6bf5319cd__header-subtitle","has-navigation":"_4b0f17e503d11619__has-navigation","header-navigation":"_673c99dcbfb58211__header-navigation",content:"be5e57d029ec4036__content","has-padding":"_128806d0b26e3a50__has-padding"};function $m({headingLevel:e,breadcrumbs:t,badges:r,visual:o,title:n,subTitle:i,children:s,className:a,actions:u,navigation:l,components:c,ariaLabel:m,hasPadding:d=!1,showSidebarToggle:h=!0}){let g=We(dc.page,a);return(0,fi.jsxs)(Hm,{className:g,ariaLabel:m??(typeof n=="string"?n:""),children:[(n||t||r||u||o||!!l?.items?.length)&&(0,fi.jsx)(Jm,{headingLevel:e,breadcrumbs:t,badges:r,visual:o,title:n,subTitle:i,actions:u,navigation:l,components:c,showSidebarToggle:h}),d?(0,fi.jsx)("div",{className:We(dc.content,dc["has-padding"]),children:s}):s]})}$m.SidebarToggleFill=Zm;var hc=$m;var zn=f(ge()),Av=f(ue()),Iv=f(th()),Ra=f(sr()),Lv=f(Kt()),Nv=f(Te());var Ov=f(ue(),1),kv=f(Cn(),1),xE=f(Kt(),1),SE=f(Dt(),1),Tu=f(Te(),1),_E=f(yo(),1);function Rn(e,t,r){t=Array.isArray(t)?[...t]:[t],e=Array.isArray(e)?[...e]:{...e};let o=t.pop(),n=e;for(let i of t){let s=n[i];n=n[i]=Array.isArray(s)?[...s]:{...s}}return n[o]=r,e}var ht=(e,t,r)=>{let o=Array.isArray(t)?t:t.split("."),n=e;return o.forEach(i=>{n=n?.[i]}),n??r};var E1=["appearanceTools","useRootPaddingAwareAlignments","background.backgroundImage","background.backgroundRepeat","background.backgroundSize","background.backgroundPosition","background.gradient","border.color","border.radius","border.radiusSizes","border.style","border.width","shadow.presets","shadow.defaultPresets","color.background","color.button","color.caption","color.custom","color.customDuotone","color.customGradient","color.defaultDuotone","color.defaultGradients","color.defaultPalette","color.duotone","color.gradients","color.heading","color.link","color.palette","color.text","custom","dimensions.aspectRatio","dimensions.height","dimensions.minHeight","dimensions.minWidth","dimensions.width","dimensions.dimensionSizes","layout.contentSize","layout.definitions","layout.wideSize","lightbox.enabled","lightbox.allowEditing","position.fixed","position.sticky","spacing.customSpacingSize","spacing.defaultSpacingSizes","spacing.spacingSizes","spacing.spacingScale","spacing.blockGap","spacing.margin","spacing.padding","spacing.units","typography.fluid","typography.customFontSize","typography.defaultFontSizes","typography.dropCap","typography.fontFamilies","typography.fontSizes","typography.fontStyle","typography.fontWeight","typography.letterSpacing","typography.lineHeight","typography.textAlign","typography.textColumns","typography.textDecoration","typography.textIndent","typography.textTransform","typography.writingMode","viewport.mobile","viewport.tablet"];function gc(e,t,r){let o=r?".blocks."+r:"",n=t?"."+t:"",i=`settings${o}${n}`,s=`settings${n}`;if(t)return ht(e,i)??ht(e,s);let a={};return E1.forEach(u=>{let l=ht(e,`settings${o}.${u}`)??ht(e,`settings.${u}`);l!==void 0&&(a=Rn(a,u.split("."),l))}),a}function yc(e,t,r,o){let n=o?".blocks."+o:"",i=t?"."+t:"",s=`settings${n}${i}`;return Rn(e,s.split("."),r)}var uh=f(ah(),1);var T1="1600px",P1="320px",O1=1,k1=.25,F1=.75,A1="14px";function lh({minimumFontSize:e,maximumFontSize:t,fontSize:r,minimumViewportWidth:o=P1,maximumViewportWidth:n=T1,scaleFactor:i=O1,minimumFontSizeLimit:s}){if(s=zr(s)?s:A1,r){let v=zr(r);if(!v?.unit||!v?.value)return null;let C=zr(s,{coerceTo:v.unit});if(C?.value&&!e&&!t&&v?.value<=C?.value)return null;if(t||(t=`${v.value}${v.unit}`),!e){let k=v.unit==="px"?v.value:v.value*16,E=Math.min(Math.max(1-.075*Math.log2(k),k1),F1),T=di(v.value*E,3);C?.value&&T0}function I1(e){let t=e?.typography??{},r=e?.layout,o=zr(r?.wideSize)?r?.wideSize:null;return vc(t)&&o?{fluid:{maxViewportWidth:o,...typeof t.fluid=="object"?t.fluid:{}}}:{fluid:t?.fluid}}function ch(e,t){let{size:r}=e;if(!r||r==="0"||e?.fluid===!1||!vc(t?.typography)&&!vc(e))return r;let o=I1(t)?.fluid??{},n=lh({minimumFontSize:typeof e?.fluid=="boolean"?void 0:e?.fluid?.min,maximumFontSize:typeof e?.fluid=="boolean"?void 0:e?.fluid?.max,fontSize:r,minimumFontSizeLimit:typeof o=="object"?o?.minFontSize:void 0,maximumViewportWidth:typeof o=="object"?o?.maxViewportWidth:void 0,minimumViewportWidth:typeof o=="object"?o?.minViewportWidth:void 0});return n||r}var L1=[{path:["color","palette"],valueKey:"color",cssVarInfix:"color",classes:[{classSuffix:"color",propertyName:"color"},{classSuffix:"background-color",propertyName:"background-color"},{classSuffix:"border-color",propertyName:"border-color"}]},{path:["color","gradients"],valueKey:"gradient",cssVarInfix:"gradient",classes:[{classSuffix:"gradient-background",propertyName:"background"}]},{path:["color","duotone"],valueKey:"colors",cssVarInfix:"duotone",valueFunc:({slug:e})=>`url( '#wp-duotone-${e}' )`,classes:[]},{path:["shadow","presets"],valueKey:"shadow",cssVarInfix:"shadow",classes:[]},{path:["typography","fontSizes"],valueFunc:(e,t)=>ch(e,t),valueKey:"size",cssVarInfix:"font-size",classes:[{classSuffix:"font-size",propertyName:"font-size"}]},{path:["typography","fontFamilies"],valueKey:"fontFamily",cssVarInfix:"font-family",classes:[{classSuffix:"font-family",propertyName:"font-family"}]},{path:["spacing","spacingSizes"],valueKey:"size",cssVarInfix:"spacing",valueFunc:({size:e})=>e,classes:[]},{path:["border","radiusSizes"],valueKey:"size",cssVarInfix:"border-radius",classes:[]},{path:["dimensions","dimensionSizes"],valueKey:"size",cssVarInfix:"dimension",classes:[]}];function N1(e,t){if(!e||!t)return e;if(typeof e=="object"&&"ref"in e&&e?.ref){let r=(0,uh.getCSSValueFromRawStyle)(ht(t,e.ref));return typeof r=="object"&&r!==null&&"ref"in r&&r?.ref?void 0:r===void 0?e:r}return e}function M1(e,t){if(!e||!t||!Array.isArray(t))return e;let r=t.find(o=>o?.name===e);return r?.href?r?.href:e}function bc(e,t){if(!e||!t)return e;let r=N1(e,t);return typeof r=="object"&&r!==null&&"url"in r&&r?.url?{...r,url:M1(r.url,t?._links?.["wp:theme-file"])}:r}function fh(e,t,r=[],o="slug",n){let i=[t?ht(e,["blocks",t,...r]):void 0,ht(e,r)].filter(Boolean);for(let s of i)if(s){let a=["custom","theme","default"];for(let u of a){let l=s[u];if(l){let c=l.find(m=>m[o]===n);if(c)return o==="slug"||fh(e,t,r,"slug",c.slug)[o]===c[o]?c:void 0}}}}function V1(e,t,r,[o,n]=[]){let i=L1.find(a=>a.cssVarInfix===o);if(!i||!e.settings)return r;let s=fh(e.settings,t,i.path,"slug",n);if(s){let{valueKey:a}=i,u=s[a];return Ms(e,t,u)}return r}function D1(e,t,r,o=[]){let n=(t?ht(e?.settings??{},["blocks",t,"custom",...o]):void 0)??ht(e?.settings??{},["custom",...o]);return n?Ms(e,t,n):r}function Ms(e,t,r){if(!r||typeof r!="string")if(typeof r=="object"&&r!==null&&"ref"in r&&typeof r.ref=="string"){let l=ht(e,r.ref);if(!l||typeof l=="object"&&"ref"in l)return l;r=l}else return r;let o="var:",n="var(--wp--",i=")",s;if(r.startsWith(o))s=r.slice(o.length).split("|");else if(r.startsWith(n)&&r.endsWith(i))s=r.slice(n.length,-i.length).split("--");else return r;let[a,...u]=s;return a==="preset"?V1(e,t,r,u):a==="custom"?D1(e,t,r,u):r}function Vs(e,t,r,o=!0){let n=t?"."+t:"",i=r?`styles.blocks.${r}${n}`:`styles${n}`;if(!e)return;let s=ht(e,i),a=void 0;if(s===void 0&&a){let l=!0,c=e;for(let m of i.split(".")){if(!c||typeof c!="object"||!Object.hasOwn(c,m)){l=!1;break}c=c[m]}l||(s=ht(e,a))}return o?Ms(e,r,s):s}function wc(e,t,r,o){let n=t?"."+t:"",i=o?`styles.blocks.${o}${n}`:`styles${n}`;return Rn(e,i.split("."),r)}var xc=f(ph(),1);function pi(e,t){return typeof e!="object"||typeof t!="object"?e===t:(0,xc.default)(e?.styles,t?.styles)&&(0,xc.default)(e?.settings,t?.settings)}var wh=f(yh(),1);function vh(e){return Object.prototype.toString.call(e)==="[object Object]"}function bh(e){var t,r;return vh(e)===!1?!1:(t=e.constructor,t===void 0?!0:(r=t.prototype,!(vh(r)===!1||r.hasOwnProperty("isPrototypeOf")===!1)))}function Go(e,t){return(0,wh.default)(e,t,{isMergeableObject:bh,customMerge:r=>{if(r==="backgroundImage")return(o,n)=>n??o}})}var Q1={grad:.9,turn:360,rad:360/(2*Math.PI)},Jr=function(e){return typeof e=="string"?e.length>0:typeof e=="number"},bt=function(e,t,r){return t===void 0&&(t=0),r===void 0&&(r=Math.pow(10,t)),Math.round(r*e)/r+0},fr=function(e,t,r){return t===void 0&&(t=0),r===void 0&&(r=1),e>r?r:e>t?e:t},Oh=function(e){return(e=isFinite(e)?e%360:0)>0?e:e+360},xh=function(e){return{r:fr(e.r,0,255),g:fr(e.g,0,255),b:fr(e.b,0,255),a:fr(e.a)}},Sc=function(e){return{r:bt(e.r),g:bt(e.g),b:bt(e.b),a:bt(e.a,3)}},$1=/^#([0-9a-f]{3,8})$/i,Ds=function(e){var t=e.toString(16);return t.length<2?"0"+t:t},kh=function(e){var t=e.r,r=e.g,o=e.b,n=e.a,i=Math.max(t,r,o),s=i-Math.min(t,r,o),a=s?i===t?(r-o)/s:i===r?2+(o-t)/s:4+(t-r)/s:0;return{h:60*(a<0?a+6:a),s:i?s/i*100:0,v:i/255*100,a:n}},Fh=function(e){var t=e.h,r=e.s,o=e.v,n=e.a;t=t/360*6,r/=100,o/=100;var i=Math.floor(t),s=o*(1-r),a=o*(1-(t-i)*r),u=o*(1-(1-t+i)*r),l=i%6;return{r:255*[o,a,s,s,u,o][l],g:255*[u,o,o,a,s,s][l],b:255*[s,s,u,o,o,a][l],a:n}},Sh=function(e){return{h:Oh(e.h),s:fr(e.s,0,100),l:fr(e.l,0,100),a:fr(e.a)}},_h=function(e){return{h:bt(e.h),s:bt(e.s),l:bt(e.l),a:bt(e.a,3)}},Ch=function(e){return Fh((r=(t=e).s,{h:t.h,s:(r*=((o=t.l)<50?o:100-o)/100)>0?2*r/(o+r)*100:0,v:o+r,a:t.a}));var t,r,o},hi=function(e){return{h:(t=kh(e)).h,s:(n=(200-(r=t.s))*(o=t.v)/100)>0&&n<200?r*o/100/(n<=100?n:200-n)*100:0,l:n/2,a:t.a};var t,r,o,n},ex=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s*,\s*([+-]?\d*\.?\d+)%\s*,\s*([+-]?\d*\.?\d+)%\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,tx=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s+([+-]?\d*\.?\d+)%\s+([+-]?\d*\.?\d+)%\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,rx=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,ox=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,Rh={string:[[function(e){var t=$1.exec(e);return t?(e=t[1]).length<=4?{r:parseInt(e[0]+e[0],16),g:parseInt(e[1]+e[1],16),b:parseInt(e[2]+e[2],16),a:e.length===4?bt(parseInt(e[3]+e[3],16)/255,2):1}:e.length===6||e.length===8?{r:parseInt(e.substr(0,2),16),g:parseInt(e.substr(2,2),16),b:parseInt(e.substr(4,2),16),a:e.length===8?bt(parseInt(e.substr(6,2),16)/255,2):1}:null:null},"hex"],[function(e){var t=rx.exec(e)||ox.exec(e);return t?t[2]!==t[4]||t[4]!==t[6]?null:xh({r:Number(t[1])/(t[2]?100/255:1),g:Number(t[3])/(t[4]?100/255:1),b:Number(t[5])/(t[6]?100/255:1),a:t[7]===void 0?1:Number(t[7])/(t[8]?100:1)}):null},"rgb"],[function(e){var t=ex.exec(e)||tx.exec(e);if(!t)return null;var r,o,n=Sh({h:(r=t[1],o=t[2],o===void 0&&(o="deg"),Number(r)*(Q1[o]||1)),s:Number(t[3]),l:Number(t[4]),a:t[5]===void 0?1:Number(t[5])/(t[6]?100:1)});return Ch(n)},"hsl"]],object:[[function(e){var t=e.r,r=e.g,o=e.b,n=e.a,i=n===void 0?1:n;return Jr(t)&&Jr(r)&&Jr(o)?xh({r:Number(t),g:Number(r),b:Number(o),a:Number(i)}):null},"rgb"],[function(e){var t=e.h,r=e.s,o=e.l,n=e.a,i=n===void 0?1:n;if(!Jr(t)||!Jr(r)||!Jr(o))return null;var s=Sh({h:Number(t),s:Number(r),l:Number(o),a:Number(i)});return Ch(s)},"hsl"],[function(e){var t=e.h,r=e.s,o=e.v,n=e.a,i=n===void 0?1:n;if(!Jr(t)||!Jr(r)||!Jr(o))return null;var s=(function(a){return{h:Oh(a.h),s:fr(a.s,0,100),v:fr(a.v,0,100),a:fr(a.a)}})({h:Number(t),s:Number(r),v:Number(o),a:Number(i)});return Fh(s)},"hsv"]]},Eh=function(e,t){for(var r=0;r=.5},e.prototype.toHex=function(){return t=Sc(this.rgba),r=t.r,o=t.g,n=t.b,s=(i=t.a)<1?Ds(bt(255*i)):"","#"+Ds(r)+Ds(o)+Ds(n)+s;var t,r,o,n,i,s},e.prototype.toRgb=function(){return Sc(this.rgba)},e.prototype.toRgbString=function(){return t=Sc(this.rgba),r=t.r,o=t.g,n=t.b,(i=t.a)<1?"rgba("+r+", "+o+", "+n+", "+i+")":"rgb("+r+", "+o+", "+n+")";var t,r,o,n,i},e.prototype.toHsl=function(){return _h(hi(this.rgba))},e.prototype.toHslString=function(){return t=_h(hi(this.rgba)),r=t.h,o=t.s,n=t.l,(i=t.a)<1?"hsla("+r+", "+o+"%, "+n+"%, "+i+")":"hsl("+r+", "+o+"%, "+n+"%)";var t,r,o,n,i},e.prototype.toHsv=function(){return t=kh(this.rgba),{h:bt(t.h),s:bt(t.s),v:bt(t.v),a:bt(t.a,3)};var t},e.prototype.invert=function(){return Cr({r:255-(t=this.rgba).r,g:255-t.g,b:255-t.b,a:t.a});var t},e.prototype.saturate=function(t){return t===void 0&&(t=.1),Cr(_c(this.rgba,t))},e.prototype.desaturate=function(t){return t===void 0&&(t=.1),Cr(_c(this.rgba,-t))},e.prototype.grayscale=function(){return Cr(_c(this.rgba,-1))},e.prototype.lighten=function(t){return t===void 0&&(t=.1),Cr(Th(this.rgba,t))},e.prototype.darken=function(t){return t===void 0&&(t=.1),Cr(Th(this.rgba,-t))},e.prototype.rotate=function(t){return t===void 0&&(t=15),this.hue(this.hue()+t)},e.prototype.alpha=function(t){return typeof t=="number"?Cr({r:(r=this.rgba).r,g:r.g,b:r.b,a:t}):bt(this.rgba.a,3);var r},e.prototype.hue=function(t){var r=hi(this.rgba);return typeof t=="number"?Cr({h:t,s:r.s,l:r.l,a:r.a}):bt(r.h)},e.prototype.isEqual=function(t){return this.toHex()===Cr(t).toHex()},e})(),Cr=function(e){return e instanceof Ph?e:new Ph(e)};function ix(e=[]){let t={r:[],g:[],b:[],a:[]};return e.forEach(r=>{let o=Cr(r).toRgb();t.r.push(o.r/255),t.g.push(o.g/255),t.b.push(o.b/255),t.a.push(o.a)}),t}function Ah(e){return`${e}{filter:none}`}function Ih(e,t){return`${e}{filter:url(#${t})}`}function Lh(e,t){let r=ix(t);return` -`}var zh={mobile:"480px",tablet:"782px"},Hh=/^(\d+|\d*\.\d+)(px|em|rem)$/,fx=16;function dx(e){return"mobile"in e||"tablet"in e}function px(e){return!e||typeof e!="object"?{}:dx(e)?e:e.settings?.viewport??{}}function mx(e){return typeof e=="string"&&Hh.test(e.trim())}function Tc(e){if(typeof e=="number")return e;if(typeof e!="string")return;let t=e.trim().match(Hh);if(!t)return;let r=Number.parseFloat(t[1]);return t[2]==="px"?r:r*fx}function Pc(e){let t=px(e),r={},o={};Object.keys(zh).forEach(a=>{let u=a,l=t[u],c=Tc(l);c!==void 0&&mx(l)&&(r[u]=l.trim(),o[u]=c)});let n=Object.keys(r);if(!n.length)return{...zh};if(n.length===1)return r;let i=r.mobile,s=r.tablet;return o.mobile>=o.tablet?{mobile:i}:{mobile:i,tablet:s}}function Uh(e){let t=Pc(e),r={};return t.mobile&&(r["@mobile"]=`@media (width <= ${t.mobile})`),t.tablet&&(r["@tablet"]=t.mobile?`@media (${t.mobile} < width <= ${t.tablet})`:`@media (width <= ${t.tablet})`),r}function Bs(e,t,r,{resolveRefs:o=!0}={}){if(!e?.styles?.blocks?.[t]?.variations?.[r])return;let n=s=>{Object.keys(s).forEach(a=>{let u=s[a];if(typeof u=="object"&&u!==null)if(u.ref!==void 0)if(typeof u.ref!="string"||u.ref.trim()==="")delete s[a];else{let l=ht(e,u.ref);l!=null?s[a]=l:delete s[a]}else n(u),Object.keys(u).length===0&&delete s[a]})},i=JSON.parse(JSON.stringify(e.styles.blocks[t].variations[r]));return o&&n(i),i}var Fc="default";function qh(e){let t=e?.viewport,r=e?.pseudoState;return(!t||t===Fc)&&(!r||r===Fc)}function hx(e){return qh(e)?[]:[e.viewport,e.pseudoState].filter(t=>!!t&&t!==Fc)}function gx(e,t){let r=hx(t);return r.length?ht(e,r):e}var yx=new Set(["blocks","variations","css"]),Oc=Object.freeze({value:{},sources:{}}),vx={root:{layer:"root"},element:{layer:"element"},block:{layer:"block"},blockVariation:{layer:"blockVariation"}};function wo(e){let t=vx[e];return t?{...t}:null}function xo(e,t){return!e||!t?null:{styles:e,source:t}}function bx(e){return e.join(".")}function wx(e){return{...e}}function Zh(e){return e===""||e===null||typeof e=="object"&&!Array.isArray(e)&&Object.keys(e).length===0}function kc(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)&&typeof e.ref=="string"}function So(e){if(!e||typeof e!="object"||Array.isArray(e))return null;let t={};for(let r of Object.keys(e))if(!yx.has(r)){if(r==="elements"){e.elements&&typeof e.elements=="object"&&(t.elements=e.elements);continue}Zh(e[r])||(t[r]=e[r])}return Object.keys(t).length===0?null:t}var Wh=new Set(["backgroundImage"]);function Xh(e,t,r,o,n,i=[]){if(!t||typeof t!="object"||Array.isArray(t))return e;for(let s of Object.keys(t)){let a=t[s];if(Zh(a))continue;if(kc(a)){if(a.ref.trim()==="")continue;let l=ht(r,a.ref);if(l==null||kc(l))continue;a=l}let u=[...i,s];if(!Wh.has(s)&&a!==null&&typeof a=="object"&&!Array.isArray(a)&&!kc(a)){let l=e[s]&&typeof e[s]=="object"&&!Array.isArray(e[s])?e[s]:{};e[s]=Xh({...l},a,r,o,n,u)}else e[s]=Wh.has(s)&&a!==null&&typeof a=="object"&&!Array.isArray(a)?{...a}:a,o&&n&&(n[bx(u)]=wx(o))}return e}function js(e,t){if(!e)return null;let r=gx(e,t);return r&&typeof r=="object"&&!Array.isArray(r)?r:null}var xx=["color.background","color.gradient","background","spacing","dimensions","border","shadow","filter"];function Sx(e){return e.startsWith("elements.")?!1:xx.some(t=>e===t||e.startsWith(`${t}.`))}function Kh(e,t){if(!e||typeof e!="object")return;let[r,...o]=t;if(o.length===0){delete e[r];return}let n=e[r];n&&typeof n=="object"&&(Kh(n,o),Object.keys(n).length===0&&delete e[r])}function Cx(e,t){for(let r of Object.keys(t))t[r].layer==="root"&&Sx(r)&&(Kh(e,r.split(".")),delete t[r])}function _x(e,t,r){let o=e?.background?.backgroundImage;if(!o)return;let n=gh(o,{...t,_links:r??void 0});n!==void 0&&(e.background.backgroundImage=n)}function Gh(e,{blockName:t,variationName:r=null,elements:o=null,viewport:n=null,pseudoState:i=null}={}){if(!e||!e.styles||!t)return Oc;let s=e.styles,a={viewport:n,pseudoState:i},u=s,l=s.blocks?.[t]??null,c=(o??[]).map(w=>s.elements?.[w]??null).filter(w=>!!w),m=r?Bs(e,t,r)??null:null,d=[xo(So(u),wo("root")),...c.map(w=>xo(So(w),wo("element"))),l?xo(So(l),wo("block")):null,m?xo(So(m),wo("blockVariation")):null];qh(a)||d.push(xo(So(js(u,a)),wo("root")),...c.map(w=>xo(So(js(w,a)),wo("element"))),l?xo(So(js(l,a)),wo("block")):null,m?xo(So(js(m,a)),wo("blockVariation")):null);let h=d.filter(Boolean);if(h.length===0)return Oc;let g={},b=h.reduce((w,C)=>Xh(w,C.styles,e,C.source,g),{});return Cx(b,g),_x(b,e,e._links??null),{value:b,sources:g}}var Rx={},Yh=new WeakMap;function Jh(e,t={}){let r=e?.styles;if(!r||typeof r!="object")return Gh(e,t);let o=Yh.get(r);o||(o=new WeakMap,Yh.set(r,o));let n=e?._links??Rx,i=o.get(n);i||(i=new Map,o.set(n,i));let s=`${t.elements?.join(",")??""}:${t.viewport??""}:${t.pseudoState??""}`,a=(t.blockName||"")+""+(t.variationName||"")+""+s;if(i.has(a))return i.get(a);let u=Gh(e,t);return i.set(a,u),u}var Qh=f(li(),1),{lock:$h,unlock:vI}=(0,Qh.__dangerousOptInToUnstableAPIsOnlyForCoreModules)("I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.","@wordpress/global-styles-engine");var Tn={};$h(Tn,{getResponsiveMediaQueries:Uh,getViewportBreakpoints:Pc,getViewportBreakpointValueInPixels:Tc,getDuotoneFilter:jh,getDuotoneStylesheet:Bh,getDuotoneUnsetStylesheet:Dh,resolveStyle:Jh,getVariationStyle:Bs});var Ac=f(Te(),1);var eg=f(Te(),1),gt=(0,eg.createContext)({user:{styles:{},settings:{}},base:{styles:{},settings:{}},merged:{styles:{},settings:{}},onChange:()=>{},fontLibraryEnabled:!1});var tg=f(Z(),1);function gi({children:e,value:t,baseValue:r,onChange:o,fontLibraryEnabled:n}){let i=(0,Ac.useMemo)(()=>Go(r,t),[r,t]),s=(0,Ac.useMemo)(()=>({user:t,base:r,merged:i,onChange:o,fontLibraryEnabled:n}),[t,r,i,o,n]);return(0,tg.jsx)(gt.Provider,{value:s,children:e})}var eo=f(ue(),1),bg=f(ge(),1);var Bx=f(Kt(),1),jx=f(sr(),1);var rg=f(Z(),1);function Ic({className:e,...t}){return(0,rg.jsx)(ai,{className:We(e,"global-styles-ui-icon-with-current-color"),...t})}var Co=f(ue(),1);var Yo=f(Z(),1);function Ex({icon:e,children:t,...r}){return(0,Yo.jsxs)(Co.__experimentalItem,{...r,children:[e&&(0,Yo.jsxs)(Co.__experimentalHStack,{justify:"flex-start",children:[(0,Yo.jsx)(Ic,{icon:e,size:24}),(0,Yo.jsx)(Co.FlexItem,{children:t})]}),!e&&t]})}function Qr(e){return(0,Yo.jsx)(Co.Navigator.Button,{as:Ex,...e})}var Ox=f(ue(),1);var kx=f(ge(),1),cg=f(Dt(),1);var Lc=function(e){var t=e/255;return t<.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)},Nc=function(e){return .2126*Lc(e.r)+.7152*Lc(e.g)+.0722*Lc(e.b)};function og(e){e.prototype.luminance=function(){return t=Nc(this.rgba),(r=2)===void 0&&(r=0),o===void 0&&(o=Math.pow(10,r)),Math.round(o*t)/o+0;var t,r,o},e.prototype.contrast=function(t){t===void 0&&(t="#FFF");var r,o,n,i,s,a,u,l=t instanceof e?t:new e(t);return i=this.rgba,s=l.toRgb(),a=Nc(i),u=Nc(s),r=a>u?(a+.05)/(u+.05):(u+.05)/(a+.05),(o=2)===void 0&&(o=0),n===void 0&&(n=Math.pow(10,o)),Math.floor(n*r)/n+0},e.prototype.isReadable=function(t,r){return t===void 0&&(t="#FFF"),r===void 0&&(r={}),this.contrast(t)>=(a=(s=(o=r).size)===void 0?"normal":s,(i=(n=o.level)===void 0?"AA":n)==="AAA"&&a==="normal"?7:i==="AA"&&a==="large"?3:4.5);var o,n,i,s,a}}var Rr=f(Te(),1),ag=f(Kt(),1),lg=f(sr(),1),Vc=f(ge(),1);var dt=f(ge(),1);var ng=f(li(),1),{lock:WI,unlock:Ve}=(0,ng.__dangerousOptInToUnstableAPIsOnlyForCoreModules)("I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.","@wordpress/global-styles-ui");var{getViewportBreakpoints:ZI}=Ve(Tn),XI={link:[{value:":link",label:(0,dt.__)("Link")},{value:":any-link",label:(0,dt.__)("Any Link")},{value:":visited",label:(0,dt.__)("Visited")},{value:":hover",label:(0,dt.__)("Hover")},{value:":focus",label:(0,dt.__)("Focus")},{value:":focus-visible",label:(0,dt.__)("Focus-visible")},{value:":active",label:(0,dt.__)("Active")}],button:[{value:":link",label:(0,dt.__)("Link")},{value:":any-link",label:(0,dt.__)("Any Link")},{value:":visited",label:(0,dt.__)("Visited")},{value:":hover",label:(0,dt.__)("Hover")},{value:":focus",label:(0,dt.__)("Focus")},{value:":focus-visible",label:(0,dt.__)("Focus-visible")},{value:":active",label:(0,dt.__)("Active")}]},KI={"core/button":[{value:":hover",label:(0,dt.__)("Hover")},{value:":focus",label:(0,dt.__)("Focus")},{value:":focus-visible",label:(0,dt.__)("Focus-visible")},{value:":active",label:(0,dt.__)("Active")}]},JI=[{value:"@tablet",label:(0,dt.__)("Tablet")},{value:"@mobile",label:(0,dt.__)("Mobile")}];function Mc(e,t){if(!t?.length||typeof e!="object"||!e||!Object.keys(e).length)return e;for(let r in e)t.includes(r)?delete e[r]:typeof e[r]=="object"&&Mc(e[r],t);return e}var zs=(e,t)=>{if(!e||!t?.length)return{};let r={};return Object.keys(e).forEach(o=>{if(t.includes(o))r[o]=e[o];else if(typeof e[o]=="object"){let n=zs(e[o],t);Object.keys(n).length&&(r[o]=n)}}),r};function yi(e,t){let r=zs(structuredClone(e),t);return pi(r,e)}function ig(e,t){if(!Array.isArray(e)||!t)return null;let o=t.replace("var(","").replace(")","")?.split("--").slice(-1)[0];return e.find(n=>n.slug===o)}function sg(e){let t=e?.settings?.typography?.fontFamilies?.theme,r=e?.settings?.typography?.fontFamilies?.custom,o=[];t&&r?o=[...t,...r]:t?o=t:r&&(o=r);let n=e?.styles?.typography?.fontFamily,i=ig(o,n),s=e?.styles?.elements?.heading?.typography?.fontFamily,a;return s?a=ig(o,e?.styles?.elements?.heading?.typography?.fontFamily):a=i,[i,a]}Vh([og]);function qe(e,t,r="merged",o=!0,n){let{user:i,base:s,merged:a,onChange:u}=(0,Rr.useContext)(gt),l=n?.split(".").filter(Boolean)??[],c=l.find(w=>w.startsWith(":")),m=l.filter(w=>!w.startsWith(":")).join("."),d=[e,m].filter(Boolean).join("."),h=a;r==="base"?h=s:r==="user"&&(h=i);let g=(0,Rr.useMemo)(()=>{let w=Vs(h,d,t,o);return c?w?.[c]??{}:w},[h,d,t,o,c]),b=(0,Rr.useCallback)(w=>{let C=w;c&&(C={...Vs(i,d,t,!1),[c]:w});let x=wc(i,d,C,t);u(x)},[i,u,d,t,c]);return[g,b]}function Ke(e,t,r="merged"){let{user:o,base:n,merged:i,onChange:s}=(0,Rr.useContext)(gt),a=i;r==="base"?a=n:r==="user"&&(a=o);let u=(0,Rr.useMemo)(()=>yc(a,e,t),[a,e,t]),l=(0,Rr.useCallback)(c=>{let m=vc(o,e,c,t);s(m)},[o,s,e,t]);return[u,l]}var Tx=[];function Px({title:e,settings:t,styles:r}){return e===(0,Vc.__)("Default")||Object.keys(t||{}).length>0||Object.keys(r||{}).length>0}function Hs(e=[]){let{variationsFromTheme:t}=(0,ag.useSelect)(o=>({variationsFromTheme:o(lg.store).__experimentalGetCurrentThemeGlobalStylesVariations?.()||Tx}),[]),{user:r}=(0,Rr.useContext)(gt);return(0,Rr.useMemo)(()=>{let o=structuredClone(r),n=Mc(o,e);n.title=(0,Vc.__)("Default");let i=t.filter(a=>yi(a,e)).map(a=>Go(n,a)),s=[n,...i];return s?.length?s.filter(Px):[]},[e,r,t])}var Dc=f(Z(),1),{useHasDimensionsPanel:lL,useHasTypographyPanel:cL,useHasColorPanel:uL,useSettingsForBlockElement:fL,useHasBackgroundPanel:dL}=Ve(cg.privateApis);var zr=f(ue(),1);function Pn(){let[e="black"]=qe("color.text"),[t="white"]=qe("color.background"),[r=e]=qe("elements.h1.color.text"),[o=r]=qe("elements.link.color.text"),[n=o]=qe("elements.button.color.background"),[i]=Ke("color.palette.core")||[],[s]=Ke("color.palette.theme")||[],[a]=Ke("color.palette.custom")||[],u=(s??[]).concat(a??[]).concat(i??[]),l=u.filter(({color:d})=>d===e),c=u.filter(({color:d})=>d===n),m=l.concat(c).concat(u).filter(({color:d})=>d!==t).slice(0,2);return{paletteColors:u,highlightedColors:m}}var pg=f(Te(),1),mg=f(ue(),1),zc=f(ge(),1);function Fx(e,t){return t.length===0?null:(t.sort((r,o)=>Math.abs(e-r)-Math.abs(e-o)),t[0])}var Ax={normal:400,bold:700};function ug(e){return e!==void 0&&Number.isFinite(e)&&e>=1&&e<=1e3}function Bc(e){let t=String(e??"").trim().toLowerCase().split(/\s+/).filter(Boolean).map(n=>Ax[n]??Number(n)),[r,o]=t;return ug(r)?t.length!==2||!ug(o)?String(r):String(Math.min(Math.max(400,r),o)):"400"}function fg(e){let t=/^(?!generic\([ a-zA-Z\-]+\)$)(?!^[a-zA-Z\-]+$).+/,r=e.trim(),o=n=>(n=n.trim(),n.match(t)?(n=n.replace(/^["']|["']$/g,""),`"${n}"`):n);return r.includes(",")?r.split(",").map(o).filter(n=>n!=="").join(", "):o(r)}function jc(e){if(!e)return"";let t=e.trim();return t.includes(",")&&(t=(t.split(",").find(r=>r.trim()!=="")??"").trim()),t=t.replace(/^["']|["']$/g,""),window.navigator.userAgent.toLowerCase().includes("firefox")&&(t=`"${t}"`),t}function On(e){let t={fontFamily:fg(e.fontFamily)};if(!("fontFace"in e)||!Array.isArray(e.fontFace))return t.fontWeight="400",t.fontStyle="normal",t;if(e.fontFace){let r=e.fontFace.filter(o=>o?.fontStyle&&o.fontStyle.toLowerCase()==="normal");if(r.length>0){t.fontStyle="normal";let o=r.map(n=>Number(Bc(n.fontWeight)));t.fontWeight=String(Fx(400,o)??400)}else t.fontStyle=e.fontFace.length&&e.fontFace[0].fontStyle||"normal",t.fontWeight=e.fontFace.length&&Bc(e.fontFace[0].fontWeight)||"400"}return t}function dg(e){return{fontFamily:fg(e.fontFamily),fontStyle:e.fontStyle||"normal",fontWeight:Bc(e.fontWeight)}}var vi=f(Z(),1);function Us({fontSize:e,variation:t}){let{base:r}=(0,pg.useContext)(gt),o=r;t&&(o={...r,...t});let[n]=qe("color.text"),[i,s]=sg(o),a=i?On(i):{},u=s?On(s):{};return n&&(a.color=n,u.color=n),e&&(a.fontSize=e,u.fontSize=e),(0,vi.jsxs)(mg.__unstableMotion.div,{animate:{scale:1,opacity:1},initial:{scale:.1,opacity:0},transition:{delay:.3,type:"tween"},style:{textAlign:"center",lineHeight:1},children:[(0,vi.jsx)("span",{style:u,children:(0,zc._x)("A","Uppercase letter A")}),(0,vi.jsx)("span",{style:a,children:(0,zc._x)("a","Lowercase letter A")})]})}var hg=f(ue(),1);var gg=f(Z(),1);function yg({normalizedColorSwatchSize:e,ratio:t}){let{highlightedColors:r}=Pn(),o=e*t;return r.map(({slug:n,color:i},s)=>(0,gg.jsx)(hg.__unstableMotion.div,{style:{height:o,width:o,background:i,borderRadius:o/2},animate:{scale:1,opacity:1},initial:{scale:.1,opacity:0},transition:{delay:s===1?.2:.1}},`${n}-${s}`))}var vg=f(ue(),1),kn=f(yo(),1),qo=f(Te(),1);var $r=f(Z(),1),Hc=248,Uc=152,Ix={leading:!0,trailing:!0};function Lx({children:e,label:t,isFocused:r,withHoverView:o}){let[n="white"]=qe("color.background"),[i]=qe("color.gradient"),s=(0,kn.useReducedMotion)(),[a,u]=(0,qo.useState)(!1),[l,{width:c}]=(0,kn.useResizeObserver)(),[m,d]=(0,qo.useState)(c),[h,g]=(0,qo.useState)(),b=(0,kn.useThrottle)(d,250,Ix);(0,qo.useLayoutEffect)(()=>{c&&b(c)},[c,b]),(0,qo.useLayoutEffect)(()=>{let v=m?m/Hc:1,_=v-(h||0);(Math.abs(_)>.1||!h)&&g(v)},[m,h]);let w=c?c/Hc:1,C=h||w,x=!!c;return(0,$r.jsxs)($r.Fragment,{children:[(0,$r.jsx)("div",{style:{position:"relative"},children:l}),!x&&(0,$r.jsx)(ui,{className:"global-styles-ui-preview__wrapper",style:{aspectRatio:Hc/Uc}}),x&&(0,$r.jsx)("div",{className:We("global-styles-ui-preview__wrapper",{"is-hoverable":o}),style:{height:Uc*C},onMouseEnter:()=>u(!0),onMouseLeave:()=>u(!1),tabIndex:-1,children:(0,$r.jsx)(vg.__unstableMotion.div,{style:{height:Uc*C,width:"100%",background:i??n},initial:"start",animate:(a||r)&&!s&&t?"hover":"start",children:[].concat(e).map((v,_)=>v({ratio:C,key:_}))})})]})}var Fn=Lx;var Jt=f(Z(),1),Nx={start:{scale:1,opacity:1},hover:{scale:0,opacity:0}},Mx={hover:{opacity:1},start:{opacity:.5}},Vx={hover:{scale:1,opacity:1},start:{scale:0,opacity:0}};function Dx({label:e,isFocused:t,withHoverView:r,variation:o}){let[n]=qe("typography.fontWeight"),[i="serif"]=qe("typography.fontFamily"),[s=i]=qe("elements.h1.typography.fontFamily"),[a=n]=qe("elements.h1.typography.fontWeight"),[u="black"]=qe("color.text"),[l=u]=qe("elements.h1.color.text"),{paletteColors:c}=Pn();return(0,Jt.jsxs)(Fn,{label:e,isFocused:t,withHoverView:r,children:[({ratio:m,key:d})=>(0,Jt.jsx)(zr.__unstableMotion.div,{variants:Nx,style:{height:"100%",overflow:"hidden"},children:(0,Jt.jsxs)(zr.__experimentalHStack,{spacing:10*m,justify:"center",style:{height:"100%",overflow:"hidden"},children:[(0,Jt.jsx)(Us,{fontSize:65*m,variation:o}),(0,Jt.jsx)(zr.__experimentalVStack,{spacing:4*m,children:(0,Jt.jsx)(yg,{normalizedColorSwatchSize:32,ratio:m})})]})},d),({key:m})=>(0,Jt.jsx)(zr.__unstableMotion.div,{variants:r?Mx:void 0,style:{height:"100%",width:"100%",position:"absolute",top:0,overflow:"hidden",filter:"blur(60px)",opacity:.1},children:(0,Jt.jsx)(zr.__experimentalHStack,{spacing:0,justify:"flex-start",style:{height:"100%",overflow:"hidden"},children:c.slice(0,4).map(({color:d},h)=>(0,Jt.jsx)("div",{style:{height:"100%",background:d,flexGrow:1}},h))})},m),({ratio:m,key:d})=>(0,Jt.jsx)(zr.__unstableMotion.div,{variants:Vx,style:{height:"100%",width:"100%",overflow:"hidden",position:"absolute",top:0},children:(0,Jt.jsx)(zr.__experimentalVStack,{spacing:3*m,justify:"center",style:{height:"100%",overflow:"hidden",padding:10*m,boxSizing:"border-box"},children:e&&(0,Jt.jsx)("div",{style:{fontSize:40*m,fontFamily:s,color:l,fontWeight:a,lineHeight:"1em",textAlign:"center"},children:e})})},d)]})}var Wc=Dx;var wg=f(Z(),1);var qc=f(_n(),1),Ro=f(ge(),1),Hr=f(ue(),1);var Zc=f(Kt(),1),pr=f(Te(),1),Ws=f(Dt(),1),Eg=f(yo(),1);import{speak as Wx}from"@wordpress/a11y";var xg=f(_n(),1),Sg=f(Kt(),1),zx=f(ue(),1);var Hx=f(Z(),1);function Ux(e,t){return e?.filter(r=>r.source==="block"||t.includes(r.name))||[]}function Gc(e){let t=(0,Sg.useSelect)(n=>{let{getBlockStyles:i}=n(xg.store);return i(e)},[e]),[r]=qe("variations",e),o=Object.keys(r??{});return Ux(t,o)}var _o=f(ue(),1),Cg=f(ge(),1);var _g=f(Dt(),1);var Rg=f(Z(),1),{StateControl:WL,StateControlBadges:GL}=Ve(_g.privateApis);var Bt=f(Z(),1),{useHasDimensionsPanel:Gx,useHasTypographyPanel:Yx,useHasBorderPanel:qx,useSettingsForBlockElement:Zx,useHasColorPanel:Xx,useHasBackgroundPanel:Kx}=Ve(Ws.privateApis),{Menu:tN}=Ve(Hr.privateApis);function Yc(e){return e==null?!1:Array.isArray(e)?e.length>0:typeof e=="object"?Object.values(e).some(Yc):!0}function Jx(e,t){return Yc(e?.styles?.blocks?.[t])||Yc(e?.settings?.blocks?.[t])}function Qx(){let e=(0,Zc.useSelect)(n=>n(qc.store).getBlockTypes(),[]),t=(n,i)=>{let{core:s,noncore:a}=n;return(i.name.startsWith("core/")?s:a).push(i),n},{core:r,noncore:o}=e.reduce(t,{core:[],noncore:[]});return[...r,...o]}function $x(e){let[t]=Ke("",e),r=Zx(t,e),o=Yx(r),n=Xx(r),i=Kx(r),s=qx(r),a=Gx(r),u=s||a,l=!!Gc(e)?.length;return o||n||i||u||l}function eS({block:e,isCustomized:t}){return $x(e.name)?(0,Bt.jsx)(Qr,{path:"/blocks/"+encodeURIComponent(e.name),children:(0,Bt.jsxs)(Hr.__experimentalHStack,{justify:"flex-start",spacing:2,children:[(0,Bt.jsx)(Ws.BlockIcon,{className:"global-styles-ui-block-types-item__icon",icon:e.icon}),(0,Bt.jsx)(Hr.FlexItem,{children:e.title}),t&&(0,Bt.jsxs)(Bt.Fragment,{children:[(0,Bt.jsx)(ec,{children:(0,Ro.__)("Has custom styles")}),(0,Bt.jsx)("span",{"aria-hidden":"true",className:"global-styles-ui-block-types-item__indicator"})]})]})}):null}function tS({filterValue:e,styleFilter:t}){let r=t==="customized"&&!e?(0,Ro.__)("You haven't customized any blocks yet."):(0,Ro.__)("No blocks found.");return(0,Bt.jsx)(Hr.__experimentalText,{align:"center",as:"p",className:"global-styles-ui-block-types-item-list__no-results",children:r})}function rS({filterValue:e,styleFilter:t}){let r=Qx(),o=(0,Eg.useDebounce)(Wx,500),{isMatchingSearchTerm:n}=(0,Zc.useSelect)(qc.store),{user:i}=(0,pr.useContext)(gt),s=(0,pr.useMemo)(()=>{let m=new Set;return[...Object.keys(i?.styles?.blocks??{}),...Object.keys(i?.settings?.blocks??{})].forEach(h=>{Jx(i,h)&&m.add(h)}),m},[i]),a=e?r.filter(m=>n(m,e)):r,u=t==="customized"?a.filter(m=>s.has(m.name)):a,l=(0,pr.useRef)(null),c=u.length>0;return(0,pr.useEffect)(()=>{if(!e&&t==="all")return;let m=c&&l.current?.childElementCount||0,d=(0,Ro.sprintf)((0,Ro._n)("%d result found.","%d results found.",m),m);o(d,"polite")},[e,t,c,o]),(0,Bt.jsx)("div",{ref:l,className:"global-styles-ui-block-types-item-list",role:"list",children:u.length===0?(0,Bt.jsx)(tS,{filterValue:e,styleFilter:t}):u.map(m=>(0,Bt.jsx)(eS,{block:m,isCustomized:s.has(m.name)},"menu-itemblock-"+m.name))})}var rN=(0,pr.memo)(rS);var aS=f(_n(),1),kg=f(Dt(),1),Xc=f(Te(),1),lS=f(Kt(),1),cS=f(sr(),1),Kc=f(ue(),1),Fg=f(ge(),1);var oS=f(Dt(),1),Tg=f(_n(),1),nS=f(ue(),1),iS=f(Te(),1);var sS=f(Z(),1),{getViewportBreakpoints:cN,getViewportBreakpointValueInPixels:uN}=Ve(Tn);var Pg=f(ue(),1),Og=f(Z(),1);function Er({children:e,level:t=2}){return(0,Og.jsx)(Pg.__experimentalHeading,{className:"global-styles-ui-subtitle",level:t,children:e})}var Jc=f(Z(),1);var{useHasDimensionsPanel:RN,useHasTypographyPanel:EN,useHasBorderPanel:TN,useSettingsForBlockElement:PN,useHasColorPanel:ON,useHasFiltersPanel:kN,useHasImageSettingsPanel:FN,useHasBackgroundPanel:AN,BackgroundPanel:IN,BorderPanel:LN,ColorPanel:NN,TypographyPanel:MN,DimensionsPanel:VN,FiltersPanel:DN,ImageSettingsPanel:BN,AdvancedPanel:jN}=Ve(kg.privateApis);var S2=f(ge(),1),C2=f(ue(),1),_2=f(Te(),1);var uS=f(ue(),1);var fS=f(Z(),1);var dS=f(ge(),1),Gs=f(ue(),1);var Ag=f(Z(),1);var Zs=f(ue(),1);var Ig=f(ue(),1);var Ys=f(Z(),1),pS=({variation:e,isFocused:t,withHoverView:r})=>(0,Ys.jsx)(Fn,{label:e.title,isFocused:t,withHoverView:r,children:({ratio:o,key:n})=>(0,Ys.jsx)(Ig.__experimentalHStack,{spacing:10*o,justify:"center",style:{height:"100%",overflow:"hidden"},children:(0,Ys.jsx)(Us,{variation:e,fontSize:85*o})},n)}),Lg=pS;var Zo=f(Te(),1),Mg=f(Qc(),1),qs=f(ge(),1);var Eo=f(Z(),1);function An({variation:e,children:t,isPill:r=!1,properties:o,showTooltip:n=!1}){let[i,s]=(0,Zo.useState)(!1),{base:a,user:u,onChange:l}=(0,Zo.useContext)(gt),c=(0,Zo.useMemo)(()=>{let w=Go(a,e);return o&&(w=zs(w,o)),{user:e,base:a,merged:w,onChange:()=>{}}},[e,a,o]),m=()=>l(e),d=w=>{w.keyCode===Mg.ENTER&&(w.preventDefault(),m())},h=(0,Zo.useMemo)(()=>pi(u,e),[u,e]),g=e?.title;e?.description&&(g=(0,qs.sprintf)((0,qs._x)("%1$s (%2$s)","variation label"),e?.title,e?.description));let b=(0,Eo.jsx)("div",{className:We("global-styles-ui-variations_item",{"is-active":h}),role:"button",onClick:m,onKeyDown:d,tabIndex:0,"aria-label":g,"aria-current":h,onFocus:()=>s(!0),onBlur:()=>s(!1),children:(0,Eo.jsx)("div",{className:We("global-styles-ui-variations_item-preview",{"is-pill":r}),children:t(i)})});return(0,Eo.jsx)(gt.Provider,{value:c,children:n?(0,Eo.jsxs)(Sn.Root,{children:[(0,Eo.jsx)(Sn.Trigger,{render:b}),(0,Eo.jsx)(Sn.Popup,{children:e?.title})]}):b})}var Xo=f(Z(),1),Vg=["typography"];function Xs({title:e,gap:t=2}){let r=Hs(Vg);return r?.length<=1?null:(0,Xo.jsxs)(Zs.__experimentalVStack,{spacing:3,children:[e&&(0,Xo.jsx)(Er,{level:3,children:e}),(0,Xo.jsx)(Zs.__experimentalGrid,{columns:3,gap:t,className:"global-styles-ui-style-variations-container",children:r.map((o,n)=>(0,Xo.jsx)(An,{variation:o,properties:Vg,showTooltip:!0,children:()=>(0,Xo.jsx)(Lg,{variation:o})},n))})]})}var w2=f(ge(),1),Ri=f(ue(),1);var x2=f(Te(),1);var to=f(Te(),1),ko=f(Kt(),1),Oo=f(sr(),1),ru=f(ge(),1);var $c=f(Bg(),1),jg=f(sr(),1),zg="/wp/v2/font-families";function Hg(e){let{receiveEntityRecords:t}=e.dispatch(jg.store);t("postType","wp_font_family",[],void 0,!0)}async function Ug(e,t){let o=await(0,$c.default)({path:zg,method:"POST",body:e});return Hg(t),{id:o.id,...o.font_family_settings,fontFace:[]}}async function Wg(e,t,r){let o={path:`${zg}/${e}/font-faces`,method:"POST",body:t},n=await(0,$c.default)(o);return Hg(r),{id:n.id,...n.font_face_settings}}var In=function(){return In=Object.assign||function(t){for(var r,o=1,n=arguments.length;o{o.forEach(n=>{n.family===jc(e?.fontFamily)&&n.weight===e?.fontWeight&&n.style===e?.fontStyle&&o.delete(n)})};if((t==="document"||t==="all")&&r(document.fonts),t==="iframe"||t==="all"){let o=document.querySelector('iframe[name="editor-canvas"]');o?.contentDocument&&r(o.contentDocument.fonts)}}function Ln(e){if(!e)return;let t;if(Array.isArray(e)?t=e[0]:t=e,!t.startsWith("file:."))return gS(t)||(t=encodeURI(t)),t}function ey(e){let t=new FormData,{fontFace:r,category:o,...n}=e,i={...n,slug:Ks(e.slug)};return t.append("font_family_settings",JSON.stringify(i)),t}function ty(e){return(e?.fontFace??[]).map((r,o)=>{let n={...r},i=new FormData;if(n.file){let s=Array.isArray(n.file)?n.file:[n.file],a=[];s.forEach((u,l)=>{let c=`file-${o}-${l}`;i.append(c,u,u.name),a.push(c)}),n.src=a.length===1?a[0]:a,delete n.file,i.append("font_face_settings",JSON.stringify(n))}else i.append("font_face_settings",JSON.stringify(n));return i})}async function ry(e,t,r){let o=[];for(let i of t)try{let s=await Wg(e,i,r);o.push({status:"fulfilled",value:s})}catch(s){o.push({status:"rejected",reason:s})}let n={errors:[],successes:[]};return o.forEach((i,s)=>{if(i.status==="fulfilled"&&i.value){let a=i.value;n.successes.push(a)}else i.reason&&n.errors.push({data:t[s],message:i.reason.message})}),n}async function oy(e){e=Array.isArray(e)?e:[e];let t=await Promise.all(e.map(async r=>fetch(new Request(r)).then(o=>{if(!o.ok)throw new Error(`Error downloading font face asset from ${r}. Server responded with status: ${o.status}`);return o.blob()}).then(o=>{let n=r.split("/").pop();return new Qg([o],n,{type:o.type})})));return t.length===1?t[0]:t}function tu(e,t){return t.findIndex(r=>r.fontWeight===e.fontWeight&&r.fontStyle===e.fontStyle)!==-1}function ny(e,t,r){t=Array.isArray(t)?[...t]:[t],e=Array.isArray(e)?[...e]:{...e};let o=t.pop(),n=e;for(let i of t){let s=n[i];n=n[i]=Array.isArray(s)?[...s]:{...s}}return n[o]=r,e}function Qs(e,t,r=[]){let o=u=>u.slug===e.slug,n=u=>u.find(o),i=u=>u?r.filter(l=>!o(l)):[...r,e],s=u=>{let l=m=>m.fontWeight===t.fontWeight&&m.fontStyle===t.fontStyle;if(!u)return[...r,{...e,fontFace:[t]}];let c=u.fontFace||[];return c.find(l)?c=c.filter(m=>!l(m)):c=[...c,t],c.length===0?r.filter(m=>!o(m)):r.map(m=>o(m)?{...m,fontFace:c}:m)},a=n(r);return t?s(a):i(a)}var iy=f(Z(),1),jt=(0,to.createContext)({});jt.displayName="FontLibraryContext";function vS({children:e}){let t=(0,ko.useRegistry)(),{saveEntityRecord:r,deleteEntityRecord:o}=(0,ko.useDispatch)(Oo.store),{globalStylesId:n}=(0,ko.useSelect)(R=>{let{__experimentalGetCurrentGlobalStylesId:B}=R(Oo.store);return{globalStylesId:B()}},[]),i=(0,Oo.useEntityRecord)("root","globalStyles",n),[s,a]=(0,to.useState)(!1),{records:u=[],isResolving:l}=(0,Oo.useEntityRecords)("postType","wp_font_family",{_embed:!0}),c=(u||[]).map(R=>({id:R.id,...R.font_family_settings||{},fontFace:R?._embedded?.font_faces?.map(B=>B.font_face_settings)||[]}))||[],[m,d]=Ke("typography.fontFamilies"),h=async R=>{if(!i.record)return;let B=i.record,re=ny(B??{},["settings","typography","fontFamilies"],R);await r("root","globalStyles",re)},[g,b]=(0,to.useState)(""),[w,C]=(0,to.useState)(void 0),x=m?.theme?m.theme.map(R=>To(R,{source:"theme"})).sort((R,B)=>R.name.localeCompare(B.name)):[],v=m?.custom?m.custom.map(R=>To(R,{source:"custom"})).sort((R,B)=>R.name.localeCompare(B.name)):[],_=c?c.map(R=>To(R,{source:"custom"})).sort((R,B)=>R.name.localeCompare(B.name)):[];(0,to.useEffect)(()=>{g||C(void 0)},[g]);let k=R=>{if(!R){C(void 0);return}let re=(R.source==="theme"?x:_).find(P=>P.slug===R.slug);C({...re||R,source:R.source})},[E]=(0,to.useState)(new Set),T=R=>R.reduce((re,P)=>{let W=P?.fontFace&&P.fontFace?.length>0?P?.fontFace.map(ne=>`${ne.fontStyle??""}${ne.fontWeight??""}`):["normal400"];return re[P.slug]=W,re},{}),O=R=>T(R==="theme"?x:v),I=(R,B,re,P)=>!B&&!re?!!O(P)[R]:!!O(P)[R]?.includes((B??"")+(re??"")),J=(R,B)=>O(B)[R]||[];async function D(R){a(!0);try{let B=[],re=[];for(let W of R){let ne=!1,xe=await(0,ko.resolveSelect)(Oo.store).getEntityRecords("postType","wp_font_family",{slug:W.slug,per_page:1,_embed:!0}),se=xe&&xe.length>0?xe[0]:null,be=se?{id:se.id,...se.font_family_settings,fontFace:(se?._embedded?.font_faces??[]).map(Fe=>Fe.font_face_settings)||[]}:null;be||(ne=!0,be=await Ug(ey(W),t));let ye=be.fontFace&&W.fontFace?be.fontFace.filter(Fe=>Fe&&W.fontFace&&tu(Fe,W.fontFace)):[];be.fontFace&&W.fontFace&&(W.fontFace=W.fontFace.filter(Fe=>!tu(Fe,be.fontFace)));let $=[],_e=[];if(W?.fontFace?.length??!1){let Fe=await ry(be.id,ty(W),t);$=Fe?.successes,_e=Fe?.errors}($?.length>0||ye?.length>0)&&(be.fontFace=[...$],B.push(be)),be&&!W?.fontFace?.length&&B.push(be),ne&&(W?.fontFace?.length??0)>0&&$?.length===0&&await o("postType","wp_font_family",be.id,{force:!0}),re=re.concat(_e)}let P=re.reduce((W,ne)=>W.includes(ne.message)?W:[...W,ne.message],[]);if(B.length>0){let W=Y(B);await h(W)}if(P.length>0){let W=new Error((0,ru.__)("There was an error installing fonts."));throw W.installationErrors=P,W}}finally{a(!1)}}async function S(R){if(!R?.id)throw new Error((0,ru.__)("Font family to uninstall is not defined."));try{await o("postType","wp_font_family",R.id,{force:!0});let B=L(R);return await h(B),{deleted:!0}}catch(B){throw console.error("There was an error uninstalling the font family:",B),B}}let L=R=>{let re=(m?.[R.source??""]??[]).filter(W=>W.slug!==R.slug),P={...m,[R.source??""]:re};return d(P),R.fontFace&&R.fontFace.forEach(W=>{bi(W,"all")}),P},Y=R=>{let B=A(R),re={...m,custom:$g(m?.custom,B)};return d(re),N(B),re},A=R=>R.map(({id:B,fontFace:re,...P})=>({...P,...re&&re.length>0?{fontFace:re.map(({id:W,...ne})=>ne)}:{}})),N=R=>{R.forEach(B=>{B.fontFace&&B.fontFace.forEach(re=>{let P=Ln(re?.src??"");P&&Po(re,P,"all")})})},q=(R,B)=>{let re=m?.[R.source??""]??[],P=Qs(R,B,re);d({...m,[R.source??""]:P});let W=I(R.slug,B?.fontStyle??"",B?.fontWeight??"",R.source??"custom");if(B&&W)bi(B,"all");else{let ne=Ln(B?.src??"");B&&ne&&Po(B,ne,"all")}},U=async R=>{if(!R.src)return;let B=Ln(R.src);!B||E.has(B)||(Po(R,B,"document"),E.add(B))};return(0,iy.jsx)(jt.Provider,{value:{libraryFontSelected:w,handleSetLibraryFontSelected:k,fontFamilies:m??{},baseCustomFonts:_,isFontActivated:I,getFontFacesActivated:J,loadFontFaceAsset:U,installFonts:D,uninstallFontFamily:S,toggleActivateFont:q,getAvailableFontsOutline:T,modalTabOpen:g,setModalTabOpen:b,saveFontFamilies:h,isResolvingLibrary:l,isInstalling:s},children:e})}var $s=vS;var ma=f(ge(),1),au=f(ue(),1),zy=f(sr(),1),v2=f(Kt(),1);var Ie=f(ue(),1),xi=f(sr(),1),ou=f(Kt(),1),Wr=f(Te(),1),st=f(ge(),1);var Mn=f(ge(),1),ea=f(Te(),1),hr=f(ue(),1);var Tr=f(Te(),1);var ro=f(Z(),1),sy=new Set;function bS(e){if(e.preview)return e.preview;if(e.src)return Array.isArray(e.src)?e.src[0]:e.src}function wS(e){return"fontStyle"in e&&e.fontStyle||"fontWeight"in e&&e.fontWeight?e:"fontFace"in e&&e.fontFace&&e.fontFace.length?e.fontFace.find(t=>t.fontStyle==="normal"&&t.fontWeight==="400")||e.fontFace[0]:{fontStyle:"normal",fontWeight:"400",fontFamily:e.fontFamily}}function xS({font:e,text:t}){let r=(0,Tr.useRef)(null),o=wS(e),n=On(e);t=t||("name"in e?e.name:"");let s=e.preview??bS(o),a=!!(s&&/\.(png|jpg|jpeg|gif|svg)$/i.test(s)),[u,l]=(0,Tr.useState)(!1),[c,m]=(0,Tr.useState)(!1),[d,h]=(0,Tr.useState)(),{loadFontFaceAsset:g}=(0,Tr.useContext)(jt),b=a?!!s&&(sy.has(s)||d===s):c,w=Math.min(Math.max(t.length*12,48),300),C=dg(o),x={fontSize:"18px",lineHeight:1,opacity:b?"1":"0",...n,...C};return(0,Tr.useEffect)(()=>{if(a)return;let v=new window.IntersectionObserver(([_])=>{l(_.isIntersecting)},{});return r.current&&v.observe(r.current),()=>v.disconnect()},[a]),(0,Tr.useEffect)(()=>{(async()=>u&&!a&&(o.src&&await g(o),m(!0)))()},[o,u,g,a]),(0,ro.jsx)("div",{ref:r,className:"font-library__font-demo",children:a?(0,ro.jsxs)(ro.Fragment,{children:[!b&&(0,ro.jsx)(ui,{className:"font-library__font-variant-demo-skeleton",style:{width:w}}),(0,ro.jsx)("img",{src:s,loading:"lazy",alt:t,onLoad:()=>{s&&sy.add(s),h(s)},onError:()=>h(s),className:We("font-library__font-variant_demo-image",{"is-loading":!b})})]}):(0,ro.jsx)("span",{style:x,className:"font-library__font-variant_demo-text",children:t})})}var Nn=xS;var Ur=f(Z(),1);function SS({font:e,onClick:t,variantsText:r,navigatorPath:o,shouldFocus:n}){let i=e.fontFace?.length||1,s={cursor:t?"pointer":"default"},a=(0,hr.useNavigator)(),u=(0,ea.useRef)(null);return(0,ea.useEffect)(()=>{n&&u.current?.focus()},[n]),(0,Ur.jsx)(hr.Button,{ref:u,__next40pxDefaultSize:!0,onClick:()=>{t(),o&&a.goTo(o)},style:s,className:"font-library__font-card",children:(0,Ur.jsxs)(hr.Flex,{justify:"space-between",wrap:!1,children:[(0,Ur.jsx)(Nn,{font:e}),(0,Ur.jsxs)(hr.Flex,{justify:"flex-end",children:[(0,Ur.jsx)(hr.FlexItem,{children:(0,Ur.jsx)(hr.__experimentalText,{className:"font-library__font-card__count",children:r||(0,Mn.sprintf)((0,Mn._n)("%d variant","%d variants",i),i)})}),(0,Ur.jsx)(hr.FlexItem,{children:(0,Ur.jsx)(ai,{icon:(0,Mn.isRTL)()?Uo:Wo})})]})]})})}var wi=SS;var ta=f(Te(),1),ra=f(ue(),1);var Ko=f(Z(),1);function CS({face:e,font:t}){let{isFontActivated:r,toggleActivateFont:o}=(0,ta.useContext)(jt),n=(t?.fontFace?.length??0)>0?r(t.slug,e.fontStyle,e.fontWeight,t.source):r(t.slug,void 0,void 0,t.source),i=()=>{if((t?.fontFace?.length??0)>0){o(t,e);return}o(t)},s=t.name+" "+Js(e),a=(0,ta.useId)();return(0,Ko.jsx)("div",{className:"font-library__font-card",children:(0,Ko.jsxs)(ra.Flex,{justify:"flex-start",align:"center",gap:"1rem",children:[(0,Ko.jsx)(ra.CheckboxControl,{checked:n,onChange:i,id:a}),(0,Ko.jsx)("label",{htmlFor:a,children:(0,Ko.jsx)(Nn,{font:e,text:s,onClick:i})})]})})}var ay=CS;function ly(e){switch(e){case"normal":return 400;case"bold":return 700;case"bolder":return 500;case"lighter":return 300;default:return parseInt(e,10)}}function oa(e){return e.sort((t,r)=>t.fontStyle==="normal"&&r.fontStyle!=="normal"?-1:r.fontStyle==="normal"&&t.fontStyle!=="normal"?1:t.fontStyle===r.fontStyle?ly(t.fontWeight?.toString()??"normal")-ly(r.fontWeight?.toString()??"normal"):!t.fontStyle||!r.fontStyle?t.fontStyle?-1:1:t.fontStyle.localeCompare(r.fontStyle))}var Ee=f(Z(),1);function cy(e){if(!e)return"";let t={};for(let r of Object.keys(e).sort())t[r]=(e[r]??[]).map(o=>({slug:o.slug,fontFace:(o.fontFace??[]).map(n=>`${n.fontStyle}-${n.fontWeight}`).sort()})).sort((o,n)=>o.slug.localeCompare(n.slug));return JSON.stringify(t)}function _S(){let{baseCustomFonts:e,libraryFontSelected:t,handleSetLibraryFontSelected:r,uninstallFontFamily:o,isResolvingLibrary:n,isInstalling:i,saveFontFamilies:s,getFontFacesActivated:a}=(0,Wr.useContext)(jt),[u,l]=Ke("typography.fontFamilies"),[c,m]=(0,Wr.useState)(void 0),[d,h]=(0,Wr.useState)(!1),[g,b]=(0,Wr.useState)(null),[w]=Ke("typography.fontFamilies",void 0,"base"),C=(0,ou.useSelect)(P=>{let{__experimentalGetCurrentGlobalStylesId:W}=P(xi.store);return W()},[]),x=(0,xi.useEntityRecord)("root","globalStyles",C),v=x?.edits?.settings?.typography?.fontFamilies,_=x?.record?.settings?.typography?.fontFamilies,k=(0,Wr.useMemo)(()=>v===void 0?!1:cy(v)!==cy(_),[v,_]),E=u?.theme?u.theme.map(P=>To(P,{source:"theme"})).sort((P,W)=>P.name.localeCompare(W.name)):[],T=new Set(E.map(P=>P.slug)),O=w?.theme?E.concat(w.theme.filter(P=>!T.has(P.slug)).map(P=>To(P,{source:"theme"})).sort((P,W)=>P.name.localeCompare(W.name))):[],I=t?.source==="custom"&&t?.id,J=(0,ou.useSelect)(P=>{let{canUser:W}=P(xi.store);return I&&W("delete",{kind:"postType",name:"wp_font_family",id:I})},[I]),D=!!t&&t?.source!=="theme"&&J,S=()=>{h(!0)},L=async()=>{b(null);try{await s(u),b({type:"success",message:(0,st.__)("Font family updated successfully.")})}catch(P){b({type:"error",message:(0,st.sprintf)((0,st.__)("There was an error updating the font family. %s"),P.message)})}},Y=P=>P?!P.fontFace||!P.fontFace.length?[{fontFamily:P.fontFamily,fontStyle:"normal",fontWeight:"400"}]:oa(P.fontFace):[],A=P=>{let W=P?.fontFace&&(P?.fontFace?.length??0)>0?P.fontFace.length:1,ne=a(P.slug,P.source).length;return(0,st.sprintf)((0,st.__)("%1$d of %2$d active"),ne,W)};(0,Wr.useEffect)(()=>{r(t)},[]);let N=t?a(t.slug,t.source).length:0,q=t?.fontFace?.length??(t?.fontFamily?1:0),U=N>0&&N!==q,R=N===q,B=()=>{if(!t||!t?.source)return;let P=u?.[t.source]?.filter(ne=>ne.slug!==t.slug)??[],W=R?P:[...P,t];l({...u,[t.source]:W}),t.fontFace&&t.fontFace.forEach(ne=>{if(R)bi(ne,"all");else{let xe=Ln(ne?.src??"");xe&&Po(ne,xe,"all")}})},re=O.length>0||e.length>0;return(0,Ee.jsxs)("div",{className:"font-library__tabpanel-layout",children:[n&&(0,Ee.jsx)("div",{className:"font-library__loading",children:(0,Ee.jsx)(Ie.ProgressBar,{})}),!n&&(0,Ee.jsxs)(Ee.Fragment,{children:[(0,Ee.jsxs)(Ie.Navigator,{initialPath:t?"/fontFamily":"/",children:[(0,Ee.jsx)(Ie.Navigator.Screen,{path:"/",children:(0,Ee.jsxs)(Ie.__experimentalVStack,{spacing:"8",children:[g&&(0,Ee.jsx)(Ie.Notice,{status:g.type,onRemove:()=>b(null),children:g.message}),!re&&(0,Ee.jsx)(Ie.__experimentalText,{as:"p",children:(0,st.__)("No fonts installed.")}),O.length>0&&(0,Ee.jsxs)(Ie.__experimentalVStack,{children:[(0,Ee.jsx)("h2",{className:"font-library__fonts-title",children:(0,st._x)("Theme","font source")}),(0,Ee.jsx)("ul",{role:"list",className:"font-library__fonts-list",children:O.map(P=>(0,Ee.jsx)("li",{className:"font-library__fonts-list-item",children:(0,Ee.jsx)(wi,{font:P,navigatorPath:"/fontFamily",variantsText:A(P),shouldFocus:P.slug===c,onClick:()=>{b(null),r(P)}})},P.slug))})]}),e.length>0&&(0,Ee.jsxs)(Ie.__experimentalVStack,{children:[(0,Ee.jsx)("h2",{className:"font-library__fonts-title",children:(0,st._x)("Custom","font source")}),(0,Ee.jsx)("ul",{role:"list",className:"font-library__fonts-list",children:e.map(P=>(0,Ee.jsx)("li",{className:"font-library__fonts-list-item",children:(0,Ee.jsx)(wi,{font:P,navigatorPath:"/fontFamily",variantsText:A(P),shouldFocus:P.slug===c,onClick:()=>{b(null),r(P)}})},P.slug))})]})]})}),(0,Ee.jsxs)(Ie.Navigator.Screen,{path:"/fontFamily",children:[t&&(0,Ee.jsx)(RS,{font:t,isOpen:d,setIsOpen:h,setNotice:b,uninstallFontFamily:o,handleSetLibraryFontSelected:r}),(0,Ee.jsxs)(Ie.Flex,{justify:"flex-start",children:[(0,Ee.jsx)(Ie.Navigator.BackButton,{icon:(0,st.isRTL)()?Wo:Uo,size:"small",onClick:()=>{m(t?.slug),r(void 0),b(null)},label:(0,st.__)("Back")}),(0,Ee.jsx)(Ie.__experimentalHeading,{level:2,size:13,className:"global-styles-ui-header",children:t?.name})]}),g&&(0,Ee.jsxs)(Ee.Fragment,{children:[(0,Ee.jsx)(Ie.__experimentalSpacer,{margin:1}),(0,Ee.jsx)(Ie.Notice,{status:g.type,onRemove:()=>b(null),children:g.message}),(0,Ee.jsx)(Ie.__experimentalSpacer,{margin:1})]}),(0,Ee.jsx)(Ie.__experimentalSpacer,{margin:4}),(0,Ee.jsx)(Ie.__experimentalText,{children:(0,st.__)("Choose font variants. Keep in mind that too many variants could make your site slower.")}),(0,Ee.jsx)(Ie.__experimentalSpacer,{margin:4}),(0,Ee.jsxs)(Ie.__experimentalVStack,{spacing:0,children:[(0,Ee.jsx)(Ie.CheckboxControl,{className:"font-library__select-all",label:(0,st.__)("Select all"),checked:R,onChange:B,indeterminate:U}),(0,Ee.jsx)(Ie.__experimentalSpacer,{margin:8}),(0,Ee.jsx)("ul",{role:"list",className:"font-library__fonts-list",children:t&&Y(t).map((P,W)=>(0,Ee.jsx)("li",{className:"font-library__fonts-list-item",children:(0,Ee.jsx)(ay,{font:t,face:P},`face${W}`)},`face${W}`))})]})]})]}),(0,Ee.jsxs)(Ie.__experimentalHStack,{justify:"flex-end",className:"font-library__footer",children:[i&&(0,Ee.jsx)(Ie.ProgressBar,{}),D&&(0,Ee.jsx)(Ie.Button,{__next40pxDefaultSize:!0,isDestructive:!0,variant:"tertiary",onClick:S,children:(0,st.__)("Delete")}),(0,Ee.jsx)(Ie.Button,{__next40pxDefaultSize:!0,variant:"primary",onClick:L,disabled:!k,accessibleWhenDisabled:!0,children:(0,st.__)("Update")})]})]})]})}function RS({font:e,isOpen:t,setIsOpen:r,setNotice:o,uninstallFontFamily:n,handleSetLibraryFontSelected:i}){let s=(0,Ie.useNavigator)(),a=async()=>{o(null),r(!1);try{await n(e),s.goBack(),i(void 0),o({type:"success",message:(0,st.__)("Font family uninstalled successfully.")})}catch(l){o({type:"error",message:(0,st.__)("There was an error uninstalling the font family.")+l.message})}},u=()=>{r(!1)};return(0,Ee.jsx)(Ie.__experimentalConfirmDialog,{isOpen:t,cancelButtonText:(0,st.__)("Cancel"),confirmButtonText:(0,st.__)("Delete"),onCancel:u,onConfirm:a,size:"medium",children:e&&(0,st.sprintf)((0,st.__)('Are you sure you want to delete "%s" font and all its variants and assets?'),e.name)})}var na=_S;var yt=f(Te(),1),Ce=f(ue(),1),yy=f(yo(),1),rt=f(ge(),1);var vy=f(sr(),1);function uy(e,t){let{category:r,search:o}=t,n=e||[];return r&&r!=="all"&&(n=n.filter(i=>i.categories&&i.categories.indexOf(r)!==-1)),o&&(n=n.filter(i=>i.font_family_settings&&i.font_family_settings.name.toLowerCase().includes(o.toLowerCase()))),n}function fy(e){return e.reduce((t,r)=>({...t,[r.slug]:(r?.fontFace||[]).reduce((o,n)=>({...o,[`${n.fontStyle}-${n.fontWeight}`]:!0}),{})}),{})}function dy(e,t,r){return t?!!r[e]?.[`${t.fontStyle}-${t.fontWeight}`]:!!r[e]}var Si=f(ge(),1),zt=f(ue(),1),gr=f(Z(),1);function ES(){let e=()=>{window.localStorage.setItem("wp-font-library-google-fonts-permission","true"),window.dispatchEvent(new Event("storage"))};return(0,gr.jsx)("div",{className:"font-library__google-fonts-confirm",children:(0,gr.jsx)(zt.Card,{children:(0,gr.jsxs)(zt.CardBody,{children:[(0,gr.jsx)(zt.__experimentalHeading,{level:2,children:(0,Si.__)("Connect to Google Fonts")}),(0,gr.jsx)(zt.__experimentalSpacer,{margin:6}),(0,gr.jsx)(zt.__experimentalText,{as:"p",children:(0,Si.__)("To install fonts from Google you must give permission to connect directly to Google servers. The fonts you install will be downloaded from Google and stored on your site. Your site will then use these locally-hosted fonts.")}),(0,gr.jsx)(zt.__experimentalSpacer,{margin:3}),(0,gr.jsx)(zt.__experimentalText,{as:"p",children:(0,Si.__)("You can alternatively upload files directly on the Upload tab.")}),(0,gr.jsx)(zt.__experimentalSpacer,{margin:6}),(0,gr.jsx)(zt.Button,{__next40pxDefaultSize:!0,variant:"primary",onClick:e,children:(0,Si.__)("Allow access to Google Fonts")})]})})})}var py=ES;var my=f(Te(),1),ia=f(ue(),1);var Jo=f(Z(),1);function TS({face:e,font:t,handleToggleVariant:r,selected:o}){let n=()=>{if(t?.fontFace){r(t,e);return}r(t)},i=t.name+" "+Js(e),s=(0,my.useId)();return(0,Jo.jsx)("div",{className:"font-library__font-card",children:(0,Jo.jsxs)(ia.Flex,{justify:"flex-start",align:"center",gap:"1rem",children:[(0,Jo.jsx)(ia.CheckboxControl,{checked:o,onChange:n,id:s}),(0,Jo.jsx)("label",{htmlFor:s,children:(0,Jo.jsx)(Nn,{font:e,text:i,onClick:n})})]})})}var hy=TS;var de=f(Z(),1),PS={slug:"all",name:(0,rt._x)("All","font categories")},gy="wp-font-library-google-fonts-permission",OS=500;function kS({slug:e}){let t=e==="google-fonts",r=()=>window.localStorage.getItem(gy)==="true",[o,n]=(0,yt.useState)(null),[i,s]=(0,yt.useState)(void 0),[a,u]=(0,yt.useState)(null),[l,c]=(0,yt.useState)([]),[m,d]=(0,yt.useState)(1),[h,g]=(0,yt.useState)({}),[b,w]=(0,yt.useState)(t&&!r()),{installFonts:C,isInstalling:x}=(0,yt.useContext)(jt),{record:v,isResolving:_}=(0,vy.useEntityRecord)("root","fontCollection",e);(0,yt.useEffect)(()=>{let $=()=>{w(t&&!r())};return $(),window.addEventListener("storage",$),()=>window.removeEventListener("storage",$)},[e,t]);let k=()=>{window.localStorage.setItem(gy,"false"),window.dispatchEvent(new Event("storage"))};(0,yt.useEffect)(()=>{n(null)},[e]),(0,yt.useEffect)(()=>{c([])},[o]);let E=(0,yt.useMemo)(()=>v?.font_families??[],[v]),T=v?.categories??[],O=[PS,...T],I=(0,yt.useMemo)(()=>uy(E,h),[E,h]),J=Math.max(window.innerHeight,OS),D=Math.floor((J-417)/61),S=Math.ceil(I.length/D),L=(m-1)*D,Y=m*D,A=I.slice(L,Y),N=$=>{g({...h,category:$}),d(1)},U=(0,yy.debounce)($=>{g({...h,search:$}),d(1)},300),R=($,_e)=>{let Fe=Qs($,_e,l);c(Fe)},B=fy(l),re=()=>{c([])},P=l.length>0?l[0]?.fontFace?.length??0:0,W=P>0&&P!==o?.fontFace?.length,ne=P===o?.fontFace?.length,xe=()=>{let $=[];!ne&&o&&$.push(o),c($)},se=async()=>{u(null);let $=l[0];try{$?.fontFace&&await Promise.all($.fontFace.map(async _e=>{_e.src&&(_e.file=await oy(_e.src))}))}catch{u({type:"error",message:(0,rt.__)("Error installing the fonts, could not be downloaded.")});return}try{await C([$]),u({type:"success",message:(0,rt.__)("Fonts were installed successfully.")})}catch(_e){u({type:"error",message:_e.message})}re()},be=$=>$?!$.fontFace||!$.fontFace.length?[{fontFamily:$.fontFamily,fontStyle:"normal",fontWeight:"400"}]:oa($.fontFace):[];if(b)return(0,de.jsx)(py,{});let ye=e==="google-fonts"&&!b&&!o;return(0,de.jsxs)("div",{className:"font-library__tabpanel-layout",children:[_&&(0,de.jsx)("div",{className:"font-library__loading",children:(0,de.jsx)(Ce.ProgressBar,{})}),!_&&v&&(0,de.jsxs)(de.Fragment,{children:[(0,de.jsxs)(Ce.Navigator,{initialPath:"/",className:"font-library__tabpanel-layout",children:[(0,de.jsxs)(Ce.Navigator.Screen,{path:"/",children:[(0,de.jsxs)(Ce.__experimentalHStack,{justify:"space-between",children:[(0,de.jsxs)(Ce.__experimentalVStack,{children:[(0,de.jsx)(Ce.__experimentalHeading,{level:2,size:13,children:v.name}),(0,de.jsx)(Ce.__experimentalText,{children:v.description})]}),ye&&(0,de.jsx)(Ce.DropdownMenu,{icon:jl,label:(0,rt.__)("Actions"),popoverProps:{position:"bottom left"},controls:[{title:(0,rt.__)("Revoke access to Google Fonts"),onClick:k}]})]}),(0,de.jsx)(Ce.__experimentalSpacer,{margin:4}),(0,de.jsxs)(Ce.__experimentalHStack,{spacing:4,justify:"space-between",children:[(0,de.jsx)(Ce.SearchControl,{className:"font-library__search",value:h.search,placeholder:(0,rt.__)("Font name\u2026"),label:(0,rt.__)("Search"),onChange:U,hideLabelFromVision:!1}),(0,de.jsx)(Ce.SelectControl,{label:(0,rt.__)("Category"),value:h.category,onChange:N,children:O&&O.map($=>(0,de.jsx)("option",{value:$.slug,children:$.name},$.slug))})]}),(0,de.jsx)(Ce.__experimentalSpacer,{margin:4}),!!v?.font_families?.length&&!I.length&&(0,de.jsx)(Ce.__experimentalText,{children:(0,rt.__)("No fonts found. Try with a different search term.")}),(0,de.jsx)("div",{className:"font-library__fonts-grid__main",children:(0,de.jsx)("ul",{role:"list",className:"font-library__fonts-list",children:A.map($=>(0,de.jsx)("li",{className:"font-library__fonts-list-item",children:(0,de.jsx)(wi,{font:$.font_family_settings,navigatorPath:"/fontFamily",shouldFocus:$.font_family_settings.slug===i,onClick:()=>{n($.font_family_settings)}})},$.font_family_settings.slug))})})]}),(0,de.jsxs)(Ce.Navigator.Screen,{path:"/fontFamily",children:[(0,de.jsxs)(Ce.Flex,{justify:"flex-start",children:[(0,de.jsx)(Ce.Navigator.BackButton,{icon:(0,rt.isRTL)()?Wo:Uo,size:"small",onClick:()=>{s(o?.slug),n(null),u(null)},label:(0,rt.__)("Back")}),(0,de.jsx)(Ce.__experimentalHeading,{level:2,size:13,className:"global-styles-ui-header",children:o?.name})]}),a&&(0,de.jsxs)(de.Fragment,{children:[(0,de.jsx)(Ce.__experimentalSpacer,{margin:1}),(0,de.jsx)(Ce.Notice,{status:a.type,onRemove:()=>u(null),children:a.message}),(0,de.jsx)(Ce.__experimentalSpacer,{margin:1})]}),(0,de.jsx)(Ce.__experimentalSpacer,{margin:4}),(0,de.jsx)(Ce.__experimentalText,{children:(0,rt.__)("Select font variants to install.")}),(0,de.jsx)(Ce.__experimentalSpacer,{margin:4}),(0,de.jsx)(Ce.CheckboxControl,{className:"font-library__select-all",label:(0,rt.__)("Select all"),checked:ne,onChange:xe,indeterminate:W}),(0,de.jsx)(Ce.__experimentalVStack,{spacing:0,children:(0,de.jsx)("ul",{role:"list",className:"font-library__fonts-list",children:o&&be(o).map(($,_e)=>(0,de.jsx)("li",{className:"font-library__fonts-list-item",children:(0,de.jsx)(hy,{font:o,face:$,handleToggleVariant:R,selected:dy(o.slug,o.fontFace?$:null,B)})},`face${_e}`))})}),(0,de.jsx)(Ce.__experimentalSpacer,{margin:16})]})]}),o&&(0,de.jsx)(Ce.Flex,{justify:"flex-end",className:"font-library__footer",children:(0,de.jsx)(Ce.Button,{__next40pxDefaultSize:!0,variant:"primary",onClick:se,isBusy:x,disabled:l.length===0||x,accessibleWhenDisabled:!0,children:(0,rt.__)("Install")})}),!o&&(0,de.jsxs)(Ce.__experimentalHStack,{expanded:!1,className:"font-library__footer",justify:"end",spacing:6,children:[(0,de.jsx)(Ce.__experimentalHStack,{justify:"flex-start",expanded:!1,spacing:1,className:"font-library__page-selection",children:(0,yt.createInterpolateElement)((0,rt.sprintf)((0,rt._x)("
Page
%1$s
of %2$d
","paging"),"",S),{div:(0,de.jsx)("div",{"aria-hidden":!0}),CurrentPage:(0,de.jsx)(Ce.SelectControl,{"aria-label":(0,rt.__)("Current page"),value:m.toString(),options:[...Array(S)].map(($,_e)=>({label:(_e+1).toString(),value:(_e+1).toString()})),onChange:$=>d(parseInt($)),size:"small",variant:"minimal"})})}),(0,de.jsxs)(Ce.__experimentalHStack,{expanded:!1,spacing:1,children:[(0,de.jsx)(Ce.Button,{onClick:()=>d(m-1),disabled:m===1,accessibleWhenDisabled:!0,label:(0,rt.__)("Previous page"),icon:(0,rt.isRTL)()?Os:Fs,showTooltip:!0,size:"compact",tooltipPosition:"top"}),(0,de.jsx)(Ce.Button,{onClick:()=>d(m+1),disabled:m===S,accessibleWhenDisabled:!0,label:(0,rt.__)("Next page"),icon:(0,rt.isRTL)()?Fs:Os,showTooltip:!0,size:"compact",tooltipPosition:"top"})]})]})]})]})}var sa=kS;var Vn=f(ge(),1),Ot=f(ue(),1),_i=f(Te(),1);var aa=(e=>typeof Wt<"u"?Wt:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof Wt<"u"?Wt:t)[r]}):e)(function(e){if(typeof Wt<"u")return Wt.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')}),by=(function(){var e,t,r;return(function(){function o(n,i,s){function a(c,m){if(!i[c]){if(!n[c]){var d=typeof aa=="function"&&aa;if(!m&&d)return d(c,!0);if(u)return u(c,!0);var h=new Error("Cannot find module '"+c+"'");throw h.code="MODULE_NOT_FOUND",h}var g=i[c]={exports:{}};n[c][0].call(g.exports,function(b){var w=n[c][1][b];return a(w||b)},g,g.exports,o,n,i,s)}return i[c].exports}for(var u=typeof aa=="function"&&aa,l=0;l0},c.prototype.readMoreInput=function(){if(!(this.bit_end_pos_>256))if(this.eos_){if(this.bit_pos_>this.bit_end_pos_)throw new Error("Unexpected end of input "+this.bit_pos_+" "+this.bit_end_pos_)}else{var m=this.buf_ptr_,d=this.input_.read(this.buf_,m,s);if(d<0)throw new Error("Unexpected end of input");if(d=8;)this.val_>>>=8,this.val_|=this.buf_[this.pos_&u]<<24,++this.pos_,this.bit_pos_=this.bit_pos_-8>>>0,this.bit_end_pos_=this.bit_end_pos_-8>>>0},c.prototype.readBits=function(m){32-this.bit_pos_>>this.bit_pos_&l[m];return this.bit_pos_+=m,d},n.exports=c},{}],2:[function(o,n,i){var s=0,a=1,u=2,l=3;i.lookup=new Uint8Array([0,0,0,0,0,0,0,0,0,4,4,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,12,16,12,12,20,12,16,24,28,12,12,32,12,36,12,44,44,44,44,44,44,44,44,44,44,32,32,24,40,28,12,12,48,52,52,52,48,52,52,52,48,52,52,52,52,52,48,52,52,52,52,52,48,52,52,52,52,52,24,12,28,12,12,12,56,60,60,60,56,60,60,60,56,60,60,60,60,60,56,60,60,60,60,60,56,60,60,60,60,60,24,12,28,12,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,56,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10,11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,14,15,15,15,15,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,22,22,22,22,23,23,23,23,24,24,24,24,25,25,25,25,26,26,26,26,27,27,27,27,28,28,28,28,29,29,29,29,30,30,30,30,31,31,31,31,32,32,32,32,33,33,33,33,34,34,34,34,35,35,35,35,36,36,36,36,37,37,37,37,38,38,38,38,39,39,39,39,40,40,40,40,41,41,41,41,42,42,42,42,43,43,43,43,44,44,44,44,45,45,45,45,46,46,46,46,47,47,47,47,48,48,48,48,49,49,49,49,50,50,50,50,51,51,51,51,52,52,52,52,53,53,53,53,54,54,54,54,55,55,55,55,56,56,56,56,57,57,57,57,58,58,58,58,59,59,59,59,60,60,60,60,61,61,61,61,62,62,62,62,63,63,63,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]),i.lookupOffsets=new Uint16Array([1024,1536,1280,1536,0,256,768,512])},{}],3:[function(o,n,i){var s=o("./streams").BrotliInput,a=o("./streams").BrotliOutput,u=o("./bit_reader"),l=o("./dictionary"),c=o("./huffman").HuffmanCode,m=o("./huffman").BrotliBuildHuffmanTable,d=o("./context"),h=o("./prefix"),g=o("./transform"),b=8,w=16,C=256,x=704,v=26,_=6,k=2,E=8,T=255,O=1080,I=18,J=new Uint8Array([1,2,3,4,0,5,17,6,16,7,8,9,10,11,12,13,14,15]),D=16,S=new Uint8Array([3,2,1,0,3,3,3,3,3,3,2,2,2,2,2,2]),L=new Int8Array([0,0,0,0,-1,1,-2,2,-3,3,-1,1,-2,2,-3,3]),Y=new Uint16Array([256,402,436,468,500,534,566,598,630,662,694,726,758,790,822,854,886,920,952,984,1016,1048,1080]);function A(X){var M;return X.readBits(1)===0?16:(M=X.readBits(3),M>0?17+M:(M=X.readBits(3),M>0?8+M:17))}function N(X){if(X.readBits(1)){var M=X.readBits(3);return M===0?1:X.readBits(M)+(1<1&&pe===0)throw new Error("Invalid size byte");M.meta_block_length|=pe<4&&le===0)throw new Error("Invalid size nibble");M.meta_block_length|=le<>>K.bit_pos_&T,Q=X[M].bits-E,Q>0&&(K.bit_pos_+=E,M+=X[M].value,M+=K.val_>>>K.bit_pos_&(1<0;){var te=0,Ne;if(H.readMoreInput(),H.fillBitWindow(),te+=H.val_>>>H.bit_pos_&31,H.bit_pos_+=he[te].bits,Ne=he[te].value&255,Ne>Ne);else{var He=Ne-14,ot,Ze,Be=0;if(Ne===w&&(Be=pe),fe!==Be&&(le=0,fe=Be),ot=le,le>0&&(le-=2,le<<=He),le+=H.readBits(He)+3,Ze=le-ot,Q+Ze>M)throw new Error("[ReadHuffmanCodeLengths] symbol + repeat_delta > num_symbols");for(var Ue=0;Ue0;++fe){var Be=J[fe],Ue=0,ct;H.fillBitWindow(),Ue+=H.val_>>>H.bit_pos_&15,H.bit_pos_+=Ze[Ue].bits,ct=Ze[Ue].value,Ne[Be]=ct,ct!==0&&(He-=32>>ct,++ot)}if(!(ot===1||He===0))throw new Error("[ReadHuffmanCode] invalid num_codes or space");B(Ne,X,le,H)}if(Q=m(M,K,E,le,X),Q===0)throw new Error("[ReadHuffmanCode] BuildHuffmanTable failed: ");return Q}function P(X,M,K){var H,Q;return H=R(X,M,K),Q=h.kBlockLengthPrefixCode[H].nbits,h.kBlockLengthPrefixCode[H].offset+K.readBits(Q)}function W(X,M,K){var H;return X>>5]),this.htrees=new Uint32Array(M)}se.prototype.decode=function(X){var M,K,H=0;for(M=0;M=X)throw new Error("[DecodeContextMap] i >= context_map_size");me[le]=0,++le}else me[le]=he-Q,++le}return M.readBits(1)&&xe(me,X),K}function ye(X,M,K,H,Q,pe,le){var fe=K*2,me=K,he=R(M,K*O,le),V;he===0?V=Q[fe+(pe[me]&1)]:he===1?V=Q[fe+(pe[me]-1&1)]+1:V=he-2,V>=X&&(V-=X),H[K]=V,Q[fe+(pe[me]&1)]=V,++pe[me]}function $(X,M,K,H,Q,pe){var le=Q+1,fe=K&Q,me=pe.pos_&u.IBUF_MASK,he;if(M<8||pe.bit_pos_+(M<<3)0;)pe.readMoreInput(),H[fe++]=pe.readBits(8),fe===le&&(X.write(H,le),fe=0);return}if(pe.bit_end_pos_<32)throw new Error("[CopyUncompressedBlockToOutput] br.bit_end_pos_ < 32");for(;pe.bit_pos_<32;)H[fe]=pe.val_>>>pe.bit_pos_,pe.bit_pos_+=8,++fe,--M;if(he=pe.bit_end_pos_-pe.bit_pos_>>3,me+he>u.IBUF_MASK){for(var V=u.IBUF_MASK+1-me,te=0;te=le){X.write(H,le),fe-=le;for(var te=0;te=le;){if(he=le-fe,pe.input_.read(H,fe,he)M.buffer.length){var Fo=new Uint8Array(H+Ye);Fo.set(M.buffer),M.buffer=Fo}if(Q=wr.input_end,Yr=wr.is_uncompressed,wr.is_metadata){for(_e(Se);Ye>0;--Ye)Se.readMoreInput(),Se.readBits(8);continue}if(Ye!==0){if(Yr){Se.bit_pos_=Se.bit_pos_+7&-8,$(M,Ye,H,V,he,Se),H+=Ye;continue}for(K=0;K<3;++K)vt[K]=N(Se)+1,vt[K]>=2&&(re(vt[K]+2,Ue,K*O,Se),re(v,ct,K*O,Se),St[K]=P(ct,K*O,Se),G[K]=1);for(Se.readMoreInput(),y=Se.readBits(2),oe=D+(Se.readBits(4)<0;){var ft,At,Ht,en,Ta,Ut,er,qr,Hn,tn,Un;for(Se.readMoreInput(),St[1]===0&&(ye(vt[1],Ue,1,kt,F,G,Se),St[1]=P(ct,O,Se),pt=Be[1].htrees[kt[1]]),--St[1],ft=R(Be[1].codes,pt,Se),At=ft>>6,At>=2?(At-=2,er=-1):er=0,Ht=h.kInsertRangeLut[At]+(ft>>3&7),en=h.kCopyRangeLut[At]+(ft&7),Ta=h.kInsertLengthPrefixCode[Ht].offset+Se.readBits(h.kInsertLengthPrefixCode[Ht].nbits),Ut=h.kCopyLengthPrefixCode[en].offset+Se.readBits(h.kCopyLengthPrefixCode[en].nbits),ot=V[H-1&he],Ze=V[H-2&he],tn=0;tn4?3:Ut-2)&255,et=j[Or+Hn],er=R(Be[2].codes,Be[2].htrees[et],Se),er>=oe){var Pa,Vu,Wn;er-=oe,Vu=er&Ae,er>>=y,Pa=(er>>1)+1,Wn=(2+(er&1)<fe)if(Ut>=l.minDictionaryWordLength&&Ut<=l.maxDictionaryWordLength){var Wn=l.offsetsByLength[Ut],Du=qr-fe-1,Bu=l.sizeBitsByLength[Ut],zv=(1<>Bu;if(Wn+=Hv*Ut,ju=te){M.write(V,me);for(var Fi=0;Fi0&&(Ne[He&3]=qr,++He),Ut>Ye)throw new Error("Invalid backward reference. pos: "+H+" distance: "+qr+" len: "+Ut+" bytes left: "+Ye);for(tn=0;tn>=1;return(m&h-1)+h}function l(m,d,h,g,b){do g-=h,m[d+g]=new s(b.bits,b.value);while(g>0)}function c(m,d,h){for(var g=1<0;--S[x])C=new s(x&255,D[v++]&65535),l(m,d+_,k,I,C),_=u(_,x);for(T=J-1,E=-1,x=h+1,k=2;x<=a;++x,k<<=1)for(;S[x]>0;--S[x])(_&T)!==E&&(d+=I,O=c(S,x,h),I=1<>h),k,I,C),_=u(_,x);return J}},{}],8:[function(o,n,i){"use strict";i.byteLength=h,i.toByteArray=b,i.fromByteArray=x;for(var s=[],a=[],u=typeof Uint8Array<"u"?Uint8Array:Array,l="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",c=0,m=l.length;c0)throw new Error("Invalid string. Length must be a multiple of 4");var k=v.indexOf("=");k===-1&&(k=_);var E=k===_?0:4-k%4;return[k,E]}function h(v){var _=d(v),k=_[0],E=_[1];return(k+E)*3/4-E}function g(v,_,k){return(_+k)*3/4-k}function b(v){for(var _,k=d(v),E=k[0],T=k[1],O=new u(g(v,E,T)),I=0,J=T>0?E-4:E,D=0;D>16&255,O[I++]=_>>8&255,O[I++]=_&255;return T===2&&(_=a[v.charCodeAt(D)]<<2|a[v.charCodeAt(D+1)]>>4,O[I++]=_&255),T===1&&(_=a[v.charCodeAt(D)]<<10|a[v.charCodeAt(D+1)]<<4|a[v.charCodeAt(D+2)]>>2,O[I++]=_>>8&255,O[I++]=_&255),O}function w(v){return s[v>>18&63]+s[v>>12&63]+s[v>>6&63]+s[v&63]}function C(v,_,k){for(var E,T=[],O=_;OJ?J:I+O));return E===1?(_=v[k-1],T.push(s[_>>2]+s[_<<4&63]+"==")):E===2&&(_=(v[k-2]<<8)+v[k-1],T.push(s[_>>10]+s[_>>4&63]+s[_<<2&63]+"=")),T.join("")}},{}],9:[function(o,n,i){function s(a,u){this.offset=a,this.nbits=u}i.kBlockLengthPrefixCode=[new s(1,2),new s(5,2),new s(9,2),new s(13,2),new s(17,3),new s(25,3),new s(33,3),new s(41,3),new s(49,4),new s(65,4),new s(81,4),new s(97,4),new s(113,5),new s(145,5),new s(177,5),new s(209,5),new s(241,6),new s(305,6),new s(369,7),new s(497,8),new s(753,9),new s(1265,10),new s(2289,11),new s(4337,12),new s(8433,13),new s(16625,24)],i.kInsertLengthPrefixCode=[new s(0,0),new s(1,0),new s(2,0),new s(3,0),new s(4,0),new s(5,0),new s(6,1),new s(8,1),new s(10,2),new s(14,2),new s(18,3),new s(26,3),new s(34,4),new s(50,4),new s(66,5),new s(98,5),new s(130,6),new s(194,7),new s(322,8),new s(578,9),new s(1090,10),new s(2114,12),new s(6210,14),new s(22594,24)],i.kCopyLengthPrefixCode=[new s(2,0),new s(3,0),new s(4,0),new s(5,0),new s(6,0),new s(7,0),new s(8,0),new s(9,0),new s(10,1),new s(12,1),new s(14,2),new s(18,2),new s(22,3),new s(30,3),new s(38,4),new s(54,4),new s(70,5),new s(102,5),new s(134,6),new s(198,7),new s(326,8),new s(582,9),new s(1094,10),new s(2118,24)],i.kInsertRangeLut=[0,0,8,8,0,16,8,16,16],i.kCopyRangeLut=[0,8,0,8,16,0,16,8,16]},{}],10:[function(o,n,i){function s(u){this.buffer=u,this.pos=0}s.prototype.read=function(u,l,c){this.pos+c>this.buffer.length&&(c=this.buffer.length-this.pos);for(var m=0;mthis.buffer.length)throw new Error("Output buffer is not large enough");return this.buffer.set(u.subarray(0,l),this.pos),this.pos+=l,l},i.BrotliOutput=a},{}],11:[function(o,n,i){var s=o("./dictionary"),a=0,u=1,l=2,c=3,m=4,d=5,h=6,g=7,b=8,w=9,C=10,x=11,v=12,_=13,k=14,E=15,T=16,O=17,I=18,J=19,D=20;function S(A,N,q){this.prefix=new Uint8Array(A.length),this.transform=N,this.suffix=new Uint8Array(q.length);for(var U=0;U'),new S("",a,` -`),new S("",c,""),new S("",a,"]"),new S("",a," for "),new S("",k,""),new S("",l,""),new S("",a," a "),new S("",a," that "),new S(" ",C,""),new S("",a,". "),new S(".",a,""),new S(" ",a,", "),new S("",E,""),new S("",a," with "),new S("",a,"'"),new S("",a," from "),new S("",a," by "),new S("",T,""),new S("",O,""),new S(" the ",a,""),new S("",m,""),new S("",a,". The "),new S("",x,""),new S("",a," on "),new S("",a," as "),new S("",a," is "),new S("",g,""),new S("",u,"ing "),new S("",a,` - `),new S("",a,":"),new S(" ",a,". "),new S("",a,"ed "),new S("",D,""),new S("",I,""),new S("",h,""),new S("",a,"("),new S("",C,", "),new S("",b,""),new S("",a," at "),new S("",a,"ly "),new S(" the ",a," of "),new S("",d,""),new S("",w,""),new S(" ",C,", "),new S("",C,'"'),new S(".",a,"("),new S("",x," "),new S("",C,'">'),new S("",a,'="'),new S(" ",a,"."),new S(".com/",a,""),new S(" the ",a," of the "),new S("",C,"'"),new S("",a,". This "),new S("",a,","),new S(".",a," "),new S("",C,"("),new S("",C,"."),new S("",a," not "),new S(" ",a,'="'),new S("",a,"er "),new S(" ",x," "),new S("",a,"al "),new S(" ",x,""),new S("",a,"='"),new S("",x,'"'),new S("",C,". "),new S(" ",a,"("),new S("",a,"ful "),new S(" ",C,". "),new S("",a,"ive "),new S("",a,"less "),new S("",x,"'"),new S("",a,"est "),new S(" ",C,"."),new S("",x,'">'),new S(" ",a,"='"),new S("",C,","),new S("",a,"ize "),new S("",x,"."),new S("\xC2\xA0",a,""),new S(" ",a,","),new S("",C,'="'),new S("",x,'="'),new S("",a,"ous "),new S("",x,", "),new S("",C,"='"),new S(" ",C,","),new S(" ",x,'="'),new S(" ",x,", "),new S("",x,","),new S("",x,"("),new S("",x,". "),new S(" ",x,"."),new S("",x,"='"),new S(" ",x,". "),new S(" ",C,'="'),new S(" ",x,"='"),new S(" ",C,"='")];i.kTransforms=L,i.kNumTransforms=L.length;function Y(A,N){return A[N]<192?(A[N]>=97&&A[N]<=122&&(A[N]^=32),1):A[N]<224?(A[N+1]^=32,2):(A[N+2]^=5,3)}i.transformDictionaryWord=function(A,N,q,U,R){var B=L[R].prefix,re=L[R].suffix,P=L[R].transform,W=PU&&(W=U);for(var be=0;be0;){var ye=Y(A,se);se+=ye,U-=ye}for(var $=0;$typeof Wt<"u"?Wt:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof Wt<"u"?Wt:t)[r]}):e)(function(e){if(typeof Wt<"u")return Wt.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')}),wy=(function(){var e,t,r;return(function(){function o(n,i,s){function a(c,m){if(!i[c]){if(!n[c]){var d=typeof la=="function"&&la;if(!m&&d)return d(c,!0);if(u)return u(c,!0);var h=new Error("Cannot find module '"+c+"'");throw h.code="MODULE_NOT_FOUND",h}var g=i[c]={exports:{}};n[c][0].call(g.exports,function(b){var w=n[c][1][b];return a(w||b)},g,g.exports,o,n,i,s)}return i[c].exports}for(var u=typeof la=="function"&&la,l=0;l=252?6:c>=248?5:c>=240?4:c>=224?3:c>=192?2:1;l[254]=l[254]=1,i.string2buf=function(d){var h,g,b,w,C,x=d.length,v=0;for(w=0;w>>6,h[C++]=128|g&63):g<65536?(h[C++]=224|g>>>12,h[C++]=128|g>>>6&63,h[C++]=128|g&63):(h[C++]=240|g>>>18,h[C++]=128|g>>>12&63,h[C++]=128|g>>>6&63,h[C++]=128|g&63);return h};function m(d,h){if(h<65534&&(d.subarray&&u||!d.subarray&&a))return String.fromCharCode.apply(null,s.shrinkBuf(d,h));for(var g="",b=0;b4){v[b++]=65533,g+=C-1;continue}for(w&=C===2?31:C===3?15:7;C>1&&g1){v[b++]=65533;continue}w<65536?v[b++]=w:(w-=65536,v[b++]=55296|w>>10&1023,v[b++]=56320|w&1023)}return m(v,b)},i.utf8border=function(d,h){var g;for(h=h||d.length,h>d.length&&(h=d.length),g=h-1;g>=0&&(d[g]&192)===128;)g--;return g<0||g===0?h:g+l[d[g]]>h?g:h}},{"./common":1}],3:[function(o,n,i){"use strict";function s(a,u,l,c){for(var m=a&65535|0,d=a>>>16&65535|0,h=0;l!==0;){h=l>2e3?2e3:l,l-=h;do m=m+u[c++]|0,d=d+m|0;while(--h);m%=65521,d%=65521}return m|d<<16|0}n.exports=s},{}],4:[function(o,n,i){"use strict";n.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],5:[function(o,n,i){"use strict";function s(){for(var l,c=[],m=0;m<256;m++){l=m;for(var d=0;d<8;d++)l=l&1?3988292384^l>>>1:l>>>1;c[m]=l}return c}var a=s();function u(l,c,m,d){var h=a,g=d+m;l^=-1;for(var b=d;b>>8^h[(l^c[b])&255];return l^-1}n.exports=u},{}],6:[function(o,n,i){"use strict";function s(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}n.exports=s},{}],7:[function(o,n,i){"use strict";var s=30,a=12;n.exports=function(l,c){var m,d,h,g,b,w,C,x,v,_,k,E,T,O,I,J,D,S,L,Y,A,N,q,U,R;m=l.state,d=l.next_in,U=l.input,h=d+(l.avail_in-5),g=l.next_out,R=l.output,b=g-(c-l.avail_out),w=g+(l.avail_out-257),C=m.dmax,x=m.wsize,v=m.whave,_=m.wnext,k=m.window,E=m.hold,T=m.bits,O=m.lencode,I=m.distcode,J=(1<>>24,E>>>=L,T-=L,L=S>>>16&255,L===0)R[g++]=S&65535;else if(L&16){Y=S&65535,L&=15,L&&(T>>=L,T-=L),T<15&&(E+=U[d++]<>>24,E>>>=L,T-=L,L=S>>>16&255,L&16){if(A=S&65535,L&=15,TC){l.msg="invalid distance too far back",m.mode=s;break e}if(E>>>=L,T-=L,L=g-b,A>L){if(L=A-L,L>v&&m.sane){l.msg="invalid distance too far back",m.mode=s;break e}if(N=0,q=k,_===0){if(N+=x-L,L2;)R[g++]=q[N++],R[g++]=q[N++],R[g++]=q[N++],Y-=3;Y&&(R[g++]=q[N++],Y>1&&(R[g++]=q[N++]))}else{N=g-A;do R[g++]=R[N++],R[g++]=R[N++],R[g++]=R[N++],Y-=3;while(Y>2);Y&&(R[g++]=R[N++],Y>1&&(R[g++]=R[N++]))}}else if((L&64)===0){S=I[(S&65535)+(E&(1<>3,d-=Y,T-=Y<<3,E&=(1<>>24&255)+(F>>>8&65280)+((F&65280)<<8)+((F&255)<<24)}function Ne(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new s.Buf16(320),this.work=new s.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function He(F){var G;return!F||!F.state?_:(G=F.state,F.total_in=F.total_out=G.total=0,F.msg="",G.wrap&&(F.adler=G.wrap&1),G.mode=I,G.last=0,G.havedict=0,G.dmax=32768,G.head=null,G.hold=0,G.bits=0,G.lencode=G.lendyn=new s.Buf32(fe),G.distcode=G.distdyn=new s.Buf32(me),G.sane=1,G.back=-1,C)}function ot(F){var G;return!F||!F.state?_:(G=F.state,G.wsize=0,G.whave=0,G.wnext=0,He(F))}function Ze(F,G){var y,oe;return!F||!F.state||(oe=F.state,G<0?(y=0,G=-G):(y=(G>>4)+1,G<48&&(G&=15)),G&&(G<8||G>15))?_:(oe.window!==null&&oe.wbits!==G&&(oe.window=null),oe.wrap=y,oe.wbits=G,ot(F))}function Be(F,G){var y,oe;return F?(oe=new Ne,F.state=oe,oe.window=null,y=Ze(F,G),y!==C&&(F.state=null),y):_}function Ue(F){return Be(F,V)}var ct=!0,Se,Pr;function $t(F){if(ct){var G;for(Se=new s.Buf32(512),Pr=new s.Buf32(32),G=0;G<144;)F.lens[G++]=8;for(;G<256;)F.lens[G++]=9;for(;G<280;)F.lens[G++]=7;for(;G<288;)F.lens[G++]=8;for(c(d,F.lens,0,288,Se,0,F.work,{bits:9}),G=0;G<32;)F.lens[G++]=5;c(h,F.lens,0,32,Pr,0,F.work,{bits:5}),ct=!1}F.lencode=Se,F.lenbits=9,F.distcode=Pr,F.distbits=5}function Ye(F,G,y,oe){var Ae,ee=F.state;return ee.window===null&&(ee.wsize=1<=ee.wsize?(s.arraySet(ee.window,G,y-ee.wsize,ee.wsize,0),ee.wnext=0,ee.whave=ee.wsize):(Ae=ee.wsize-ee.wnext,Ae>oe&&(Ae=oe),s.arraySet(ee.window,G,y-oe,Ae,ee.wnext),oe-=Ae,oe?(s.arraySet(ee.window,G,y-oe,oe,0),ee.wnext=oe,ee.whave=ee.wsize):(ee.wnext+=Ae,ee.wnext===ee.wsize&&(ee.wnext=0),ee.whave>>8&255,y.check=u(y.check,ft,2,0),j=0,z=0,y.mode=J;break}if(y.flags=0,y.head&&(y.head.done=!1),!(y.wrap&1)||(((j&255)<<8)+(j>>8))%31){F.msg="incorrect header check",y.mode=Q;break}if((j&15)!==O){F.msg="unknown compression method",y.mode=Q;break}if(j>>>=4,z-=4,at=(j&15)+8,y.wbits===0)y.wbits=at;else if(at>y.wbits){F.msg="invalid window size",y.mode=Q;break}y.dmax=1<>8&1),y.flags&512&&(ft[0]=j&255,ft[1]=j>>>8&255,y.check=u(y.check,ft,2,0)),j=0,z=0,y.mode=D;case D:for(;z<32;){if(ie===0)break e;ie--,j+=oe[ee++]<>>8&255,ft[2]=j>>>16&255,ft[3]=j>>>24&255,y.check=u(y.check,ft,4,0)),j=0,z=0,y.mode=S;case S:for(;z<16;){if(ie===0)break e;ie--,j+=oe[ee++]<>8),y.flags&512&&(ft[0]=j&255,ft[1]=j>>>8&255,y.check=u(y.check,ft,2,0)),j=0,z=0,y.mode=L;case L:if(y.flags&1024){for(;z<16;){if(ie===0)break e;ie--,j+=oe[ee++]<>>8&255,y.check=u(y.check,ft,2,0)),j=0,z=0}else y.head&&(y.head.extra=null);y.mode=Y;case Y:if(y.flags&1024&&(ce=y.length,ce>ie&&(ce=ie),ce&&(y.head&&(at=y.head.extra_len-y.length,y.head.extra||(y.head.extra=new Array(y.head.extra_len)),s.arraySet(y.head.extra,oe,ee,ce,at)),y.flags&512&&(y.check=u(y.check,oe,ce,ee)),ie-=ce,ee+=ce,y.length-=ce),y.length))break e;y.length=0,y.mode=A;case A:if(y.flags&2048){if(ie===0)break e;ce=0;do at=oe[ee+ce++],y.head&&at&&y.length<65536&&(y.head.name+=String.fromCharCode(at));while(at&&ce>9&1,y.head.done=!0),F.adler=y.check=0,y.mode=B;break;case U:for(;z<32;){if(ie===0)break e;ie--,j+=oe[ee++]<>>=z&7,z-=z&7,y.mode=M;break}for(;z<3;){if(ie===0)break e;ie--,j+=oe[ee++]<>>=1,z-=1,j&3){case 0:y.mode=P;break;case 1:if($t(y),y.mode=ye,G===w){j>>>=2,z-=2;break e}break;case 2:y.mode=xe;break;case 3:F.msg="invalid block type",y.mode=Q}j>>>=2,z-=2;break;case P:for(j>>>=z&7,z-=z&7;z<32;){if(ie===0)break e;ie--,j+=oe[ee++]<>>16^65535)){F.msg="invalid stored block lengths",y.mode=Q;break}if(y.length=j&65535,j=0,z=0,y.mode=W,G===w)break e;case W:y.mode=ne;case ne:if(ce=y.length,ce){if(ce>ie&&(ce=ie),ce>Je&&(ce=Je),ce===0)break e;s.arraySet(Ae,oe,ee,ce,Qe),ie-=ce,ee+=ce,Je-=ce,Qe+=ce,y.length-=ce;break}y.mode=B;break;case xe:for(;z<14;){if(ie===0)break e;ie--,j+=oe[ee++]<>>=5,z-=5,y.ndist=(j&31)+1,j>>>=5,z-=5,y.ncode=(j&15)+4,j>>>=4,z-=4,y.nlen>286||y.ndist>30){F.msg="too many length or distance symbols",y.mode=Q;break}y.have=0,y.mode=se;case se:for(;y.have>>=3,z-=3}for(;y.have<19;)y.lens[en[y.have++]]=0;if(y.lencode=y.lendyn,y.lenbits=7,At={bits:y.lenbits},Ft=c(m,y.lens,0,19,y.lencode,0,y.work,At),y.lenbits=At.bits,Ft){F.msg="invalid code lengths set",y.mode=Q;break}y.have=0,y.mode=be;case be:for(;y.have>>24,$e=et>>>16&255,ut=et&65535,!(Me<=z);){if(ie===0)break e;ie--,j+=oe[ee++]<>>=Me,z-=Me,y.lens[y.have++]=ut;else{if(ut===16){for(Ht=Me+2;z>>=Me,z-=Me,y.have===0){F.msg="invalid bit length repeat",y.mode=Q;break}at=y.lens[y.have-1],ce=3+(j&3),j>>>=2,z-=2}else if(ut===17){for(Ht=Me+3;z>>=Me,z-=Me,at=0,ce=3+(j&7),j>>>=3,z-=3}else{for(Ht=Me+7;z>>=Me,z-=Me,at=0,ce=11+(j&127),j>>>=7,z-=7}if(y.have+ce>y.nlen+y.ndist){F.msg="invalid bit length repeat",y.mode=Q;break}for(;ce--;)y.lens[y.have++]=at}}if(y.mode===Q)break;if(y.lens[256]===0){F.msg="invalid code -- missing end-of-block",y.mode=Q;break}if(y.lenbits=9,At={bits:y.lenbits},Ft=c(d,y.lens,0,y.nlen,y.lencode,0,y.work,At),y.lenbits=At.bits,Ft){F.msg="invalid literal/lengths set",y.mode=Q;break}if(y.distbits=6,y.distcode=y.distdyn,At={bits:y.distbits},Ft=c(h,y.lens,y.nlen,y.ndist,y.distcode,0,y.work,At),y.distbits=At.bits,Ft){F.msg="invalid distances set",y.mode=Q;break}if(y.mode=ye,G===w)break e;case ye:y.mode=$;case $:if(ie>=6&&Je>=258){F.next_out=Qe,F.avail_out=Je,F.next_in=ee,F.avail_in=ie,y.hold=j,y.bits=z,l(F,je),Qe=F.next_out,Ae=F.output,Je=F.avail_out,ee=F.next_in,oe=F.input,ie=F.avail_in,j=y.hold,z=y.bits,y.mode===B&&(y.back=-1);break}for(y.back=0;et=y.lencode[j&(1<>>24,$e=et>>>16&255,ut=et&65535,!(Me<=z);){if(ie===0)break e;ie--,j+=oe[ee++]<>pt)],Me=et>>>24,$e=et>>>16&255,ut=et&65535,!(pt+Me<=z);){if(ie===0)break e;ie--,j+=oe[ee++]<>>=pt,z-=pt,y.back+=pt}if(j>>>=Me,z-=Me,y.back+=Me,y.length=ut,$e===0){y.mode=X;break}if($e&32){y.back=-1,y.mode=B;break}if($e&64){F.msg="invalid literal/length code",y.mode=Q;break}y.extra=$e&15,y.mode=_e;case _e:if(y.extra){for(Ht=y.extra;z>>=y.extra,z-=y.extra,y.back+=y.extra}y.was=y.length,y.mode=Fe;case Fe:for(;et=y.distcode[j&(1<>>24,$e=et>>>16&255,ut=et&65535,!(Me<=z);){if(ie===0)break e;ie--,j+=oe[ee++]<>pt)],Me=et>>>24,$e=et>>>16&255,ut=et&65535,!(pt+Me<=z);){if(ie===0)break e;ie--,j+=oe[ee++]<>>=pt,z-=pt,y.back+=pt}if(j>>>=Me,z-=Me,y.back+=Me,$e&64){F.msg="invalid distance code",y.mode=Q;break}y.offset=ut,y.extra=$e&15,y.mode=xt;case xt:if(y.extra){for(Ht=y.extra;z>>=y.extra,z-=y.extra,y.back+=y.extra}if(y.offset>y.dmax){F.msg="invalid distance too far back",y.mode=Q;break}y.mode=Le;case Le:if(Je===0)break e;if(ce=je-Je,y.offset>ce){if(ce=y.offset-ce,ce>y.whave&&y.sane){F.msg="invalid distance too far back",y.mode=Q;break}ce>y.wnext?(ce-=y.wnext,br=y.wsize-ce):br=y.wnext-ce,ce>y.length&&(ce=y.length),Or=y.window}else Or=Ae,br=Qe-y.offset,ce=y.length;ce>Je&&(ce=Je),Je-=ce,y.length-=ce;do Ae[Qe++]=Or[br++];while(--ce);y.length===0&&(y.mode=$);break;case X:if(Je===0)break e;Ae[Qe++]=y.length,Je--,y.mode=$;break;case M:if(y.wrap){for(;z<32;){if(ie===0)break e;ie--,j|=oe[ee++]<=1&&$[Y]===0;Y--);if(A>Y&&(A=Y),Y===0)return E[T++]=1<<24|64<<16|0,E[T++]=1<<24|64<<16|0,I.bits=1,0;for(L=1;L0&&(x===c||Y!==1))return-1;for(_e[1]=0,D=1;Du||x===d&&R>l)return 1;for(;;){Le=D-q,O[S]ye?(X=Fe[xt+O[S]],M=se[be+O[S]]):(X=96,M=0),re=1<>q)+P]=Le<<24|X<<16|M|0;while(P!==0);for(re=1<>=1;if(re!==0?(B&=re-1,B+=re):B=0,S++,--$[D]===0){if(D===Y)break;D=v[_+O[S]]}if(D>A&&(B&ne)!==W){for(q===0&&(q=A),xe+=L,N=D-q,U=1<u||x===d&&R>l)return 1;W=B&ne,E[W]=A<<24|N<<16|xe-T|0}}return B!==0&&(E[xe+B]=D-q<<24|64<<16|0),I.bits=A,0}},{"../utils/common":1}],10:[function(o,n,i){"use strict";n.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],11:[function(o,n,i){"use strict";function s(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}n.exports=s},{}],"/lib/inflate.js":[function(o,n,i){"use strict";var s=o("./zlib/inflate"),a=o("./utils/common"),u=o("./utils/strings"),l=o("./zlib/constants"),c=o("./zlib/messages"),m=o("./zlib/zstream"),d=o("./zlib/gzheader"),h=Object.prototype.toString;function g(C){if(!(this instanceof g))return new g(C);this.options=a.assign({chunkSize:16384,windowBits:0,to:""},C||{});var x=this.options;x.raw&&x.windowBits>=0&&x.windowBits<16&&(x.windowBits=-x.windowBits,x.windowBits===0&&(x.windowBits=-15)),x.windowBits>=0&&x.windowBits<16&&!(C&&C.windowBits)&&(x.windowBits+=32),x.windowBits>15&&x.windowBits<48&&(x.windowBits&15)===0&&(x.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new m,this.strm.avail_out=0;var v=s.inflateInit2(this.strm,x.windowBits);if(v!==l.Z_OK)throw new Error(c[v]);if(this.header=new d,s.inflateGetHeader(this.strm,this.header),x.dictionary&&(typeof x.dictionary=="string"?x.dictionary=u.string2buf(x.dictionary):h.call(x.dictionary)==="[object ArrayBuffer]"&&(x.dictionary=new Uint8Array(x.dictionary)),x.raw&&(v=s.inflateSetDictionary(this.strm,x.dictionary),v!==l.Z_OK)))throw new Error(c[v])}g.prototype.push=function(C,x){var v=this.strm,_=this.options.chunkSize,k=this.options.dictionary,E,T,O,I,J,D=!1;if(this.ended)return!1;T=x===~~x?x:x===!0?l.Z_FINISH:l.Z_NO_FLUSH,typeof C=="string"?v.input=u.binstring2buf(C):h.call(C)==="[object ArrayBuffer]"?v.input=new Uint8Array(C):v.input=C,v.next_in=0,v.avail_in=v.input.length;do{if(v.avail_out===0&&(v.output=new a.Buf8(_),v.next_out=0,v.avail_out=_),E=s.inflate(v,l.Z_NO_FLUSH),E===l.Z_NEED_DICT&&k&&(E=s.inflateSetDictionary(this.strm,k)),E===l.Z_BUF_ERROR&&D===!0&&(E=l.Z_OK,D=!1),E!==l.Z_STREAM_END&&E!==l.Z_OK)return this.onEnd(E),this.ended=!0,!1;v.next_out&&(v.avail_out===0||E===l.Z_STREAM_END||v.avail_in===0&&(T===l.Z_FINISH||T===l.Z_SYNC_FLUSH))&&(this.options.to==="string"?(O=u.utf8border(v.output,v.next_out),I=v.next_out-O,J=u.buf2string(v.output,O),v.next_out=I,v.avail_out=_-I,I&&a.arraySet(v.output,v.output,O,I,0),this.onData(J)):this.onData(a.shrinkBuf(v.output,v.next_out))),v.avail_in===0&&v.avail_out===0&&(D=!0)}while((v.avail_in>0||v.avail_out===0)&&E!==l.Z_STREAM_END);return E===l.Z_STREAM_END&&(T=l.Z_FINISH),T===l.Z_FINISH?(E=s.inflateEnd(this.strm),this.onEnd(E),this.ended=!0,E===l.Z_OK):(T===l.Z_SYNC_FLUSH&&(this.onEnd(l.Z_OK),v.avail_out=0),!0)},g.prototype.onData=function(C){this.chunks.push(C)},g.prototype.onEnd=function(C){C===l.Z_OK&&(this.options.to==="string"?this.result=this.chunks.join(""):this.result=a.flattenChunks(this.chunks)),this.chunks=[],this.err=C,this.msg=this.strm.msg};function b(C,x){var v=new g(x);if(v.push(C,!0),v.err)throw v.msg||c[v.err];return v.result}function w(C,x){return x=x||{},x.raw=!0,b(C,x)}i.Inflate=g,i.inflate=b,i.inflateRaw=w,i.ungzip=b},{"./utils/common":1,"./utils/strings":2,"./zlib/constants":4,"./zlib/gzheader":6,"./zlib/inflate":8,"./zlib/messages":10,"./zlib/zstream":11}]},{},[])("/lib/inflate.js")})();var TM=globalThis.fetch,ca=class{constructor(e,t={},r){this.type=e,this.detail=t,this.msg=r,Object.defineProperty(this,"__mayPropagate",{enumerable:!1,writable:!0}),this.__mayPropagate=!0}preventDefault(){}stopPropagation(){this.__mayPropagate=!1}valueOf(){return this}toString(){return this.msg?`[${this.type} event]: ${this.msg}`:`[${this.type} event]`}},FS=class{constructor(){this.listeners={}}addEventListener(e,t,r){let o=this.listeners[e]||[];r?o.unshift(t):o.push(t),this.listeners[e]=o}removeEventListener(e,t){let r=this.listeners[e]||[],o=r.findIndex(n=>n===t);o>-1&&(r.splice(o,1),this.listeners[e]=r)}dispatch(e){let t=this.listeners[e.type];if(t)for(let r=0,o=t.length;rString.fromCharCode(t)).join("")}var LS=class{constructor(e,t,r){this.name=(r||e.tag||"").trim(),this.length=e.length,this.start=e.offset,this.offset=0,this.data=t,["getInt8","getUint8","getInt16","getUint16","getInt32","getUint32","getBigInt64","getBigUint64"].forEach(o=>{let n=o.replace(/get(Big)?/,"").toLowerCase(),i=parseInt(o.replace(/[^\d]/g,""))/8;Object.defineProperty(this,n,{get:()=>this.getValue(o,i)})})}get currentPosition(){return this.start+this.offset}set currentPosition(e){this.start=e,this.offset=0}skip(e=0,t=8){this.offset+=e*t/8}getValue(e,t){let r=this.start+this.offset;this.offset+=t;try{return this.data[e](r)}catch(o){throw console.error("parser",e,t,this),console.error("parser",this.start,this.offset),o}}flags(e){if(e===8||e===16||e===32||e===64)return this[`uint${e}`].toString(2).padStart(e,0).split("").map(t=>t==="1");console.error("Error parsing flags: flag types can only be 1, 2, 4, or 8 bytes long"),console.trace()}get tag(){let e=this.uint32;return IS([e>>24&255,e>>16&255,e>>8&255,e&255])}get fixed(){let e=this.int16,t=Math.round(1e3*this.uint16/65356);return e+t/1e3}get legacyFixed(){let e=this.uint16,t=this.uint16.toString(16).padStart(4,0);return parseFloat(`${e}.${t}`)}get uint24(){return(this.uint8<<16)+(this.uint8<<8)+this.uint8}get uint128(){let e=0;for(let t=0;t<5;t++){let r=this.uint8;if(e=e*128+(r&127),r<128)break}return e}get longdatetime(){return new Date(AS+1e3*parseInt(this.int64.toString()))}get fword(){return this.int16}get ufword(){return this.uint16}get Offset16(){return this.uint16}get Offset32(){return this.uint32}get F2DOT14(){let e=p.uint16,t=[0,1,-2,-1][e>>14],r=e&16383;return t+r/16384}verifyLength(){this.offset!=this.length&&console.error(`unexpected parsed table size (${this.offset}) for "${this.name}" (expected ${this.length})`)}readBytes(e=0,t=0,r=8,o=!1){if(e=e||this.length,e===0)return[];t&&(this.currentPosition=t);let n=`${o?"":"u"}int${r}`,i=[];for(;e--;)i.push(this[n]);return i}},lt=class{constructor(e){Object.defineProperty(this,"parser",{enumerable:!1,get:()=>e});let r=e.currentPosition;Object.defineProperty(this,"start",{enumerable:!1,get:()=>r})}load(e){Object.keys(e).forEach(t=>{let r=Object.getOwnPropertyDescriptor(e,t);r.get?this[t]=r.get.bind(this):r.value!==void 0&&(this[t]=r.value)}),this.parser.length&&this.parser.verifyLength()}},ke=class extends lt{constructor(e,t,r){let{parser:o,start:n}=super(new LS(e,t,r));Object.defineProperty(this,"p",{enumerable:!1,get:()=>o}),Object.defineProperty(this,"tableStart",{enumerable:!1,get:()=>n})}};function ae(e,t,r){let o;Object.defineProperty(e,t,{get:()=>o||(o=r(),o),enumerable:!0})}var NS=class extends ke{constructor(e,t,r){let{p:o}=super({offset:0,length:12},t,"sfnt");this.version=o.uint32,this.numTables=o.uint16,this.searchRange=o.uint16,this.entrySelector=o.uint16,this.rangeShift=o.uint16,o.verifyLength(),this.directory=[...new Array(this.numTables)].map(n=>new MS(o)),this.tables={},this.directory.forEach(n=>{let i=()=>r(this.tables,{tag:n.tag,offset:n.offset,length:n.length},t);ae(this.tables,n.tag.trim(),i)})}},MS=class{constructor(e){this.tag=e.tag,this.checksum=e.uint32,this.offset=e.uint32,this.length=e.uint32}},xy=wy.inflate||void 0,Sy=void 0,VS=class extends ke{constructor(e,t,r){let{p:o}=super({offset:0,length:44},t,"woff");this.signature=o.tag,this.flavor=o.uint32,this.length=o.uint32,this.numTables=o.uint16,o.uint16,this.totalSfntSize=o.uint32,this.majorVersion=o.uint16,this.minorVersion=o.uint16,this.metaOffset=o.uint32,this.metaLength=o.uint32,this.metaOrigLength=o.uint32,this.privOffset=o.uint32,this.privLength=o.uint32,o.verifyLength(),this.directory=[...new Array(this.numTables)].map(n=>new DS(o)),BS(this,t,r)}},DS=class{constructor(e){this.tag=e.tag,this.offset=e.uint32,this.compLength=e.uint32,this.origLength=e.uint32,this.origChecksum=e.uint32}};function BS(e,t,r){e.tables={},e.directory.forEach(o=>{ae(e.tables,o.tag.trim(),()=>{let n=0,i=t;if(o.compLength!==o.origLength){let s=t.buffer.slice(o.offset,o.offset+o.compLength),a;if(xy)a=xy(new Uint8Array(s));else if(Sy)a=Sy(new Uint8Array(s));else{let u="no brotli decoder available to decode WOFF2 font";throw font.onerror&&font.onerror(u),new Error(u)}i=new DataView(a.buffer)}else n=o.offset;return r(e.tables,{tag:o.tag,offset:n,length:o.origLength},i)})})}var Cy=by,_y=void 0,jS=class extends ke{constructor(e,t,r){let{p:o}=super({offset:0,length:48},t,"woff2");this.signature=o.tag,this.flavor=o.uint32,this.length=o.uint32,this.numTables=o.uint16,o.uint16,this.totalSfntSize=o.uint32,this.totalCompressedSize=o.uint32,this.majorVersion=o.uint16,this.minorVersion=o.uint16,this.metaOffset=o.uint32,this.metaLength=o.uint32,this.metaOrigLength=o.uint32,this.privOffset=o.uint32,this.privLength=o.uint32,o.verifyLength(),this.directory=[...new Array(this.numTables)].map(a=>new zS(o));let n=o.currentPosition;this.directory[0].offset=0,this.directory.forEach((a,u)=>{let l=this.directory[u+1];l&&(l.offset=a.offset+(a.transformLength!==void 0?a.transformLength:a.origLength))});let i,s=t.buffer.slice(n);if(Cy)i=Cy(new Uint8Array(s));else if(_y)i=new Uint8Array(_y(s));else{let a="no brotli decoder available to decode WOFF2 font";throw e.onerror&&e.onerror(a),new Error(a)}HS(this,i,r)}},zS=class{constructor(e){this.flags=e.uint8;let t=this.tagNumber=this.flags&63;t===63?this.tag=e.tag:this.tag=US(t);let o=(this.transformVersion=(this.flags&192)>>6)!==0;(this.tag==="glyf"||this.tag==="loca")&&(o=this.transformVersion!==3),this.origLength=e.uint128,o&&(this.transformLength=e.uint128)}};function HS(e,t,r){e.tables={},e.directory.forEach(o=>{ae(e.tables,o.tag.trim(),()=>{let n=o.offset,i=n+(o.transformLength?o.transformLength:o.origLength),s=new DataView(t.slice(n,i).buffer);try{return r(e.tables,{tag:o.tag,offset:0,length:o.origLength},s)}catch(a){console.error(a)}})})}function US(e){return["cmap","head","hhea","hmtx","maxp","name","OS/2","post","cvt ","fpgm","glyf","loca","prep","CFF ","VORG","EBDT","EBLC","gasp","hdmx","kern","LTSH","PCLT","VDMX","vhea","vmtx","BASE","GDEF","GPOS","GSUB","EBSC","JSTF","MATH","CBDT","CBLC","COLR","CPAL","SVG ","sbix","acnt","avar","bdat","bloc","bsln","cvar","fdsc","feat","fmtx","fvar","gvar","hsty","just","lcar","mort","morx","opbd","prop","trak","Zapf","Silf","Glat","Gloc","Feat","Sill"][e&63]}var Fy={},Ay=!1;Promise.all([Promise.resolve().then(function(){return yC}),Promise.resolve().then(function(){return bC}),Promise.resolve().then(function(){return xC}),Promise.resolve().then(function(){return _C}),Promise.resolve().then(function(){return EC}),Promise.resolve().then(function(){return FC}),Promise.resolve().then(function(){return IC}),Promise.resolve().then(function(){return NC}),Promise.resolve().then(function(){return GC}),Promise.resolve().then(function(){return r_}),Promise.resolve().then(function(){return U_}),Promise.resolve().then(function(){return G_}),Promise.resolve().then(function(){return X_}),Promise.resolve().then(function(){return $_}),Promise.resolve().then(function(){return tR}),Promise.resolve().then(function(){return oR}),Promise.resolve().then(function(){return sR}),Promise.resolve().then(function(){return lR}),Promise.resolve().then(function(){return uR}),Promise.resolve().then(function(){return dR}),Promise.resolve().then(function(){return mR}),Promise.resolve().then(function(){return gR}),Promise.resolve().then(function(){return bR}),Promise.resolve().then(function(){return SR}),Promise.resolve().then(function(){return CR}),Promise.resolve().then(function(){return RR}),Promise.resolve().then(function(){return TR}),Promise.resolve().then(function(){return OR}),Promise.resolve().then(function(){return FR}),Promise.resolve().then(function(){return LR}),Promise.resolve().then(function(){return jR}),Promise.resolve().then(function(){return WR}),Promise.resolve().then(function(){return qR}),Promise.resolve().then(function(){return JR}),Promise.resolve().then(function(){return $R}),Promise.resolve().then(function(){return t2}),Promise.resolve().then(function(){return n2}),Promise.resolve().then(function(){return s2}),Promise.resolve().then(function(){return f2}),Promise.resolve().then(function(){return p2}),Promise.resolve().then(function(){return g2})]).then(e=>{e.forEach(t=>{let r=Object.keys(t)[0];Fy[r]=t[r]}),Ay=!0});function WS(e,t,r){let o=t.tag.replace(/[^\w\d]/g,""),n=Fy[o];return n?new n(t,r,e):(console.warn(`lib-font has no definition for ${o}. The table was skipped.`),{})}function GS(){let e=0;function t(r,o){if(!Ay)return e>10?o(new Error("loading took too long")):(e++,setTimeout(()=>t(r),250));r(WS)}return new Promise((r,o)=>t(r))}function YS(e,t){let r=e.lastIndexOf("."),o=(e.substring(r+1)||"").toLowerCase(),n={ttf:"truetype",otf:"opentype",woff:"woff",woff2:"woff2"}[o];if(n)return n;let i={eot:"The .eot format is not supported: it died in January 12, 2016, when Microsoft retired all versions of IE that didn't already support WOFF.",svg:"The .svg format is not supported: SVG fonts (not to be confused with OpenType with embedded SVG) were so bad we took the entire fonts chapter out of the SVG specification again.",fon:"The .fon format is not supported: this is an ancient Windows bitmap font format.",ttc:"Based on the current CSS specification, font collections are not (yet?) supported."}[o];if(i||(i=`${e} is not a known webfont format.`),t)throw new Error(i);console.warn(`Could not load font: ${i}`)}async function qS(e,t,r={}){if(!globalThis.document)return;let o=YS(t,r.errorOnStyle);if(!o)return;let n=document.createElement("style");n.className="injected-by-Font-js";let i=[];return r.styleRules&&(i=Object.entries(r.styleRules).map(([s,a])=>`${s}: ${a};`)),n.textContent=` +`}var Nh={mobile:"480px",tablet:"782px"},Mh=/^(\d+|\d*\.\d+)(px|em|rem)$/,sx=16;function ax(e){return"mobile"in e||"tablet"in e}function lx(e){return!e||typeof e!="object"?{}:ax(e)?e:e.settings?.viewport??{}}function cx(e){return typeof e=="string"&&Mh.test(e.trim())}function Rc(e){if(typeof e=="number")return e;if(typeof e!="string")return;let t=e.trim().match(Mh);if(!t)return;let r=Number.parseFloat(t[1]);return t[2]==="px"?r:r*sx}function Ec(e){let t=lx(e),r={},o={};Object.keys(Nh).forEach(a=>{let u=a,l=t[u],c=Rc(l);c!==void 0&&cx(l)&&(r[u]=l.trim(),o[u]=c)});let n=Object.keys(r);if(!n.length)return{...Nh};if(n.length===1)return r;let i=r.mobile,s=r.tablet;return o.mobile>=o.tablet?{mobile:i}:{mobile:i,tablet:s}}function Vh(e){let t=Ec(e),r={};return t.mobile&&(r["@mobile"]=`@media (width <= ${t.mobile})`),t.tablet&&(r["@tablet"]=t.mobile?`@media (${t.mobile} < width <= ${t.tablet})`:`@media (width <= ${t.tablet})`),r}function Bs(e,t,r,{resolveRefs:o=!0}={}){if(!e?.styles?.blocks?.[t]?.variations?.[r])return;let n=s=>{Object.keys(s).forEach(a=>{let u=s[a];if(typeof u=="object"&&u!==null)if(u.ref!==void 0)if(typeof u.ref!="string"||u.ref.trim()==="")delete s[a];else{let l=ht(e,u.ref);l!=null?s[a]=l:delete s[a]}else n(u),Object.keys(u).length===0&&delete s[a]})},i=JSON.parse(JSON.stringify(e.styles.blocks[t].variations[r]));return o&&n(i),i}var Oc="default";function zh(e){let t=e?.viewport,r=e?.pseudoState;return(!t||t===Oc)&&(!r||r===Oc)}function ux(e){return zh(e)?[]:[e.viewport,e.pseudoState].filter(t=>!!t&&t!==Oc)}function fx(e,t){let r=ux(t);return r.length?ht(e,r):e}var dx=new Set(["blocks","variations","css"]),Tc=Object.freeze({value:{},sources:{}}),px={root:{layer:"root"},element:{layer:"element"},block:{layer:"block"},blockVariation:{layer:"blockVariation"}};function wo(e){let t=px[e];return t?{...t}:null}function xo(e,t){return!e||!t?null:{styles:e,source:t}}function mx(e){return e.join(".")}function hx(e){return{...e}}function Hh(e){return e===""||e===null||typeof e=="object"&&!Array.isArray(e)&&Object.keys(e).length===0}function Pc(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)&&typeof e.ref=="string"}function So(e){if(!e||typeof e!="object"||Array.isArray(e))return null;let t={};for(let r of Object.keys(e))if(!dx.has(r)){if(r==="elements"){e.elements&&typeof e.elements=="object"&&(t.elements=e.elements);continue}Hh(e[r])||(t[r]=e[r])}return Object.keys(t).length===0?null:t}var Dh=new Set(["backgroundImage"]);function Uh(e,t,r,o,n,i=[]){if(!t||typeof t!="object"||Array.isArray(t))return e;for(let s of Object.keys(t)){let a=t[s];if(Hh(a))continue;if(Pc(a)){if(a.ref.trim()==="")continue;let l=ht(r,a.ref);if(l==null||Pc(l))continue;a=l}let u=[...i,s];if(!Dh.has(s)&&a!==null&&typeof a=="object"&&!Array.isArray(a)&&!Pc(a)){let l=e[s]&&typeof e[s]=="object"&&!Array.isArray(e[s])?e[s]:{};e[s]=Uh({...l},a,r,o,n,u)}else e[s]=Dh.has(s)&&a!==null&&typeof a=="object"&&!Array.isArray(a)?{...a}:a,o&&n&&(n[mx(u)]=hx(o))}return e}function js(e,t){if(!e)return null;let r=fx(e,t);return r&&typeof r=="object"&&!Array.isArray(r)?r:null}var gx=["color.background","color.gradient","background","spacing","dimensions","border","shadow","filter"];function yx(e){return e.startsWith("elements.")?!1:gx.some(t=>e===t||e.startsWith(`${t}.`))}function Wh(e,t){if(!e||typeof e!="object")return;let[r,...o]=t;if(o.length===0){delete e[r];return}let n=e[r];n&&typeof n=="object"&&(Wh(n,o),Object.keys(n).length===0&&delete e[r])}function vx(e,t){for(let r of Object.keys(t))t[r].layer==="root"&&yx(r)&&(Wh(e,r.split(".")),delete t[r])}function bx(e,t,r){let o=e?.background?.backgroundImage;if(!o)return;let n=bc(o,{...t,_links:r??void 0});n!==void 0&&(e.background.backgroundImage=n)}function Bh(e,{blockName:t,variationName:r=null,elements:o=null,viewport:n=null,pseudoState:i=null}={}){if(!e||!e.styles||!t)return Tc;let s=e.styles,a={viewport:n,pseudoState:i},u=s,l=s.blocks?.[t]??null,c=(o??[]).map(w=>s.elements?.[w]??null).filter(w=>!!w),m=r?Bs(e,t,r)??null:null,d=[xo(So(u),wo("root")),...c.map(w=>xo(So(w),wo("element"))),l?xo(So(l),wo("block")):null,m?xo(So(m),wo("blockVariation")):null];zh(a)||d.push(xo(So(js(u,a)),wo("root")),...c.map(w=>xo(So(js(w,a)),wo("element"))),l?xo(So(js(l,a)),wo("block")):null,m?xo(So(js(m,a)),wo("blockVariation")):null);let h=d.filter(Boolean);if(h.length===0)return Tc;let g={},b=h.reduce((w,_)=>Uh(w,_.styles,e,_.source,g),{});return vx(b,g),bx(b,e,e._links??null),{value:b,sources:g}}var wx={},jh=new WeakMap;function Gh(e,t={}){let r=e?.styles;if(!r||typeof r!="object")return Bh(e,t);let o=jh.get(r);o||(o=new WeakMap,jh.set(r,o));let n=e?._links??wx,i=o.get(n);i||(i=new Map,o.set(n,i));let s=`${t.elements?.join(",")??""}:${t.viewport??""}:${t.pseudoState??""}`,a=(t.blockName||"")+""+(t.variationName||"")+""+s;if(i.has(a))return i.get(a);let u=Bh(e,t);return i.set(a,u),u}var Yh=f(ai(),1),{lock:qh,unlock:mI}=(0,Yh.__dangerousOptInToUnstableAPIsOnlyForCoreModules)("I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.","@wordpress/global-styles-engine");var Tn={};qh(Tn,{getResponsiveMediaQueries:Vh,getViewportBreakpoints:Ec,getViewportBreakpointValueInPixels:Rc,getDuotoneFilter:Lh,getDuotoneStylesheet:Ih,getDuotoneUnsetStylesheet:Ah,resolveStyle:Gh,getVariationStyle:Bs});var kc=f(Te(),1);var Zh=f(Te(),1),gt=(0,Zh.createContext)({user:{styles:{},settings:{}},base:{styles:{},settings:{}},merged:{styles:{},settings:{}},onChange:()=>{},fontLibraryEnabled:!1});var Xh=f(Z(),1);function gi({children:e,value:t,baseValue:r,onChange:o,fontLibraryEnabled:n}){let i=(0,kc.useMemo)(()=>Go(r,t),[r,t]),s=(0,kc.useMemo)(()=>({user:t,base:r,merged:i,onChange:o,fontLibraryEnabled:n}),[t,r,i,o,n]);return(0,Xh.jsx)(gt.Provider,{value:s,children:e})}var eo=f(ue(),1),dg=f(ge(),1);var Lx=f(Kt(),1),Nx=f(sr(),1);var Kh=f(Z(),1);function Fc({className:e,...t}){return(0,Kh.jsx)(ci,{className:We(e,"global-styles-ui-icon-with-current-color"),...t})}var _o=f(ue(),1);var Yo=f(Z(),1);function xx({icon:e,children:t,...r}){return(0,Yo.jsxs)(_o.__experimentalItem,{...r,children:[e&&(0,Yo.jsxs)(_o.__experimentalHStack,{justify:"flex-start",children:[(0,Yo.jsx)(Fc,{icon:e,size:24}),(0,Yo.jsx)(_o.FlexItem,{children:t})]}),!e&&t]})}function Qr(e){return(0,Yo.jsx)(_o.Navigator.Button,{as:xx,...e})}var Cx=f(ue(),1);var Rx=f(ge(),1),rg=f(Dt(),1);var Rr=f(Te(),1),eg=f(Kt(),1),tg=f(sr(),1),Ic=f(ge(),1);var dt=f(ge(),1);var Jh=f(ai(),1),{lock:BI,unlock:De}=(0,Jh.__dangerousOptInToUnstableAPIsOnlyForCoreModules)("I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.","@wordpress/global-styles-ui");var{getViewportBreakpoints:UI}=De(Tn),WI={link:[{value:":link",label:(0,dt.__)("Link")},{value:":any-link",label:(0,dt.__)("Any Link")},{value:":visited",label:(0,dt.__)("Visited")},{value:":hover",label:(0,dt.__)("Hover")},{value:":focus",label:(0,dt.__)("Focus")},{value:":focus-visible",label:(0,dt.__)("Focus-visible")},{value:":active",label:(0,dt.__)("Active")}],button:[{value:":link",label:(0,dt.__)("Link")},{value:":any-link",label:(0,dt.__)("Any Link")},{value:":visited",label:(0,dt.__)("Visited")},{value:":hover",label:(0,dt.__)("Hover")},{value:":focus",label:(0,dt.__)("Focus")},{value:":focus-visible",label:(0,dt.__)("Focus-visible")},{value:":active",label:(0,dt.__)("Active")}]},GI={"core/button":[{value:":hover",label:(0,dt.__)("Hover")},{value:":focus",label:(0,dt.__)("Focus")},{value:":focus-visible",label:(0,dt.__)("Focus-visible")},{value:":active",label:(0,dt.__)("Active")}]},YI=[{value:"@tablet",label:(0,dt.__)("Tablet")},{value:"@mobile",label:(0,dt.__)("Mobile")}];function Ac(e,t){if(!t?.length||typeof e!="object"||!e||!Object.keys(e).length)return e;for(let r in e)t.includes(r)?delete e[r]:typeof e[r]=="object"&&Ac(e[r],t);return e}var zs=(e,t)=>{if(!e||!t?.length)return{};let r={};return Object.keys(e).forEach(o=>{if(t.includes(o))r[o]=e[o];else if(typeof e[o]=="object"){let n=zs(e[o],t);Object.keys(n).length&&(r[o]=n)}}),r};function yi(e,t){let r=zs(structuredClone(e),t);return pi(r,e)}function Qh(e,t){if(!Array.isArray(e)||!t)return null;let o=t.replace("var(","").replace(")","")?.split("--").slice(-1)[0];return e.find(n=>n.slug===o)}function $h(e){let t=e?.settings?.typography?.fontFamilies?.theme,r=e?.settings?.typography?.fontFamilies?.custom,o=[];t&&r?o=[...t,...r]:t?o=t:r&&(o=r);let n=e?.styles?.typography?.fontFamily,i=Qh(o,n),s=e?.styles?.elements?.heading?.typography?.fontFamily,a;return s?a=Qh(o,e?.styles?.elements?.heading?.typography?.fontFamily):a=i,[i,a]}function qe(e,t,r="merged",o=!0,n){let{user:i,base:s,merged:a,onChange:u}=(0,Rr.useContext)(gt),l=n?.split(".").filter(Boolean)??[],c=l.find(w=>w.startsWith(":")),m=l.filter(w=>!w.startsWith(":")).join("."),d=[e,m].filter(Boolean).join("."),h=a;r==="base"?h=s:r==="user"&&(h=i);let g=(0,Rr.useMemo)(()=>{let w=Vs(h,d,t,o);return c?w?.[c]??{}:w},[h,d,t,o,c]),b=(0,Rr.useCallback)(w=>{let _=w;c&&(_={...Vs(i,d,t,!1),[c]:w});let x=wc(i,d,_,t);u(x)},[i,u,d,t,c]);return[g,b]}function Ke(e,t,r="merged"){let{user:o,base:n,merged:i,onChange:s}=(0,Rr.useContext)(gt),a=i;r==="base"?a=n:r==="user"&&(a=o);let u=(0,Rr.useMemo)(()=>gc(a,e,t),[a,e,t]),l=(0,Rr.useCallback)(c=>{let m=yc(o,e,c,t);s(m)},[o,s,e,t]);return[u,l]}var Sx=[];function _x({title:e,settings:t,styles:r}){return e===(0,Ic.__)("Default")||Object.keys(t||{}).length>0||Object.keys(r||{}).length>0}function Hs(e=[]){let{variationsFromTheme:t}=(0,eg.useSelect)(o=>({variationsFromTheme:o(tg.store).__experimentalGetCurrentThemeGlobalStylesVariations?.()||Sx}),[]),{user:r}=(0,Rr.useContext)(gt);return(0,Rr.useMemo)(()=>{let o=structuredClone(r),n=Ac(o,e);n.title=(0,Ic.__)("Default");let i=t.filter(a=>yi(a,e)).map(a=>Go(n,a)),s=[n,...i];return s?.length?s.filter(_x):[]},[e,r,t])}var Lc=f(Z(),1),{useHasDimensionsPanel:tL,useHasTypographyPanel:rL,useHasColorPanel:oL,useSettingsForBlockElement:nL,useHasBackgroundPanel:iL}=De(rg.privateApis);var Hr=f(ue(),1);function Pn(){let[e="black"]=qe("color.text"),[t="white"]=qe("color.background"),[r=e]=qe("elements.h1.color.text"),[o=r]=qe("elements.link.color.text"),[n=o]=qe("elements.button.color.background"),[i]=Ke("color.palette.core")||[],[s]=Ke("color.palette.theme")||[],[a]=Ke("color.palette.custom")||[],u=(s??[]).concat(a??[]).concat(i??[]),l=u.filter(({color:d})=>d===e),c=u.filter(({color:d})=>d===n),m=l.concat(c).concat(u).filter(({color:d})=>d!==t).slice(0,2);return{paletteColors:u,highlightedColors:m}}var sg=f(Te(),1),ag=f(ue(),1),Vc=f(ge(),1);function Ex(e,t){return t.length===0?null:(t.sort((r,o)=>Math.abs(e-r)-Math.abs(e-o)),t[0])}var Tx={normal:400,bold:700};function og(e){return e!==void 0&&Number.isFinite(e)&&e>=1&&e<=1e3}function Nc(e){let t=String(e??"").trim().toLowerCase().split(/\s+/).filter(Boolean).map(n=>Tx[n]??Number(n)),[r,o]=t;return og(r)?t.length!==2||!og(o)?String(r):String(Math.min(Math.max(400,r),o)):"400"}function ng(e){let t=/^(?!generic\([ a-zA-Z\-]+\)$)(?!var\(\s*--[\w-]+\s*\)$)(?!^[a-zA-Z\-]+$).+/,r=e.trim(),o=n=>(n=n.trim(),n.match(t)?(n=n.replace(/^["']|["']$/g,""),`"${n}"`):n);return r.includes(",")?r.split(",").map(o).filter(n=>n!=="").join(", "):o(r)}function Mc(e){if(!e)return"";let t=e.trim();return t.includes(",")&&(t=(t.split(",").find(r=>r.trim()!=="")??"").trim()),t=t.replace(/^["']|["']$/g,""),window.navigator.userAgent.toLowerCase().includes("firefox")&&(t=`"${t}"`),t}function On(e){let t={fontFamily:ng(e.fontFamily)};if(!("fontFace"in e)||!Array.isArray(e.fontFace))return t.fontWeight="400",t.fontStyle="normal",t;if(e.fontFace){let r=e.fontFace.filter(o=>o?.fontStyle&&o.fontStyle.toLowerCase()==="normal");if(r.length>0){t.fontStyle="normal";let o=r.map(n=>Number(Nc(n.fontWeight)));t.fontWeight=String(Ex(400,o)??400)}else t.fontStyle=e.fontFace.length&&e.fontFace[0].fontStyle||"normal",t.fontWeight=e.fontFace.length&&Nc(e.fontFace[0].fontWeight)||"400"}return t}function ig(e){return{fontFamily:ng(e.fontFamily),fontStyle:e.fontStyle||"normal",fontWeight:Nc(e.fontWeight)}}var vi=f(Z(),1);function Us({fontSize:e,variation:t}){let{base:r}=(0,sg.useContext)(gt),o=r;t&&(o={...r,...t});let[n]=qe("color.text"),[i,s]=$h(o),a=i?On(i):{},u=s?On(s):{};return n&&(a.color=n,u.color=n),e&&(a.fontSize=e,u.fontSize=e),(0,vi.jsxs)(ag.__unstableMotion.div,{animate:{scale:1,opacity:1},initial:{scale:.1,opacity:0},transition:{delay:.3,type:"tween"},style:{textAlign:"center",lineHeight:1},children:[(0,vi.jsx)("span",{style:u,children:(0,Vc._x)("A","Uppercase letter A")}),(0,vi.jsx)("span",{style:a,children:(0,Vc._x)("a","Lowercase letter A")})]})}var lg=f(ue(),1);var cg=f(Z(),1);function ug({normalizedColorSwatchSize:e,ratio:t}){let{highlightedColors:r}=Pn(),o=e*t;return r.map(({slug:n,color:i},s)=>(0,cg.jsx)(lg.__unstableMotion.div,{style:{height:o,width:o,background:i,borderRadius:o/2},animate:{scale:1,opacity:1},initial:{scale:.1,opacity:0},transition:{delay:s===1?.2:.1}},`${n}-${s}`))}var fg=f(ue(),1),kn=f(yo(),1),qo=f(Te(),1);var $r=f(Z(),1),Dc=248,Bc=152,Px={leading:!0,trailing:!0};function Ox({children:e,label:t,isFocused:r,withHoverView:o}){let[n="white"]=qe("color.background"),[i]=qe("color.gradient"),s=(0,kn.useReducedMotion)(),[a,u]=(0,qo.useState)(!1),[l,{width:c}]=(0,kn.useResizeObserver)(),[m,d]=(0,qo.useState)(c),[h,g]=(0,qo.useState)(),b=(0,kn.useThrottle)(d,250,Px);(0,qo.useLayoutEffect)(()=>{c&&b(c)},[c,b]),(0,qo.useLayoutEffect)(()=>{let v=m?m/Dc:1,C=v-(h||0);(Math.abs(C)>.1||!h)&&g(v)},[m,h]);let w=c?c/Dc:1,_=h||w,x=!!c;return(0,$r.jsxs)($r.Fragment,{children:[(0,$r.jsx)("div",{style:{position:"relative"},children:l}),!x&&(0,$r.jsx)(ui,{className:"global-styles-ui-preview__wrapper",style:{aspectRatio:Dc/Bc}}),x&&(0,$r.jsx)("div",{className:We("global-styles-ui-preview__wrapper",{"is-hoverable":o}),style:{height:Bc*_},onMouseEnter:()=>u(!0),onMouseLeave:()=>u(!1),tabIndex:-1,children:(0,$r.jsx)(fg.__unstableMotion.div,{style:{height:Bc*_,width:"100%",background:i??n},initial:"start",animate:(a||r)&&!s&&t?"hover":"start",children:[].concat(e).map((v,C)=>v({ratio:_,key:C}))})})]})}var Fn=Ox;var Jt=f(Z(),1),kx={start:{scale:1,opacity:1},hover:{scale:0,opacity:0}},Fx={hover:{opacity:1},start:{opacity:.5}},Ax={hover:{scale:1,opacity:1},start:{scale:0,opacity:0}};function Ix({label:e,isFocused:t,withHoverView:r,variation:o}){let[n]=qe("typography.fontWeight"),[i="serif"]=qe("typography.fontFamily"),[s=i]=qe("elements.h1.typography.fontFamily"),[a=n]=qe("elements.h1.typography.fontWeight"),[u="black"]=qe("color.text"),[l=u]=qe("elements.h1.color.text"),{paletteColors:c}=Pn();return(0,Jt.jsxs)(Fn,{label:e,isFocused:t,withHoverView:r,children:[({ratio:m,key:d})=>(0,Jt.jsx)(Hr.__unstableMotion.div,{variants:kx,style:{height:"100%",overflow:"hidden"},children:(0,Jt.jsxs)(Hr.__experimentalHStack,{spacing:10*m,justify:"center",style:{height:"100%",overflow:"hidden"},children:[(0,Jt.jsx)(Us,{fontSize:65*m,variation:o}),(0,Jt.jsx)(Hr.__experimentalVStack,{spacing:4*m,children:(0,Jt.jsx)(ug,{normalizedColorSwatchSize:32,ratio:m})})]})},d),({key:m})=>(0,Jt.jsx)(Hr.__unstableMotion.div,{variants:r?Fx:void 0,style:{height:"100%",width:"100%",position:"absolute",top:0,overflow:"hidden",filter:"blur(60px)",opacity:.1},children:(0,Jt.jsx)(Hr.__experimentalHStack,{spacing:0,justify:"flex-start",style:{height:"100%",overflow:"hidden"},children:c.slice(0,4).map(({color:d},h)=>(0,Jt.jsx)("div",{style:{height:"100%",background:d,flexGrow:1}},h))})},m),({ratio:m,key:d})=>(0,Jt.jsx)(Hr.__unstableMotion.div,{variants:Ax,style:{height:"100%",width:"100%",overflow:"hidden",position:"absolute",top:0},children:(0,Jt.jsx)(Hr.__experimentalVStack,{spacing:3*m,justify:"center",style:{height:"100%",overflow:"hidden",padding:10*m,boxSizing:"border-box"},children:e&&(0,Jt.jsx)("div",{style:{fontSize:40*m,fontFamily:s,color:l,fontWeight:a,lineHeight:"1em",textAlign:"center"},children:e})})},d)]})}var jc=Ix;var pg=f(Z(),1);var Uc=f(Cn(),1),Ro=f(ge(),1),Ur=f(ue(),1);var Wc=f(Kt(),1),dr=f(Te(),1),Ws=f(Dt(),1),bg=f(yo(),1);import{speak as Bx}from"@wordpress/a11y";var mg=f(Cn(),1),hg=f(Kt(),1),Mx=f(ue(),1);var Vx=f(Z(),1);function Dx(e,t){return e?.filter(r=>r.source==="block"||t.includes(r.name))||[]}function zc(e){let t=(0,hg.useSelect)(n=>{let{getBlockStyles:i}=n(mg.store);return i(e)},[e]),[r]=qe("variations",e),o=Object.keys(r??{});return Dx(t,o)}var Co=f(ue(),1),gg=f(ge(),1);var yg=f(Dt(),1);var vg=f(Z(),1),{StateControl:VL,StateControlBadges:DL}=De(yg.privateApis);var Bt=f(Z(),1),{useHasDimensionsPanel:jx,useHasTypographyPanel:zx,useHasBorderPanel:Hx,useSettingsForBlockElement:Ux,useHasColorPanel:Wx,useHasBackgroundPanel:Gx}=De(Ws.privateApis),{Menu:ZL}=De(Ur.privateApis);function Hc(e){return e==null?!1:Array.isArray(e)?e.length>0:typeof e=="object"?Object.values(e).some(Hc):!0}function Yx(e,t){return Hc(e?.styles?.blocks?.[t])||Hc(e?.settings?.blocks?.[t])}function qx(){let e=(0,Wc.useSelect)(n=>n(Uc.store).getBlockTypes(),[]),t=(n,i)=>{let{core:s,noncore:a}=n;return(i.name.startsWith("core/")?s:a).push(i),n},{core:r,noncore:o}=e.reduce(t,{core:[],noncore:[]});return[...r,...o]}function Zx(e){let[t]=Ke("",e),r=Ux(t,e),o=zx(r),n=Wx(r),i=Gx(r),s=Hx(r),a=jx(r),u=s||a,l=!!zc(e)?.length;return o||n||i||u||l}function Xx({block:e,isCustomized:t}){return Zx(e.name)?(0,Bt.jsx)(Qr,{path:"/blocks/"+encodeURIComponent(e.name),children:(0,Bt.jsxs)(Ur.__experimentalHStack,{justify:"flex-start",spacing:2,children:[(0,Bt.jsx)(Ws.BlockIcon,{className:"global-styles-ui-block-types-item__icon",icon:e.icon}),(0,Bt.jsx)(Ur.FlexItem,{children:e.title}),t&&(0,Bt.jsxs)(Bt.Fragment,{children:[(0,Bt.jsx)(rc,{children:(0,Ro.__)("Has custom styles")}),(0,Bt.jsx)("span",{"aria-hidden":"true",className:"global-styles-ui-block-types-item__indicator"})]})]})}):null}function Kx({filterValue:e,styleFilter:t}){let r=t==="customized"&&!e?(0,Ro.__)("You haven't customized any blocks yet."):(0,Ro.__)("No blocks found.");return(0,Bt.jsx)(Ur.__experimentalText,{align:"center",as:"p",className:"global-styles-ui-block-types-item-list__no-results",children:r})}function Jx({filterValue:e,styleFilter:t}){let r=qx(),o=(0,bg.useDebounce)(Bx,500),{isMatchingSearchTerm:n}=(0,Wc.useSelect)(Uc.store),{user:i}=(0,dr.useContext)(gt),s=(0,dr.useMemo)(()=>{let m=new Set;return[...Object.keys(i?.styles?.blocks??{}),...Object.keys(i?.settings?.blocks??{})].forEach(h=>{Yx(i,h)&&m.add(h)}),m},[i]),a=e?r.filter(m=>n(m,e)):r,u=t==="customized"?a.filter(m=>s.has(m.name)):a,l=(0,dr.useRef)(null),c=u.length>0;return(0,dr.useEffect)(()=>{if(!e&&t==="all")return;let m=c&&l.current?.childElementCount||0,d=(0,Ro.sprintf)((0,Ro._n)("%d result found.","%d results found.",m),m);o(d,"polite")},[e,t,c,o]),(0,Bt.jsx)("div",{ref:l,className:"global-styles-ui-block-types-item-list",role:"list",children:u.length===0?(0,Bt.jsx)(Kx,{filterValue:e,styleFilter:t}):u.map(m=>(0,Bt.jsx)(Xx,{block:m,isCustomized:s.has(m.name)},"menu-itemblock-"+m.name))})}var XL=(0,dr.memo)(Jx);var oS=f(Cn(),1),_g=f(Dt(),1),Gc=f(Te(),1),nS=f(Kt(),1),iS=f(sr(),1),Yc=f(ue(),1),Cg=f(ge(),1);var Qx=f(Dt(),1),wg=f(Cn(),1),$x=f(ue(),1),eS=f(Te(),1);var tS=f(Z(),1),{getViewportBreakpoints:rN,getViewportBreakpointValueInPixels:oN}=De(Tn);var xg=f(ue(),1),Sg=f(Z(),1);function Er({children:e,level:t=2}){return(0,Sg.jsx)(xg.__experimentalHeading,{className:"global-styles-ui-subtitle",level:t,children:e})}var qc=f(Z(),1);var{useHasDimensionsPanel:vN,useHasTypographyPanel:bN,useHasBorderPanel:wN,useSettingsForBlockElement:xN,useHasColorPanel:SN,useHasFiltersPanel:_N,useHasImageSettingsPanel:CN,useHasBackgroundPanel:RN,BackgroundPanel:EN,BorderPanel:TN,ColorPanel:PN,TypographyPanel:ON,DimensionsPanel:kN,FiltersPanel:FN,ImageSettingsPanel:AN,AdvancedPanel:IN}=De(_g.privateApis);var v2=f(ge(),1),b2=f(ue(),1),w2=f(Te(),1);var sS=f(ue(),1);var aS=f(Z(),1);var lS=f(ge(),1),Gs=f(ue(),1);var Rg=f(Z(),1);var Zs=f(ue(),1);var Eg=f(ue(),1);var Ys=f(Z(),1),cS=({variation:e,isFocused:t,withHoverView:r})=>(0,Ys.jsx)(Fn,{label:e.title,isFocused:t,withHoverView:r,children:({ratio:o,key:n})=>(0,Ys.jsx)(Eg.__experimentalHStack,{spacing:10*o,justify:"center",style:{height:"100%",overflow:"hidden"},children:(0,Ys.jsx)(Us,{variation:e,fontSize:85*o})},n)}),Tg=cS;var Zo=f(Te(),1),Og=f(Zc(),1),qs=f(ge(),1);var Eo=f(Z(),1);function An({variation:e,children:t,isPill:r=!1,properties:o,showTooltip:n=!1}){let[i,s]=(0,Zo.useState)(!1),{base:a,user:u,onChange:l}=(0,Zo.useContext)(gt),c=(0,Zo.useMemo)(()=>{let w=Go(a,e);return o&&(w=zs(w,o)),{user:e,base:a,merged:w,onChange:()=>{}}},[e,a,o]),m=()=>l(e),d=w=>{w.keyCode===Og.ENTER&&(w.preventDefault(),m())},h=(0,Zo.useMemo)(()=>pi(u,e),[u,e]),g=e?.title;e?.description&&(g=(0,qs.sprintf)((0,qs._x)("%1$s (%2$s)","variation label"),e?.title,e?.description));let b=(0,Eo.jsx)("div",{className:We("global-styles-ui-variations_item",{"is-active":h}),role:"button",onClick:m,onKeyDown:d,tabIndex:0,"aria-label":g,"aria-current":h,onFocus:()=>s(!0),onBlur:()=>s(!1),children:(0,Eo.jsx)("div",{className:We("global-styles-ui-variations_item-preview",{"is-pill":r}),children:t(i)})});return(0,Eo.jsx)(gt.Provider,{value:c,children:n?(0,Eo.jsxs)(xn.Root,{children:[(0,Eo.jsx)(xn.Trigger,{render:b}),(0,Eo.jsx)(xn.Popup,{children:e?.title})]}):b})}var Xo=f(Z(),1),kg=["typography"];function Xs({title:e,gap:t=2}){let r=Hs(kg);return r?.length<=1?null:(0,Xo.jsxs)(Zs.__experimentalVStack,{spacing:3,children:[e&&(0,Xo.jsx)(Er,{level:3,children:e}),(0,Xo.jsx)(Zs.__experimentalGrid,{columns:3,gap:t,className:"global-styles-ui-style-variations-container",children:r.map((o,n)=>(0,Xo.jsx)(An,{variation:o,properties:kg,showTooltip:!0,children:()=>(0,Xo.jsx)(Tg,{variation:o})},n))})]})}var g2=f(ge(),1),Ri=f(ue(),1);var y2=f(Te(),1);var to=f(Te(),1),ko=f(Kt(),1),Oo=f(sr(),1),Qc=f(ge(),1);var Xc=f(Ag(),1),Ig=f(sr(),1),Lg="/wp/v2/font-families";function Ng(e){let{receiveEntityRecords:t}=e.dispatch(Ig.store);t("postType","wp_font_family",[],void 0,!0)}async function Mg(e,t){let o=await(0,Xc.default)({path:Lg,method:"POST",body:e});return Ng(t),{id:o.id,...o.font_family_settings,fontFace:[]}}async function Vg(e,t,r){let o={path:`${Lg}/${e}/font-faces`,method:"POST",body:t},n=await(0,Xc.default)(o);return Ng(r),{id:n.id,...n.font_face_settings}}var In=function(){return In=Object.assign||function(t){for(var r,o=1,n=arguments.length;o{o.forEach(n=>{n.family===Mc(e?.fontFamily)&&n.weight===e?.fontWeight&&n.style===e?.fontStyle&&o.delete(n)})};if((t==="document"||t==="all")&&r(document.fonts),t==="iframe"||t==="all"){let o=document.querySelector('iframe[name="editor-canvas"]');o?.contentDocument&&r(o.contentDocument.fonts)}}function Ln(e){if(!e)return;let t;if(Array.isArray(e)?t=e[0]:t=e,!t.startsWith("file:."))return dS(t)||(t=encodeURI(t)),t}function qg(e){let t=new FormData,{fontFace:r,category:o,...n}=e,i={...n,slug:Ks(e.slug)};return t.append("font_family_settings",JSON.stringify(i)),t}function Zg(e){return(e?.fontFace??[]).map((r,o)=>{let n={...r},i=new FormData;if(n.file){let s=Array.isArray(n.file)?n.file:[n.file],a=[];s.forEach((u,l)=>{let c=`file-${o}-${l}`;i.append(c,u,u.name),a.push(c)}),n.src=a.length===1?a[0]:a,delete n.file,i.append("font_face_settings",JSON.stringify(n))}else i.append("font_face_settings",JSON.stringify(n));return i})}async function Xg(e,t,r){let o=[];for(let i of t)try{let s=await Vg(e,i,r);o.push({status:"fulfilled",value:s})}catch(s){o.push({status:"rejected",reason:s})}let n={errors:[],successes:[]};return o.forEach((i,s)=>{if(i.status==="fulfilled"&&i.value){let a=i.value;n.successes.push(a)}else i.reason&&n.errors.push({data:t[s],message:i.reason.message})}),n}async function Kg(e){e=Array.isArray(e)?e:[e];let t=await Promise.all(e.map(async r=>fetch(new Request(r)).then(o=>{if(!o.ok)throw new Error(`Error downloading font face asset from ${r}. Server responded with status: ${o.status}`);return o.blob()}).then(o=>{let n=r.split("/").pop();return new Gg([o],n,{type:o.type})})));return t.length===1?t[0]:t}function Jc(e,t){return t.findIndex(r=>r.fontWeight===e.fontWeight&&r.fontStyle===e.fontStyle)!==-1}function Jg(e,t,r){t=Array.isArray(t)?[...t]:[t],e=Array.isArray(e)?[...e]:{...e};let o=t.pop(),n=e;for(let i of t){let s=n[i];n=n[i]=Array.isArray(s)?[...s]:{...s}}return n[o]=r,e}function Qs(e,t,r=[]){let o=u=>u.slug===e.slug,n=u=>u.find(o),i=u=>u?r.filter(l=>!o(l)):[...r,e],s=u=>{let l=m=>m.fontWeight===t.fontWeight&&m.fontStyle===t.fontStyle;if(!u)return[...r,{...e,fontFace:[t]}];let c=u.fontFace||[];return c.find(l)?c=c.filter(m=>!l(m)):c=[...c,t],c.length===0?r.filter(m=>!o(m)):r.map(m=>o(m)?{...m,fontFace:c}:m)},a=n(r);return t?s(a):i(a)}var Qg=f(Z(),1),jt=(0,to.createContext)({});jt.displayName="FontLibraryContext";function mS({children:e}){let t=(0,ko.useRegistry)(),{saveEntityRecord:r,deleteEntityRecord:o}=(0,ko.useDispatch)(Oo.store),{globalStylesId:n}=(0,ko.useSelect)(R=>{let{__experimentalGetCurrentGlobalStylesId:B}=R(Oo.store);return{globalStylesId:B()}},[]),i=(0,Oo.useEntityRecord)("root","globalStyles",n??0,{enabled:n!==void 0}),[s,a]=(0,to.useState)(!1),{records:u=[],isResolving:l}=(0,Oo.useEntityRecords)("postType","wp_font_family",{_embed:!0}),c=(u||[]).map(R=>({id:R.id,...R.font_family_settings||{},fontFace:R?._embedded?.font_faces?.map(B=>B.font_face_settings)||[]}))||[],[m,d]=Ke("typography.fontFamilies"),h=async R=>{if(!i.record)return;let B=i.record,re=Jg(B??{},["settings","typography","fontFamilies"],R);await r("root","globalStyles",re)},[g,b]=(0,to.useState)(""),[w,_]=(0,to.useState)(void 0),x=m?.theme?m.theme.map(R=>To(R,{source:"theme"})).sort((R,B)=>R.name.localeCompare(B.name)):[],v=m?.custom?m.custom.map(R=>To(R,{source:"custom"})).sort((R,B)=>R.name.localeCompare(B.name)):[],C=c?c.map(R=>To(R,{source:"custom"})).sort((R,B)=>R.name.localeCompare(B.name)):[];(0,to.useEffect)(()=>{g||_(void 0)},[g]);let k=R=>{if(!R){_(void 0);return}let re=(R.source==="theme"?x:C).find(P=>P.slug===R.slug);_({...re||R,source:R.source})},[E]=(0,to.useState)(new Set),T=R=>R.reduce((re,P)=>{let W=P?.fontFace&&P.fontFace?.length>0?P?.fontFace.map(ne=>`${ne.fontStyle??""}${ne.fontWeight??""}`):["normal400"];return re[P.slug]=W,re},{}),O=R=>T(R==="theme"?x:v),I=(R,B,re,P)=>!B&&!re?!!O(P)[R]:!!O(P)[R]?.includes((B??"")+(re??"")),J=(R,B)=>O(B)[R]||[];async function D(R){a(!0);try{let B=[],re=[];for(let W of R){let ne=!1,xe=await(0,ko.resolveSelect)(Oo.store).getEntityRecords("postType","wp_font_family",{slug:W.slug,per_page:1,_embed:!0}),se=xe&&xe.length>0?xe[0]:null,be=se?{id:se.id,...se.font_family_settings,fontFace:(se?._embedded?.font_faces??[]).map(Fe=>Fe.font_face_settings)||[]}:null;be||(ne=!0,be=await Mg(qg(W),t));let ye=be.fontFace&&W.fontFace?be.fontFace.filter(Fe=>Fe&&W.fontFace&&Jc(Fe,W.fontFace)):[];be.fontFace&&W.fontFace&&(W.fontFace=W.fontFace.filter(Fe=>!Jc(Fe,be.fontFace)));let $=[],Ce=[];if(W?.fontFace?.length??!1){let Fe=await Xg(be.id,Zg(W),t);$=Fe?.successes,Ce=Fe?.errors}($?.length>0||ye?.length>0)&&(be.fontFace=[...$],B.push(be)),be&&!W?.fontFace?.length&&B.push(be),ne&&(W?.fontFace?.length??0)>0&&$?.length===0&&await o("postType","wp_font_family",be.id,{force:!0}),re=re.concat(Ce)}let P=re.reduce((W,ne)=>W.includes(ne.message)?W:[...W,ne.message],[]);if(B.length>0){let W=Y(B);await h(W)}if(P.length>0){let W=new Error((0,Qc.__)("There was an error installing fonts."));throw W.installationErrors=P,W}}finally{a(!1)}}async function S(R){if(!R?.id)throw new Error((0,Qc.__)("Font family to uninstall is not defined."));try{await o("postType","wp_font_family",R.id,{force:!0});let B=L(R);return await h(B),{deleted:!0}}catch(B){throw console.error("There was an error uninstalling the font family:",B),B}}let L=R=>{let re=(m?.[R.source??""]??[]).filter(W=>W.slug!==R.slug),P={...m,[R.source??""]:re};return d(P),R.fontFace&&R.fontFace.forEach(W=>{bi(W,"all")}),P},Y=R=>{let B=A(R),re={...m,custom:Yg(m?.custom,B)};return d(re),N(B),re},A=R=>R.map(({id:B,fontFace:re,...P})=>({...P,...re&&re.length>0?{fontFace:re.map(({id:W,...ne})=>ne)}:{}})),N=R=>{R.forEach(B=>{B.fontFace&&B.fontFace.forEach(re=>{let P=Ln(re?.src??"");P&&Po(re,P,"all")})})},q=(R,B)=>{let re=m?.[R.source??""]??[],P=Qs(R,B,re);d({...m,[R.source??""]:P});let W=I(R.slug,B?.fontStyle??"",B?.fontWeight??"",R.source??"custom");if(B&&W)bi(B,"all");else{let ne=Ln(B?.src??"");B&&ne&&Po(B,ne,"all")}},U=async R=>{if(!R.src)return;let B=Ln(R.src);!B||E.has(B)||(Po(R,B,"document"),E.add(B))};return(0,Qg.jsx)(jt.Provider,{value:{libraryFontSelected:w,handleSetLibraryFontSelected:k,fontFamilies:m??{},baseCustomFonts:C,isFontActivated:I,getFontFacesActivated:J,loadFontFaceAsset:U,installFonts:D,uninstallFontFamily:S,toggleActivateFont:q,getAvailableFontsOutline:T,modalTabOpen:g,setModalTabOpen:b,saveFontFamilies:h,isResolvingLibrary:l,isInstalling:s},children:e})}var $s=mS;var ma=f(ge(),1),ou=f(ue(),1),Ly=f(sr(),1),m2=f(Kt(),1);var Ie=f(ue(),1),xi=f(sr(),1),$c=f(Kt(),1),Gr=f(Te(),1),st=f(ge(),1);var Mn=f(ge(),1),ea=f(Te(),1),mr=f(ue(),1);var Tr=f(Te(),1);var ro=f(Z(),1),$g=new Set;function hS(e){if(e.preview)return e.preview;if(e.src)return Array.isArray(e.src)?e.src[0]:e.src}function gS(e){return"fontStyle"in e&&e.fontStyle||"fontWeight"in e&&e.fontWeight?e:"fontFace"in e&&e.fontFace&&e.fontFace.length?e.fontFace.find(t=>t.fontStyle==="normal"&&t.fontWeight==="400")||e.fontFace[0]:{fontStyle:"normal",fontWeight:"400",fontFamily:e.fontFamily}}function yS({font:e,text:t}){let r=(0,Tr.useRef)(null),o=gS(e),n=On(e);t=t||("name"in e?e.name:"");let s=e.preview??hS(o),a=!!(s&&/\.(png|jpg|jpeg|gif|svg)$/i.test(s)),[u,l]=(0,Tr.useState)(!1),[c,m]=(0,Tr.useState)(!1),[d,h]=(0,Tr.useState)(),{loadFontFaceAsset:g}=(0,Tr.useContext)(jt),b=a?!!s&&($g.has(s)||d===s):c,w=Math.min(Math.max(t.length*12,48),300),_=ig(o),x={fontSize:"18px",lineHeight:1,opacity:b?"1":"0",...n,..._};return(0,Tr.useEffect)(()=>{if(a)return;let v=new window.IntersectionObserver(([C])=>{l(C.isIntersecting)},{});return r.current&&v.observe(r.current),()=>v.disconnect()},[a]),(0,Tr.useEffect)(()=>{(async()=>u&&!a&&(o.src&&await g(o),m(!0)))()},[o,u,g,a]),(0,ro.jsx)("div",{ref:r,className:"font-library__font-demo",children:a?(0,ro.jsxs)(ro.Fragment,{children:[!b&&(0,ro.jsx)(ui,{className:"font-library__font-variant-demo-skeleton",style:{width:w}}),(0,ro.jsx)("img",{src:s,loading:"lazy",alt:t,onLoad:()=>{s&&$g.add(s),h(s)},onError:()=>h(s),className:We("font-library__font-variant_demo-image",{"is-loading":!b})})]}):(0,ro.jsx)("span",{style:x,className:"font-library__font-variant_demo-text",children:t})})}var Nn=yS;var Wr=f(Z(),1);function vS({font:e,onClick:t,variantsText:r,navigatorPath:o,shouldFocus:n}){let i=e.fontFace?.length||1,s={cursor:t?"pointer":"default"},a=(0,mr.useNavigator)(),u=(0,ea.useRef)(null);return(0,ea.useEffect)(()=>{n&&u.current?.focus()},[n]),(0,Wr.jsx)(mr.Button,{ref:u,__next40pxDefaultSize:!0,onClick:()=>{t(),o&&a.goTo(o)},style:s,className:"font-library__font-card",children:(0,Wr.jsxs)(mr.Flex,{justify:"space-between",wrap:!1,children:[(0,Wr.jsx)(Nn,{font:e}),(0,Wr.jsxs)(mr.Flex,{justify:"flex-end",children:[(0,Wr.jsx)(mr.FlexItem,{children:(0,Wr.jsx)(mr.__experimentalText,{className:"font-library__font-card__count",children:r||(0,Mn.sprintf)((0,Mn._n)("%d variant","%d variants",i),i)})}),(0,Wr.jsx)(mr.FlexItem,{children:(0,Wr.jsx)(ci,{icon:(0,Mn.isRTL)()?Uo:Wo})})]})]})})}var wi=vS;var ta=f(Te(),1),ra=f(ue(),1);var Ko=f(Z(),1);function bS({face:e,font:t}){let{isFontActivated:r,toggleActivateFont:o}=(0,ta.useContext)(jt),n=(t?.fontFace?.length??0)>0?r(t.slug,e.fontStyle,e.fontWeight,t.source):r(t.slug,void 0,void 0,t.source),i=()=>{if((t?.fontFace?.length??0)>0){o(t,e);return}o(t)},s=t.name+" "+Js(e),a=(0,ta.useId)();return(0,Ko.jsx)("div",{className:"font-library__font-card",children:(0,Ko.jsxs)(ra.Flex,{justify:"flex-start",align:"center",gap:"1rem",children:[(0,Ko.jsx)(ra.CheckboxControl,{checked:n,onChange:i,id:a}),(0,Ko.jsx)("label",{htmlFor:a,children:(0,Ko.jsx)(Nn,{font:e,text:s,onClick:i})})]})})}var ey=bS;function ty(e){switch(e){case"normal":return 400;case"bold":return 700;case"bolder":return 500;case"lighter":return 300;default:return parseInt(e,10)}}function oa(e){return e.sort((t,r)=>t.fontStyle==="normal"&&r.fontStyle!=="normal"?-1:r.fontStyle==="normal"&&t.fontStyle!=="normal"?1:t.fontStyle===r.fontStyle?ty(t.fontWeight?.toString()??"normal")-ty(r.fontWeight?.toString()??"normal"):!t.fontStyle||!r.fontStyle?t.fontStyle?-1:1:t.fontStyle.localeCompare(r.fontStyle))}var Ee=f(Z(),1);function ry(e){if(!e)return"";let t={};for(let r of Object.keys(e).sort())t[r]=(e[r]??[]).map(o=>({slug:o.slug,fontFace:(o.fontFace??[]).map(n=>`${n.fontStyle}-${n.fontWeight}`).sort()})).sort((o,n)=>o.slug.localeCompare(n.slug));return JSON.stringify(t)}function wS(){let{baseCustomFonts:e,libraryFontSelected:t,handleSetLibraryFontSelected:r,uninstallFontFamily:o,isResolvingLibrary:n,isInstalling:i,saveFontFamilies:s,getFontFacesActivated:a}=(0,Gr.useContext)(jt),[u,l]=Ke("typography.fontFamilies"),[c,m]=(0,Gr.useState)(void 0),[d,h]=(0,Gr.useState)(!1),[g,b]=(0,Gr.useState)(null),[w]=Ke("typography.fontFamilies",void 0,"base"),_=(0,$c.useSelect)(P=>{let{__experimentalGetCurrentGlobalStylesId:W}=P(xi.store);return W()},[]),x=(0,xi.useEntityRecord)("root","globalStyles",_??0,{enabled:_!==void 0}),v=x?.edits?.settings?.typography?.fontFamilies,C=x?.record?.settings?.typography?.fontFamilies,k=(0,Gr.useMemo)(()=>v===void 0?!1:ry(v)!==ry(C),[v,C]),E=u?.theme?u.theme.map(P=>To(P,{source:"theme"})).sort((P,W)=>P.name.localeCompare(W.name)):[],T=new Set(E.map(P=>P.slug)),O=w?.theme?E.concat(w.theme.filter(P=>!T.has(P.slug)).map(P=>To(P,{source:"theme"})).sort((P,W)=>P.name.localeCompare(W.name))):[],I=t?.source==="custom"&&t?.id,J=(0,$c.useSelect)(P=>{let{canUser:W}=P(xi.store);return I&&W("delete",{kind:"postType",name:"wp_font_family",id:I})},[I]),D=!!t&&t?.source!=="theme"&&J,S=()=>{h(!0)},L=async()=>{b(null);try{await s(u),b({type:"success",message:(0,st.__)("Font family updated successfully.")})}catch(P){b({type:"error",message:(0,st.sprintf)((0,st.__)("There was an error updating the font family. %s"),P.message)})}},Y=P=>P?!P.fontFace||!P.fontFace.length?[{fontFamily:P.fontFamily,fontStyle:"normal",fontWeight:"400"}]:oa(P.fontFace):[],A=P=>{let W=P?.fontFace&&(P?.fontFace?.length??0)>0?P.fontFace.length:1,ne=a(P.slug,P.source).length;return(0,st.sprintf)((0,st.__)("%1$d of %2$d active"),ne,W)};(0,Gr.useEffect)(()=>{r(t)},[]);let N=t?a(t.slug,t.source).length:0,q=t?.fontFace?.length??(t?.fontFamily?1:0),U=N>0&&N!==q,R=N===q,B=()=>{if(!t||!t?.source)return;let P=u?.[t.source]?.filter(ne=>ne.slug!==t.slug)??[],W=R?P:[...P,t];l({...u,[t.source]:W}),t.fontFace&&t.fontFace.forEach(ne=>{if(R)bi(ne,"all");else{let xe=Ln(ne?.src??"");xe&&Po(ne,xe,"all")}})},re=O.length>0||e.length>0;return(0,Ee.jsxs)("div",{className:"font-library__tabpanel-layout",children:[n&&(0,Ee.jsx)("div",{className:"font-library__loading",children:(0,Ee.jsx)(Ie.ProgressBar,{})}),!n&&(0,Ee.jsxs)(Ee.Fragment,{children:[(0,Ee.jsxs)(Ie.Navigator,{initialPath:t?"/fontFamily":"/",children:[(0,Ee.jsx)(Ie.Navigator.Screen,{path:"/",children:(0,Ee.jsxs)(Ie.__experimentalVStack,{spacing:"8",children:[g&&(0,Ee.jsx)(Ie.Notice,{status:g.type,onRemove:()=>b(null),children:g.message}),!re&&(0,Ee.jsx)(Ie.__experimentalText,{as:"p",children:(0,st.__)("No fonts installed.")}),O.length>0&&(0,Ee.jsxs)(Ie.__experimentalVStack,{children:[(0,Ee.jsx)("h2",{className:"font-library__fonts-title",children:(0,st._x)("Theme","font source")}),(0,Ee.jsx)("ul",{role:"list",className:"font-library__fonts-list",children:O.map(P=>(0,Ee.jsx)("li",{className:"font-library__fonts-list-item",children:(0,Ee.jsx)(wi,{font:P,navigatorPath:"/fontFamily",variantsText:A(P),shouldFocus:P.slug===c,onClick:()=>{b(null),r(P)}})},P.slug))})]}),e.length>0&&(0,Ee.jsxs)(Ie.__experimentalVStack,{children:[(0,Ee.jsx)("h2",{className:"font-library__fonts-title",children:(0,st._x)("Custom","font source")}),(0,Ee.jsx)("ul",{role:"list",className:"font-library__fonts-list",children:e.map(P=>(0,Ee.jsx)("li",{className:"font-library__fonts-list-item",children:(0,Ee.jsx)(wi,{font:P,navigatorPath:"/fontFamily",variantsText:A(P),shouldFocus:P.slug===c,onClick:()=>{b(null),r(P)}})},P.slug))})]})]})}),(0,Ee.jsxs)(Ie.Navigator.Screen,{path:"/fontFamily",children:[t&&(0,Ee.jsx)(xS,{font:t,isOpen:d,setIsOpen:h,setNotice:b,uninstallFontFamily:o,handleSetLibraryFontSelected:r}),(0,Ee.jsxs)(Ie.Flex,{justify:"flex-start",children:[(0,Ee.jsx)(Ie.Navigator.BackButton,{icon:(0,st.isRTL)()?Wo:Uo,size:"small",onClick:()=>{m(t?.slug),r(void 0),b(null)},label:(0,st.__)("Back")}),(0,Ee.jsx)(Ie.__experimentalHeading,{level:2,size:13,className:"global-styles-ui-header",children:t?.name})]}),g&&(0,Ee.jsxs)(Ee.Fragment,{children:[(0,Ee.jsx)(Ie.__experimentalSpacer,{margin:1}),(0,Ee.jsx)(Ie.Notice,{status:g.type,onRemove:()=>b(null),children:g.message}),(0,Ee.jsx)(Ie.__experimentalSpacer,{margin:1})]}),(0,Ee.jsx)(Ie.__experimentalSpacer,{margin:4}),(0,Ee.jsx)(Ie.__experimentalText,{children:(0,st.__)("Choose font variants. Keep in mind that too many variants could make your site slower.")}),(0,Ee.jsx)(Ie.__experimentalSpacer,{margin:4}),(0,Ee.jsxs)(Ie.__experimentalVStack,{spacing:0,children:[(0,Ee.jsx)(Ie.CheckboxControl,{className:"font-library__select-all",label:(0,st.__)("Select all"),checked:R,onChange:B,indeterminate:U}),(0,Ee.jsx)(Ie.__experimentalSpacer,{margin:8}),(0,Ee.jsx)("ul",{role:"list",className:"font-library__fonts-list",children:t&&Y(t).map((P,W)=>(0,Ee.jsx)("li",{className:"font-library__fonts-list-item",children:(0,Ee.jsx)(ey,{font:t,face:P},`face${W}`)},`face${W}`))})]})]})]}),(0,Ee.jsxs)(Ie.__experimentalHStack,{justify:"flex-end",className:"font-library__footer",children:[i&&(0,Ee.jsx)(Ie.ProgressBar,{}),D&&(0,Ee.jsx)(Ie.Button,{__next40pxDefaultSize:!0,isDestructive:!0,variant:"tertiary",onClick:S,children:(0,st.__)("Delete")}),(0,Ee.jsx)(Ie.Button,{__next40pxDefaultSize:!0,variant:"primary",onClick:L,disabled:!k,accessibleWhenDisabled:!0,children:(0,st.__)("Update")})]})]})]})}function xS({font:e,isOpen:t,setIsOpen:r,setNotice:o,uninstallFontFamily:n,handleSetLibraryFontSelected:i}){let s=(0,Ie.useNavigator)(),a=async()=>{o(null),r(!1);try{await n(e),s.goBack(),i(void 0),o({type:"success",message:(0,st.__)("Font family uninstalled successfully.")})}catch(l){o({type:"error",message:(0,st.__)("There was an error uninstalling the font family.")+l.message})}},u=()=>{r(!1)};return(0,Ee.jsx)(Ie.__experimentalConfirmDialog,{isOpen:t,cancelButtonText:(0,st.__)("Cancel"),confirmButtonText:(0,st.__)("Delete"),onCancel:u,onConfirm:a,size:"medium",children:e&&(0,st.sprintf)((0,st.__)('Are you sure you want to delete "%s" font and all its variants and assets?'),e.name)})}var na=wS;var yt=f(Te(),1),_e=f(ue(),1),uy=f(yo(),1),rt=f(ge(),1);var fy=f(sr(),1);function oy(e,t){let{category:r,search:o}=t,n=e||[];return r&&r!=="all"&&(n=n.filter(i=>i.categories&&i.categories.indexOf(r)!==-1)),o&&(n=n.filter(i=>i.font_family_settings&&i.font_family_settings.name.toLowerCase().includes(o.toLowerCase()))),n}function ny(e){return e.reduce((t,r)=>({...t,[r.slug]:(r?.fontFace||[]).reduce((o,n)=>({...o,[`${n.fontStyle}-${n.fontWeight}`]:!0}),{})}),{})}function iy(e,t,r){return t?!!r[e]?.[`${t.fontStyle}-${t.fontWeight}`]:!!r[e]}var Si=f(ge(),1),zt=f(ue(),1),hr=f(Z(),1);function SS(){let e=()=>{window.localStorage.setItem("wp-font-library-google-fonts-permission","true"),window.dispatchEvent(new Event("storage"))};return(0,hr.jsx)("div",{className:"font-library__google-fonts-confirm",children:(0,hr.jsx)(zt.Card,{children:(0,hr.jsxs)(zt.CardBody,{children:[(0,hr.jsx)(zt.__experimentalHeading,{level:2,children:(0,Si.__)("Connect to Google Fonts")}),(0,hr.jsx)(zt.__experimentalSpacer,{margin:6}),(0,hr.jsx)(zt.__experimentalText,{as:"p",children:(0,Si.__)("To install fonts from Google you must give permission to connect directly to Google servers. The fonts you install will be downloaded from Google and stored on your site. Your site will then use these locally-hosted fonts.")}),(0,hr.jsx)(zt.__experimentalSpacer,{margin:3}),(0,hr.jsx)(zt.__experimentalText,{as:"p",children:(0,Si.__)("You can alternatively upload files directly on the Upload tab.")}),(0,hr.jsx)(zt.__experimentalSpacer,{margin:6}),(0,hr.jsx)(zt.Button,{__next40pxDefaultSize:!0,variant:"primary",onClick:e,children:(0,Si.__)("Allow access to Google Fonts")})]})})})}var sy=SS;var ay=f(Te(),1),ia=f(ue(),1);var Jo=f(Z(),1);function _S({face:e,font:t,handleToggleVariant:r,selected:o}){let n=()=>{if(t?.fontFace){r(t,e);return}r(t)},i=t.name+" "+Js(e),s=(0,ay.useId)();return(0,Jo.jsx)("div",{className:"font-library__font-card",children:(0,Jo.jsxs)(ia.Flex,{justify:"flex-start",align:"center",gap:"1rem",children:[(0,Jo.jsx)(ia.CheckboxControl,{checked:o,onChange:n,id:s}),(0,Jo.jsx)("label",{htmlFor:s,children:(0,Jo.jsx)(Nn,{font:e,text:i,onClick:n})})]})})}var ly=_S;var de=f(Z(),1),CS={slug:"all",name:(0,rt._x)("All","font categories")},cy="wp-font-library-google-fonts-permission",RS=500;function ES({slug:e}){let t=e==="google-fonts",r=()=>window.localStorage.getItem(cy)==="true",[o,n]=(0,yt.useState)(null),[i,s]=(0,yt.useState)(void 0),[a,u]=(0,yt.useState)(null),[l,c]=(0,yt.useState)([]),[m,d]=(0,yt.useState)(1),[h,g]=(0,yt.useState)({}),[b,w]=(0,yt.useState)(t&&!r()),{installFonts:_,isInstalling:x}=(0,yt.useContext)(jt),{record:v,isResolving:C}=(0,fy.useEntityRecord)("root","fontCollection",e);(0,yt.useEffect)(()=>{let $=()=>{w(t&&!r())};return $(),window.addEventListener("storage",$),()=>window.removeEventListener("storage",$)},[e,t]);let k=()=>{window.localStorage.setItem(cy,"false"),window.dispatchEvent(new Event("storage"))};(0,yt.useEffect)(()=>{n(null)},[e]),(0,yt.useEffect)(()=>{c([])},[o]);let E=(0,yt.useMemo)(()=>v?.font_families??[],[v]),T=v?.categories??[],O=[CS,...T],I=(0,yt.useMemo)(()=>oy(E,h),[E,h]),J=Math.max(window.innerHeight,RS),D=Math.floor((J-417)/61),S=Math.ceil(I.length/D),L=(m-1)*D,Y=m*D,A=I.slice(L,Y),N=$=>{g({...h,category:$}),d(1)},U=(0,uy.debounce)($=>{g({...h,search:$}),d(1)},300),R=($,Ce)=>{let Fe=Qs($,Ce,l);c(Fe)},B=ny(l),re=()=>{c([])},P=l.length>0?l[0]?.fontFace?.length??0:0,W=P>0&&P!==o?.fontFace?.length,ne=P===o?.fontFace?.length,xe=()=>{let $=[];!ne&&o&&$.push(o),c($)},se=async()=>{u(null);let $=l[0];try{$?.fontFace&&await Promise.all($.fontFace.map(async Ce=>{Ce.src&&(Ce.file=await Kg(Ce.src))}))}catch{u({type:"error",message:(0,rt.__)("Error installing the fonts, could not be downloaded.")});return}try{await _([$]),u({type:"success",message:(0,rt.__)("Fonts were installed successfully.")})}catch(Ce){u({type:"error",message:Ce.message})}re()},be=$=>$?!$.fontFace||!$.fontFace.length?[{fontFamily:$.fontFamily,fontStyle:"normal",fontWeight:"400"}]:oa($.fontFace):[];if(b)return(0,de.jsx)(sy,{});let ye=e==="google-fonts"&&!b&&!o;return(0,de.jsxs)("div",{className:"font-library__tabpanel-layout",children:[C&&(0,de.jsx)("div",{className:"font-library__loading",children:(0,de.jsx)(_e.ProgressBar,{})}),!C&&v&&(0,de.jsxs)(de.Fragment,{children:[(0,de.jsxs)(_e.Navigator,{initialPath:"/",className:"font-library__tabpanel-layout",children:[(0,de.jsxs)(_e.Navigator.Screen,{path:"/",children:[(0,de.jsxs)(_e.__experimentalHStack,{justify:"space-between",children:[(0,de.jsxs)(_e.__experimentalVStack,{children:[(0,de.jsx)(_e.__experimentalHeading,{level:2,size:13,children:v.name}),(0,de.jsx)(_e.__experimentalText,{children:v.description})]}),ye&&(0,de.jsx)(_e.DropdownMenu,{icon:Jl,label:(0,rt.__)("Actions"),popoverProps:{position:"bottom left"},controls:[{title:(0,rt.__)("Revoke access to Google Fonts"),onClick:k}]})]}),(0,de.jsx)(_e.__experimentalSpacer,{margin:4}),(0,de.jsxs)(_e.__experimentalHStack,{spacing:4,justify:"space-between",children:[(0,de.jsx)(_e.SearchControl,{className:"font-library__search",value:h.search,placeholder:(0,rt.__)("Font name\u2026"),label:(0,rt.__)("Search"),onChange:U,hideLabelFromVision:!1}),(0,de.jsx)(_e.SelectControl,{label:(0,rt.__)("Category"),value:h.category,onChange:N,children:O&&O.map($=>(0,de.jsx)("option",{value:$.slug,children:$.name},$.slug))})]}),(0,de.jsx)(_e.__experimentalSpacer,{margin:4}),!!v?.font_families?.length&&!I.length&&(0,de.jsx)(_e.__experimentalText,{children:(0,rt.__)("No fonts found. Try with a different search term.")}),(0,de.jsx)("div",{className:"font-library__fonts-grid__main",children:(0,de.jsx)("ul",{role:"list",className:"font-library__fonts-list",children:A.map($=>(0,de.jsx)("li",{className:"font-library__fonts-list-item",children:(0,de.jsx)(wi,{font:$.font_family_settings,navigatorPath:"/fontFamily",shouldFocus:$.font_family_settings.slug===i,onClick:()=>{n($.font_family_settings)}})},$.font_family_settings.slug))})})]}),(0,de.jsxs)(_e.Navigator.Screen,{path:"/fontFamily",children:[(0,de.jsxs)(_e.Flex,{justify:"flex-start",children:[(0,de.jsx)(_e.Navigator.BackButton,{icon:(0,rt.isRTL)()?Wo:Uo,size:"small",onClick:()=>{s(o?.slug),n(null),u(null)},label:(0,rt.__)("Back")}),(0,de.jsx)(_e.__experimentalHeading,{level:2,size:13,className:"global-styles-ui-header",children:o?.name})]}),a&&(0,de.jsxs)(de.Fragment,{children:[(0,de.jsx)(_e.__experimentalSpacer,{margin:1}),(0,de.jsx)(_e.Notice,{status:a.type,onRemove:()=>u(null),children:a.message}),(0,de.jsx)(_e.__experimentalSpacer,{margin:1})]}),(0,de.jsx)(_e.__experimentalSpacer,{margin:4}),(0,de.jsx)(_e.__experimentalText,{children:(0,rt.__)("Select font variants to install.")}),(0,de.jsx)(_e.__experimentalSpacer,{margin:4}),(0,de.jsx)(_e.CheckboxControl,{className:"font-library__select-all",label:(0,rt.__)("Select all"),checked:ne,onChange:xe,indeterminate:W}),(0,de.jsx)(_e.__experimentalVStack,{spacing:0,children:(0,de.jsx)("ul",{role:"list",className:"font-library__fonts-list",children:o&&be(o).map(($,Ce)=>(0,de.jsx)("li",{className:"font-library__fonts-list-item",children:(0,de.jsx)(ly,{font:o,face:$,handleToggleVariant:R,selected:iy(o.slug,o.fontFace?$:null,B)})},`face${Ce}`))})}),(0,de.jsx)(_e.__experimentalSpacer,{margin:16})]})]}),o&&(0,de.jsx)(_e.Flex,{justify:"flex-end",className:"font-library__footer",children:(0,de.jsx)(_e.Button,{__next40pxDefaultSize:!0,variant:"primary",onClick:se,isBusy:x,disabled:l.length===0||x,accessibleWhenDisabled:!0,children:(0,rt.__)("Install")})}),!o&&(0,de.jsxs)(_e.__experimentalHStack,{expanded:!1,className:"font-library__footer",justify:"end",spacing:6,children:[(0,de.jsx)(_e.__experimentalHStack,{justify:"flex-start",expanded:!1,spacing:1,className:"font-library__page-selection",children:(0,yt.createInterpolateElement)((0,rt.sprintf)((0,rt._x)("
Page
%1$s
of %2$d
","paging"),"",S),{div:(0,de.jsx)("div",{"aria-hidden":!0}),CurrentPage:(0,de.jsx)(_e.SelectControl,{"aria-label":(0,rt.__)("Current page"),value:m.toString(),options:[...Array(S)].map(($,Ce)=>({label:(Ce+1).toString(),value:(Ce+1).toString()})),onChange:$=>d(parseInt($)),size:"small",variant:"minimal"})})}),(0,de.jsxs)(_e.__experimentalHStack,{expanded:!1,spacing:1,children:[(0,de.jsx)(_e.Button,{onClick:()=>d(m-1),disabled:m===1,accessibleWhenDisabled:!0,label:(0,rt.__)("Previous page"),icon:(0,rt.isRTL)()?Is:Ns,showTooltip:!0,size:"compact",tooltipPosition:"top"}),(0,de.jsx)(_e.Button,{onClick:()=>d(m+1),disabled:m===S,accessibleWhenDisabled:!0,label:(0,rt.__)("Next page"),icon:(0,rt.isRTL)()?Ns:Is,showTooltip:!0,size:"compact",tooltipPosition:"top"})]})]})]})]})}var sa=ES;var Vn=f(ge(),1),Ot=f(ue(),1),Ci=f(Te(),1);var aa=(e=>typeof Wt<"u"?Wt:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof Wt<"u"?Wt:t)[r]}):e)(function(e){if(typeof Wt<"u")return Wt.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')}),dy=(function(){var e,t,r;return(function(){function o(n,i,s){function a(c,m){if(!i[c]){if(!n[c]){var d=typeof aa=="function"&&aa;if(!m&&d)return d(c,!0);if(u)return u(c,!0);var h=new Error("Cannot find module '"+c+"'");throw h.code="MODULE_NOT_FOUND",h}var g=i[c]={exports:{}};n[c][0].call(g.exports,function(b){var w=n[c][1][b];return a(w||b)},g,g.exports,o,n,i,s)}return i[c].exports}for(var u=typeof aa=="function"&&aa,l=0;l0},c.prototype.readMoreInput=function(){if(!(this.bit_end_pos_>256))if(this.eos_){if(this.bit_pos_>this.bit_end_pos_)throw new Error("Unexpected end of input "+this.bit_pos_+" "+this.bit_end_pos_)}else{var m=this.buf_ptr_,d=this.input_.read(this.buf_,m,s);if(d<0)throw new Error("Unexpected end of input");if(d=8;)this.val_>>>=8,this.val_|=this.buf_[this.pos_&u]<<24,++this.pos_,this.bit_pos_=this.bit_pos_-8>>>0,this.bit_end_pos_=this.bit_end_pos_-8>>>0},c.prototype.readBits=function(m){32-this.bit_pos_>>this.bit_pos_&l[m];return this.bit_pos_+=m,d},n.exports=c},{}],2:[function(o,n,i){var s=0,a=1,u=2,l=3;i.lookup=new Uint8Array([0,0,0,0,0,0,0,0,0,4,4,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,12,16,12,12,20,12,16,24,28,12,12,32,12,36,12,44,44,44,44,44,44,44,44,44,44,32,32,24,40,28,12,12,48,52,52,52,48,52,52,52,48,52,52,52,52,52,48,52,52,52,52,52,48,52,52,52,52,52,24,12,28,12,12,12,56,60,60,60,56,60,60,60,56,60,60,60,60,60,56,60,60,60,60,60,56,60,60,60,60,60,24,12,28,12,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,56,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10,11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,14,15,15,15,15,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,22,22,22,22,23,23,23,23,24,24,24,24,25,25,25,25,26,26,26,26,27,27,27,27,28,28,28,28,29,29,29,29,30,30,30,30,31,31,31,31,32,32,32,32,33,33,33,33,34,34,34,34,35,35,35,35,36,36,36,36,37,37,37,37,38,38,38,38,39,39,39,39,40,40,40,40,41,41,41,41,42,42,42,42,43,43,43,43,44,44,44,44,45,45,45,45,46,46,46,46,47,47,47,47,48,48,48,48,49,49,49,49,50,50,50,50,51,51,51,51,52,52,52,52,53,53,53,53,54,54,54,54,55,55,55,55,56,56,56,56,57,57,57,57,58,58,58,58,59,59,59,59,60,60,60,60,61,61,61,61,62,62,62,62,63,63,63,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]),i.lookupOffsets=new Uint16Array([1024,1536,1280,1536,0,256,768,512])},{}],3:[function(o,n,i){var s=o("./streams").BrotliInput,a=o("./streams").BrotliOutput,u=o("./bit_reader"),l=o("./dictionary"),c=o("./huffman").HuffmanCode,m=o("./huffman").BrotliBuildHuffmanTable,d=o("./context"),h=o("./prefix"),g=o("./transform"),b=8,w=16,_=256,x=704,v=26,C=6,k=2,E=8,T=255,O=1080,I=18,J=new Uint8Array([1,2,3,4,0,5,17,6,16,7,8,9,10,11,12,13,14,15]),D=16,S=new Uint8Array([3,2,1,0,3,3,3,3,3,3,2,2,2,2,2,2]),L=new Int8Array([0,0,0,0,-1,1,-2,2,-3,3,-1,1,-2,2,-3,3]),Y=new Uint16Array([256,402,436,468,500,534,566,598,630,662,694,726,758,790,822,854,886,920,952,984,1016,1048,1080]);function A(X){var M;return X.readBits(1)===0?16:(M=X.readBits(3),M>0?17+M:(M=X.readBits(3),M>0?8+M:17))}function N(X){if(X.readBits(1)){var M=X.readBits(3);return M===0?1:X.readBits(M)+(1<1&&pe===0)throw new Error("Invalid size byte");M.meta_block_length|=pe<4&&le===0)throw new Error("Invalid size nibble");M.meta_block_length|=le<>>K.bit_pos_&T,Q=X[M].bits-E,Q>0&&(K.bit_pos_+=E,M+=X[M].value,M+=K.val_>>>K.bit_pos_&(1<0;){var te=0,Ne;if(H.readMoreInput(),H.fillBitWindow(),te+=H.val_>>>H.bit_pos_&31,H.bit_pos_+=he[te].bits,Ne=he[te].value&255,Ne>Ne);else{var He=Ne-14,ot,Ze,Be=0;if(Ne===w&&(Be=pe),fe!==Be&&(le=0,fe=Be),ot=le,le>0&&(le-=2,le<<=He),le+=H.readBits(He)+3,Ze=le-ot,Q+Ze>M)throw new Error("[ReadHuffmanCodeLengths] symbol + repeat_delta > num_symbols");for(var Ue=0;Ue0;++fe){var Be=J[fe],Ue=0,ct;H.fillBitWindow(),Ue+=H.val_>>>H.bit_pos_&15,H.bit_pos_+=Ze[Ue].bits,ct=Ze[Ue].value,Ne[Be]=ct,ct!==0&&(He-=32>>ct,++ot)}if(!(ot===1||He===0))throw new Error("[ReadHuffmanCode] invalid num_codes or space");B(Ne,X,le,H)}if(Q=m(M,K,E,le,X),Q===0)throw new Error("[ReadHuffmanCode] BuildHuffmanTable failed: ");return Q}function P(X,M,K){var H,Q;return H=R(X,M,K),Q=h.kBlockLengthPrefixCode[H].nbits,h.kBlockLengthPrefixCode[H].offset+K.readBits(Q)}function W(X,M,K){var H;return X>>5]),this.htrees=new Uint32Array(M)}se.prototype.decode=function(X){var M,K,H=0;for(M=0;M=X)throw new Error("[DecodeContextMap] i >= context_map_size");me[le]=0,++le}else me[le]=he-Q,++le}return M.readBits(1)&&xe(me,X),K}function ye(X,M,K,H,Q,pe,le){var fe=K*2,me=K,he=R(M,K*O,le),V;he===0?V=Q[fe+(pe[me]&1)]:he===1?V=Q[fe+(pe[me]-1&1)]+1:V=he-2,V>=X&&(V-=X),H[K]=V,Q[fe+(pe[me]&1)]=V,++pe[me]}function $(X,M,K,H,Q,pe){var le=Q+1,fe=K&Q,me=pe.pos_&u.IBUF_MASK,he;if(M<8||pe.bit_pos_+(M<<3)0;)pe.readMoreInput(),H[fe++]=pe.readBits(8),fe===le&&(X.write(H,le),fe=0);return}if(pe.bit_end_pos_<32)throw new Error("[CopyUncompressedBlockToOutput] br.bit_end_pos_ < 32");for(;pe.bit_pos_<32;)H[fe]=pe.val_>>>pe.bit_pos_,pe.bit_pos_+=8,++fe,--M;if(he=pe.bit_end_pos_-pe.bit_pos_>>3,me+he>u.IBUF_MASK){for(var V=u.IBUF_MASK+1-me,te=0;te=le){X.write(H,le),fe-=le;for(var te=0;te=le;){if(he=le-fe,pe.input_.read(H,fe,he)M.buffer.length){var Fo=new Uint8Array(H+Ye);Fo.set(M.buffer),M.buffer=Fo}if(Q=br.input_end,Yr=br.is_uncompressed,br.is_metadata){for(Ce(Se);Ye>0;--Ye)Se.readMoreInput(),Se.readBits(8);continue}if(Ye!==0){if(Yr){Se.bit_pos_=Se.bit_pos_+7&-8,$(M,Ye,H,V,he,Se),H+=Ye;continue}for(K=0;K<3;++K)vt[K]=N(Se)+1,vt[K]>=2&&(re(vt[K]+2,Ue,K*O,Se),re(v,ct,K*O,Se),St[K]=P(ct,K*O,Se),G[K]=1);for(Se.readMoreInput(),y=Se.readBits(2),oe=D+(Se.readBits(4)<0;){var ft,At,Ht,en,Ea,Ut,er,qr,Hn,tn,Un;for(Se.readMoreInput(),St[1]===0&&(ye(vt[1],Ue,1,kt,F,G,Se),St[1]=P(ct,O,Se),pt=Be[1].htrees[kt[1]]),--St[1],ft=R(Be[1].codes,pt,Se),At=ft>>6,At>=2?(At-=2,er=-1):er=0,Ht=h.kInsertRangeLut[At]+(ft>>3&7),en=h.kCopyRangeLut[At]+(ft&7),Ea=h.kInsertLengthPrefixCode[Ht].offset+Se.readBits(h.kInsertLengthPrefixCode[Ht].nbits),Ut=h.kCopyLengthPrefixCode[en].offset+Se.readBits(h.kCopyLengthPrefixCode[en].nbits),ot=V[H-1&he],Ze=V[H-2&he],tn=0;tn4?3:Ut-2)&255,et=j[kr+Hn],er=R(Be[2].codes,Be[2].htrees[et],Se),er>=oe){var Ta,Au,Wn;er-=oe,Au=er&Ae,er>>=y,Ta=(er>>1)+1,Wn=(2+(er&1)<fe)if(Ut>=l.minDictionaryWordLength&&Ut<=l.maxDictionaryWordLength){var Wn=l.offsetsByLength[Ut],Iu=qr-fe-1,Lu=l.sizeBitsByLength[Ut],Mv=(1<>Lu;if(Wn+=Vv*Ut,Nu=te){M.write(V,me);for(var Fi=0;Fi0&&(Ne[He&3]=qr,++He),Ut>Ye)throw new Error("Invalid backward reference. pos: "+H+" distance: "+qr+" len: "+Ut+" bytes left: "+Ye);for(tn=0;tn>=1;return(m&h-1)+h}function l(m,d,h,g,b){do g-=h,m[d+g]=new s(b.bits,b.value);while(g>0)}function c(m,d,h){for(var g=1<0;--S[x])_=new s(x&255,D[v++]&65535),l(m,d+C,k,I,_),C=u(C,x);for(T=J-1,E=-1,x=h+1,k=2;x<=a;++x,k<<=1)for(;S[x]>0;--S[x])(C&T)!==E&&(d+=I,O=c(S,x,h),I=1<>h),k,I,_),C=u(C,x);return J}},{}],8:[function(o,n,i){"use strict";i.byteLength=h,i.toByteArray=b,i.fromByteArray=x;for(var s=[],a=[],u=typeof Uint8Array<"u"?Uint8Array:Array,l="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",c=0,m=l.length;c0)throw new Error("Invalid string. Length must be a multiple of 4");var k=v.indexOf("=");k===-1&&(k=C);var E=k===C?0:4-k%4;return[k,E]}function h(v){var C=d(v),k=C[0],E=C[1];return(k+E)*3/4-E}function g(v,C,k){return(C+k)*3/4-k}function b(v){for(var C,k=d(v),E=k[0],T=k[1],O=new u(g(v,E,T)),I=0,J=T>0?E-4:E,D=0;D>16&255,O[I++]=C>>8&255,O[I++]=C&255;return T===2&&(C=a[v.charCodeAt(D)]<<2|a[v.charCodeAt(D+1)]>>4,O[I++]=C&255),T===1&&(C=a[v.charCodeAt(D)]<<10|a[v.charCodeAt(D+1)]<<4|a[v.charCodeAt(D+2)]>>2,O[I++]=C>>8&255,O[I++]=C&255),O}function w(v){return s[v>>18&63]+s[v>>12&63]+s[v>>6&63]+s[v&63]}function _(v,C,k){for(var E,T=[],O=C;OJ?J:I+O));return E===1?(C=v[k-1],T.push(s[C>>2]+s[C<<4&63]+"==")):E===2&&(C=(v[k-2]<<8)+v[k-1],T.push(s[C>>10]+s[C>>4&63]+s[C<<2&63]+"=")),T.join("")}},{}],9:[function(o,n,i){function s(a,u){this.offset=a,this.nbits=u}i.kBlockLengthPrefixCode=[new s(1,2),new s(5,2),new s(9,2),new s(13,2),new s(17,3),new s(25,3),new s(33,3),new s(41,3),new s(49,4),new s(65,4),new s(81,4),new s(97,4),new s(113,5),new s(145,5),new s(177,5),new s(209,5),new s(241,6),new s(305,6),new s(369,7),new s(497,8),new s(753,9),new s(1265,10),new s(2289,11),new s(4337,12),new s(8433,13),new s(16625,24)],i.kInsertLengthPrefixCode=[new s(0,0),new s(1,0),new s(2,0),new s(3,0),new s(4,0),new s(5,0),new s(6,1),new s(8,1),new s(10,2),new s(14,2),new s(18,3),new s(26,3),new s(34,4),new s(50,4),new s(66,5),new s(98,5),new s(130,6),new s(194,7),new s(322,8),new s(578,9),new s(1090,10),new s(2114,12),new s(6210,14),new s(22594,24)],i.kCopyLengthPrefixCode=[new s(2,0),new s(3,0),new s(4,0),new s(5,0),new s(6,0),new s(7,0),new s(8,0),new s(9,0),new s(10,1),new s(12,1),new s(14,2),new s(18,2),new s(22,3),new s(30,3),new s(38,4),new s(54,4),new s(70,5),new s(102,5),new s(134,6),new s(198,7),new s(326,8),new s(582,9),new s(1094,10),new s(2118,24)],i.kInsertRangeLut=[0,0,8,8,0,16,8,16,16],i.kCopyRangeLut=[0,8,0,8,16,0,16,8,16]},{}],10:[function(o,n,i){function s(u){this.buffer=u,this.pos=0}s.prototype.read=function(u,l,c){this.pos+c>this.buffer.length&&(c=this.buffer.length-this.pos);for(var m=0;mthis.buffer.length)throw new Error("Output buffer is not large enough");return this.buffer.set(u.subarray(0,l),this.pos),this.pos+=l,l},i.BrotliOutput=a},{}],11:[function(o,n,i){var s=o("./dictionary"),a=0,u=1,l=2,c=3,m=4,d=5,h=6,g=7,b=8,w=9,_=10,x=11,v=12,C=13,k=14,E=15,T=16,O=17,I=18,J=19,D=20;function S(A,N,q){this.prefix=new Uint8Array(A.length),this.transform=N,this.suffix=new Uint8Array(q.length);for(var U=0;U'),new S("",a,` +`),new S("",c,""),new S("",a,"]"),new S("",a," for "),new S("",k,""),new S("",l,""),new S("",a," a "),new S("",a," that "),new S(" ",_,""),new S("",a,". "),new S(".",a,""),new S(" ",a,", "),new S("",E,""),new S("",a," with "),new S("",a,"'"),new S("",a," from "),new S("",a," by "),new S("",T,""),new S("",O,""),new S(" the ",a,""),new S("",m,""),new S("",a,". The "),new S("",x,""),new S("",a," on "),new S("",a," as "),new S("",a," is "),new S("",g,""),new S("",u,"ing "),new S("",a,` + `),new S("",a,":"),new S(" ",a,". "),new S("",a,"ed "),new S("",D,""),new S("",I,""),new S("",h,""),new S("",a,"("),new S("",_,", "),new S("",b,""),new S("",a," at "),new S("",a,"ly "),new S(" the ",a," of "),new S("",d,""),new S("",w,""),new S(" ",_,", "),new S("",_,'"'),new S(".",a,"("),new S("",x," "),new S("",_,'">'),new S("",a,'="'),new S(" ",a,"."),new S(".com/",a,""),new S(" the ",a," of the "),new S("",_,"'"),new S("",a,". This "),new S("",a,","),new S(".",a," "),new S("",_,"("),new S("",_,"."),new S("",a," not "),new S(" ",a,'="'),new S("",a,"er "),new S(" ",x," "),new S("",a,"al "),new S(" ",x,""),new S("",a,"='"),new S("",x,'"'),new S("",_,". "),new S(" ",a,"("),new S("",a,"ful "),new S(" ",_,". "),new S("",a,"ive "),new S("",a,"less "),new S("",x,"'"),new S("",a,"est "),new S(" ",_,"."),new S("",x,'">'),new S(" ",a,"='"),new S("",_,","),new S("",a,"ize "),new S("",x,"."),new S("\xC2\xA0",a,""),new S(" ",a,","),new S("",_,'="'),new S("",x,'="'),new S("",a,"ous "),new S("",x,", "),new S("",_,"='"),new S(" ",_,","),new S(" ",x,'="'),new S(" ",x,", "),new S("",x,","),new S("",x,"("),new S("",x,". "),new S(" ",x,"."),new S("",x,"='"),new S(" ",x,". "),new S(" ",_,'="'),new S(" ",x,"='"),new S(" ",_,"='")];i.kTransforms=L,i.kNumTransforms=L.length;function Y(A,N){return A[N]<192?(A[N]>=97&&A[N]<=122&&(A[N]^=32),1):A[N]<224?(A[N+1]^=32,2):(A[N+2]^=5,3)}i.transformDictionaryWord=function(A,N,q,U,R){var B=L[R].prefix,re=L[R].suffix,P=L[R].transform,W=PU&&(W=U);for(var be=0;be0;){var ye=Y(A,se);se+=ye,U-=ye}for(var $=0;$typeof Wt<"u"?Wt:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof Wt<"u"?Wt:t)[r]}):e)(function(e){if(typeof Wt<"u")return Wt.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')}),py=(function(){var e,t,r;return(function(){function o(n,i,s){function a(c,m){if(!i[c]){if(!n[c]){var d=typeof la=="function"&&la;if(!m&&d)return d(c,!0);if(u)return u(c,!0);var h=new Error("Cannot find module '"+c+"'");throw h.code="MODULE_NOT_FOUND",h}var g=i[c]={exports:{}};n[c][0].call(g.exports,function(b){var w=n[c][1][b];return a(w||b)},g,g.exports,o,n,i,s)}return i[c].exports}for(var u=typeof la=="function"&&la,l=0;l=252?6:c>=248?5:c>=240?4:c>=224?3:c>=192?2:1;l[254]=l[254]=1,i.string2buf=function(d){var h,g,b,w,_,x=d.length,v=0;for(w=0;w>>6,h[_++]=128|g&63):g<65536?(h[_++]=224|g>>>12,h[_++]=128|g>>>6&63,h[_++]=128|g&63):(h[_++]=240|g>>>18,h[_++]=128|g>>>12&63,h[_++]=128|g>>>6&63,h[_++]=128|g&63);return h};function m(d,h){if(h<65534&&(d.subarray&&u||!d.subarray&&a))return String.fromCharCode.apply(null,s.shrinkBuf(d,h));for(var g="",b=0;b4){v[b++]=65533,g+=_-1;continue}for(w&=_===2?31:_===3?15:7;_>1&&g1){v[b++]=65533;continue}w<65536?v[b++]=w:(w-=65536,v[b++]=55296|w>>10&1023,v[b++]=56320|w&1023)}return m(v,b)},i.utf8border=function(d,h){var g;for(h=h||d.length,h>d.length&&(h=d.length),g=h-1;g>=0&&(d[g]&192)===128;)g--;return g<0||g===0?h:g+l[d[g]]>h?g:h}},{"./common":1}],3:[function(o,n,i){"use strict";function s(a,u,l,c){for(var m=a&65535|0,d=a>>>16&65535|0,h=0;l!==0;){h=l>2e3?2e3:l,l-=h;do m=m+u[c++]|0,d=d+m|0;while(--h);m%=65521,d%=65521}return m|d<<16|0}n.exports=s},{}],4:[function(o,n,i){"use strict";n.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],5:[function(o,n,i){"use strict";function s(){for(var l,c=[],m=0;m<256;m++){l=m;for(var d=0;d<8;d++)l=l&1?3988292384^l>>>1:l>>>1;c[m]=l}return c}var a=s();function u(l,c,m,d){var h=a,g=d+m;l^=-1;for(var b=d;b>>8^h[(l^c[b])&255];return l^-1}n.exports=u},{}],6:[function(o,n,i){"use strict";function s(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}n.exports=s},{}],7:[function(o,n,i){"use strict";var s=30,a=12;n.exports=function(l,c){var m,d,h,g,b,w,_,x,v,C,k,E,T,O,I,J,D,S,L,Y,A,N,q,U,R;m=l.state,d=l.next_in,U=l.input,h=d+(l.avail_in-5),g=l.next_out,R=l.output,b=g-(c-l.avail_out),w=g+(l.avail_out-257),_=m.dmax,x=m.wsize,v=m.whave,C=m.wnext,k=m.window,E=m.hold,T=m.bits,O=m.lencode,I=m.distcode,J=(1<>>24,E>>>=L,T-=L,L=S>>>16&255,L===0)R[g++]=S&65535;else if(L&16){Y=S&65535,L&=15,L&&(T>>=L,T-=L),T<15&&(E+=U[d++]<>>24,E>>>=L,T-=L,L=S>>>16&255,L&16){if(A=S&65535,L&=15,T_){l.msg="invalid distance too far back",m.mode=s;break e}if(E>>>=L,T-=L,L=g-b,A>L){if(L=A-L,L>v&&m.sane){l.msg="invalid distance too far back",m.mode=s;break e}if(N=0,q=k,C===0){if(N+=x-L,L2;)R[g++]=q[N++],R[g++]=q[N++],R[g++]=q[N++],Y-=3;Y&&(R[g++]=q[N++],Y>1&&(R[g++]=q[N++]))}else{N=g-A;do R[g++]=R[N++],R[g++]=R[N++],R[g++]=R[N++],Y-=3;while(Y>2);Y&&(R[g++]=R[N++],Y>1&&(R[g++]=R[N++]))}}else if((L&64)===0){S=I[(S&65535)+(E&(1<>3,d-=Y,T-=Y<<3,E&=(1<>>24&255)+(F>>>8&65280)+((F&65280)<<8)+((F&255)<<24)}function Ne(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new s.Buf16(320),this.work=new s.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function He(F){var G;return!F||!F.state?C:(G=F.state,F.total_in=F.total_out=G.total=0,F.msg="",G.wrap&&(F.adler=G.wrap&1),G.mode=I,G.last=0,G.havedict=0,G.dmax=32768,G.head=null,G.hold=0,G.bits=0,G.lencode=G.lendyn=new s.Buf32(fe),G.distcode=G.distdyn=new s.Buf32(me),G.sane=1,G.back=-1,_)}function ot(F){var G;return!F||!F.state?C:(G=F.state,G.wsize=0,G.whave=0,G.wnext=0,He(F))}function Ze(F,G){var y,oe;return!F||!F.state||(oe=F.state,G<0?(y=0,G=-G):(y=(G>>4)+1,G<48&&(G&=15)),G&&(G<8||G>15))?C:(oe.window!==null&&oe.wbits!==G&&(oe.window=null),oe.wrap=y,oe.wbits=G,ot(F))}function Be(F,G){var y,oe;return F?(oe=new Ne,F.state=oe,oe.window=null,y=Ze(F,G),y!==_&&(F.state=null),y):C}function Ue(F){return Be(F,V)}var ct=!0,Se,Or;function $t(F){if(ct){var G;for(Se=new s.Buf32(512),Or=new s.Buf32(32),G=0;G<144;)F.lens[G++]=8;for(;G<256;)F.lens[G++]=9;for(;G<280;)F.lens[G++]=7;for(;G<288;)F.lens[G++]=8;for(c(d,F.lens,0,288,Se,0,F.work,{bits:9}),G=0;G<32;)F.lens[G++]=5;c(h,F.lens,0,32,Or,0,F.work,{bits:5}),ct=!1}F.lencode=Se,F.lenbits=9,F.distcode=Or,F.distbits=5}function Ye(F,G,y,oe){var Ae,ee=F.state;return ee.window===null&&(ee.wsize=1<=ee.wsize?(s.arraySet(ee.window,G,y-ee.wsize,ee.wsize,0),ee.wnext=0,ee.whave=ee.wsize):(Ae=ee.wsize-ee.wnext,Ae>oe&&(Ae=oe),s.arraySet(ee.window,G,y-oe,Ae,ee.wnext),oe-=Ae,oe?(s.arraySet(ee.window,G,y-oe,oe,0),ee.wnext=oe,ee.whave=ee.wsize):(ee.wnext+=Ae,ee.wnext===ee.wsize&&(ee.wnext=0),ee.whave>>8&255,y.check=u(y.check,ft,2,0),j=0,z=0,y.mode=J;break}if(y.flags=0,y.head&&(y.head.done=!1),!(y.wrap&1)||(((j&255)<<8)+(j>>8))%31){F.msg="incorrect header check",y.mode=Q;break}if((j&15)!==O){F.msg="unknown compression method",y.mode=Q;break}if(j>>>=4,z-=4,at=(j&15)+8,y.wbits===0)y.wbits=at;else if(at>y.wbits){F.msg="invalid window size",y.mode=Q;break}y.dmax=1<>8&1),y.flags&512&&(ft[0]=j&255,ft[1]=j>>>8&255,y.check=u(y.check,ft,2,0)),j=0,z=0,y.mode=D;case D:for(;z<32;){if(ie===0)break e;ie--,j+=oe[ee++]<>>8&255,ft[2]=j>>>16&255,ft[3]=j>>>24&255,y.check=u(y.check,ft,4,0)),j=0,z=0,y.mode=S;case S:for(;z<16;){if(ie===0)break e;ie--,j+=oe[ee++]<>8),y.flags&512&&(ft[0]=j&255,ft[1]=j>>>8&255,y.check=u(y.check,ft,2,0)),j=0,z=0,y.mode=L;case L:if(y.flags&1024){for(;z<16;){if(ie===0)break e;ie--,j+=oe[ee++]<>>8&255,y.check=u(y.check,ft,2,0)),j=0,z=0}else y.head&&(y.head.extra=null);y.mode=Y;case Y:if(y.flags&1024&&(ce=y.length,ce>ie&&(ce=ie),ce&&(y.head&&(at=y.head.extra_len-y.length,y.head.extra||(y.head.extra=new Array(y.head.extra_len)),s.arraySet(y.head.extra,oe,ee,ce,at)),y.flags&512&&(y.check=u(y.check,oe,ce,ee)),ie-=ce,ee+=ce,y.length-=ce),y.length))break e;y.length=0,y.mode=A;case A:if(y.flags&2048){if(ie===0)break e;ce=0;do at=oe[ee+ce++],y.head&&at&&y.length<65536&&(y.head.name+=String.fromCharCode(at));while(at&&ce>9&1,y.head.done=!0),F.adler=y.check=0,y.mode=B;break;case U:for(;z<32;){if(ie===0)break e;ie--,j+=oe[ee++]<>>=z&7,z-=z&7,y.mode=M;break}for(;z<3;){if(ie===0)break e;ie--,j+=oe[ee++]<>>=1,z-=1,j&3){case 0:y.mode=P;break;case 1:if($t(y),y.mode=ye,G===w){j>>>=2,z-=2;break e}break;case 2:y.mode=xe;break;case 3:F.msg="invalid block type",y.mode=Q}j>>>=2,z-=2;break;case P:for(j>>>=z&7,z-=z&7;z<32;){if(ie===0)break e;ie--,j+=oe[ee++]<>>16^65535)){F.msg="invalid stored block lengths",y.mode=Q;break}if(y.length=j&65535,j=0,z=0,y.mode=W,G===w)break e;case W:y.mode=ne;case ne:if(ce=y.length,ce){if(ce>ie&&(ce=ie),ce>Je&&(ce=Je),ce===0)break e;s.arraySet(Ae,oe,ee,ce,Qe),ie-=ce,ee+=ce,Je-=ce,Qe+=ce,y.length-=ce;break}y.mode=B;break;case xe:for(;z<14;){if(ie===0)break e;ie--,j+=oe[ee++]<>>=5,z-=5,y.ndist=(j&31)+1,j>>>=5,z-=5,y.ncode=(j&15)+4,j>>>=4,z-=4,y.nlen>286||y.ndist>30){F.msg="too many length or distance symbols",y.mode=Q;break}y.have=0,y.mode=se;case se:for(;y.have>>=3,z-=3}for(;y.have<19;)y.lens[en[y.have++]]=0;if(y.lencode=y.lendyn,y.lenbits=7,At={bits:y.lenbits},Ft=c(m,y.lens,0,19,y.lencode,0,y.work,At),y.lenbits=At.bits,Ft){F.msg="invalid code lengths set",y.mode=Q;break}y.have=0,y.mode=be;case be:for(;y.have>>24,$e=et>>>16&255,ut=et&65535,!(Me<=z);){if(ie===0)break e;ie--,j+=oe[ee++]<>>=Me,z-=Me,y.lens[y.have++]=ut;else{if(ut===16){for(Ht=Me+2;z>>=Me,z-=Me,y.have===0){F.msg="invalid bit length repeat",y.mode=Q;break}at=y.lens[y.have-1],ce=3+(j&3),j>>>=2,z-=2}else if(ut===17){for(Ht=Me+3;z>>=Me,z-=Me,at=0,ce=3+(j&7),j>>>=3,z-=3}else{for(Ht=Me+7;z>>=Me,z-=Me,at=0,ce=11+(j&127),j>>>=7,z-=7}if(y.have+ce>y.nlen+y.ndist){F.msg="invalid bit length repeat",y.mode=Q;break}for(;ce--;)y.lens[y.have++]=at}}if(y.mode===Q)break;if(y.lens[256]===0){F.msg="invalid code -- missing end-of-block",y.mode=Q;break}if(y.lenbits=9,At={bits:y.lenbits},Ft=c(d,y.lens,0,y.nlen,y.lencode,0,y.work,At),y.lenbits=At.bits,Ft){F.msg="invalid literal/lengths set",y.mode=Q;break}if(y.distbits=6,y.distcode=y.distdyn,At={bits:y.distbits},Ft=c(h,y.lens,y.nlen,y.ndist,y.distcode,0,y.work,At),y.distbits=At.bits,Ft){F.msg="invalid distances set",y.mode=Q;break}if(y.mode=ye,G===w)break e;case ye:y.mode=$;case $:if(ie>=6&&Je>=258){F.next_out=Qe,F.avail_out=Je,F.next_in=ee,F.avail_in=ie,y.hold=j,y.bits=z,l(F,je),Qe=F.next_out,Ae=F.output,Je=F.avail_out,ee=F.next_in,oe=F.input,ie=F.avail_in,j=y.hold,z=y.bits,y.mode===B&&(y.back=-1);break}for(y.back=0;et=y.lencode[j&(1<>>24,$e=et>>>16&255,ut=et&65535,!(Me<=z);){if(ie===0)break e;ie--,j+=oe[ee++]<>pt)],Me=et>>>24,$e=et>>>16&255,ut=et&65535,!(pt+Me<=z);){if(ie===0)break e;ie--,j+=oe[ee++]<>>=pt,z-=pt,y.back+=pt}if(j>>>=Me,z-=Me,y.back+=Me,y.length=ut,$e===0){y.mode=X;break}if($e&32){y.back=-1,y.mode=B;break}if($e&64){F.msg="invalid literal/length code",y.mode=Q;break}y.extra=$e&15,y.mode=Ce;case Ce:if(y.extra){for(Ht=y.extra;z>>=y.extra,z-=y.extra,y.back+=y.extra}y.was=y.length,y.mode=Fe;case Fe:for(;et=y.distcode[j&(1<>>24,$e=et>>>16&255,ut=et&65535,!(Me<=z);){if(ie===0)break e;ie--,j+=oe[ee++]<>pt)],Me=et>>>24,$e=et>>>16&255,ut=et&65535,!(pt+Me<=z);){if(ie===0)break e;ie--,j+=oe[ee++]<>>=pt,z-=pt,y.back+=pt}if(j>>>=Me,z-=Me,y.back+=Me,$e&64){F.msg="invalid distance code",y.mode=Q;break}y.offset=ut,y.extra=$e&15,y.mode=xt;case xt:if(y.extra){for(Ht=y.extra;z>>=y.extra,z-=y.extra,y.back+=y.extra}if(y.offset>y.dmax){F.msg="invalid distance too far back",y.mode=Q;break}y.mode=Le;case Le:if(Je===0)break e;if(ce=je-Je,y.offset>ce){if(ce=y.offset-ce,ce>y.whave&&y.sane){F.msg="invalid distance too far back",y.mode=Q;break}ce>y.wnext?(ce-=y.wnext,vr=y.wsize-ce):vr=y.wnext-ce,ce>y.length&&(ce=y.length),kr=y.window}else kr=Ae,vr=Qe-y.offset,ce=y.length;ce>Je&&(ce=Je),Je-=ce,y.length-=ce;do Ae[Qe++]=kr[vr++];while(--ce);y.length===0&&(y.mode=$);break;case X:if(Je===0)break e;Ae[Qe++]=y.length,Je--,y.mode=$;break;case M:if(y.wrap){for(;z<32;){if(ie===0)break e;ie--,j|=oe[ee++]<=1&&$[Y]===0;Y--);if(A>Y&&(A=Y),Y===0)return E[T++]=1<<24|64<<16|0,E[T++]=1<<24|64<<16|0,I.bits=1,0;for(L=1;L0&&(x===c||Y!==1))return-1;for(Ce[1]=0,D=1;Du||x===d&&R>l)return 1;for(;;){Le=D-q,O[S]ye?(X=Fe[xt+O[S]],M=se[be+O[S]]):(X=96,M=0),re=1<>q)+P]=Le<<24|X<<16|M|0;while(P!==0);for(re=1<>=1;if(re!==0?(B&=re-1,B+=re):B=0,S++,--$[D]===0){if(D===Y)break;D=v[C+O[S]]}if(D>A&&(B&ne)!==W){for(q===0&&(q=A),xe+=L,N=D-q,U=1<u||x===d&&R>l)return 1;W=B&ne,E[W]=A<<24|N<<16|xe-T|0}}return B!==0&&(E[xe+B]=D-q<<24|64<<16|0),I.bits=A,0}},{"../utils/common":1}],10:[function(o,n,i){"use strict";n.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],11:[function(o,n,i){"use strict";function s(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}n.exports=s},{}],"/lib/inflate.js":[function(o,n,i){"use strict";var s=o("./zlib/inflate"),a=o("./utils/common"),u=o("./utils/strings"),l=o("./zlib/constants"),c=o("./zlib/messages"),m=o("./zlib/zstream"),d=o("./zlib/gzheader"),h=Object.prototype.toString;function g(_){if(!(this instanceof g))return new g(_);this.options=a.assign({chunkSize:16384,windowBits:0,to:""},_||{});var x=this.options;x.raw&&x.windowBits>=0&&x.windowBits<16&&(x.windowBits=-x.windowBits,x.windowBits===0&&(x.windowBits=-15)),x.windowBits>=0&&x.windowBits<16&&!(_&&_.windowBits)&&(x.windowBits+=32),x.windowBits>15&&x.windowBits<48&&(x.windowBits&15)===0&&(x.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new m,this.strm.avail_out=0;var v=s.inflateInit2(this.strm,x.windowBits);if(v!==l.Z_OK)throw new Error(c[v]);if(this.header=new d,s.inflateGetHeader(this.strm,this.header),x.dictionary&&(typeof x.dictionary=="string"?x.dictionary=u.string2buf(x.dictionary):h.call(x.dictionary)==="[object ArrayBuffer]"&&(x.dictionary=new Uint8Array(x.dictionary)),x.raw&&(v=s.inflateSetDictionary(this.strm,x.dictionary),v!==l.Z_OK)))throw new Error(c[v])}g.prototype.push=function(_,x){var v=this.strm,C=this.options.chunkSize,k=this.options.dictionary,E,T,O,I,J,D=!1;if(this.ended)return!1;T=x===~~x?x:x===!0?l.Z_FINISH:l.Z_NO_FLUSH,typeof _=="string"?v.input=u.binstring2buf(_):h.call(_)==="[object ArrayBuffer]"?v.input=new Uint8Array(_):v.input=_,v.next_in=0,v.avail_in=v.input.length;do{if(v.avail_out===0&&(v.output=new a.Buf8(C),v.next_out=0,v.avail_out=C),E=s.inflate(v,l.Z_NO_FLUSH),E===l.Z_NEED_DICT&&k&&(E=s.inflateSetDictionary(this.strm,k)),E===l.Z_BUF_ERROR&&D===!0&&(E=l.Z_OK,D=!1),E!==l.Z_STREAM_END&&E!==l.Z_OK)return this.onEnd(E),this.ended=!0,!1;v.next_out&&(v.avail_out===0||E===l.Z_STREAM_END||v.avail_in===0&&(T===l.Z_FINISH||T===l.Z_SYNC_FLUSH))&&(this.options.to==="string"?(O=u.utf8border(v.output,v.next_out),I=v.next_out-O,J=u.buf2string(v.output,O),v.next_out=I,v.avail_out=C-I,I&&a.arraySet(v.output,v.output,O,I,0),this.onData(J)):this.onData(a.shrinkBuf(v.output,v.next_out))),v.avail_in===0&&v.avail_out===0&&(D=!0)}while((v.avail_in>0||v.avail_out===0)&&E!==l.Z_STREAM_END);return E===l.Z_STREAM_END&&(T=l.Z_FINISH),T===l.Z_FINISH?(E=s.inflateEnd(this.strm),this.onEnd(E),this.ended=!0,E===l.Z_OK):(T===l.Z_SYNC_FLUSH&&(this.onEnd(l.Z_OK),v.avail_out=0),!0)},g.prototype.onData=function(_){this.chunks.push(_)},g.prototype.onEnd=function(_){_===l.Z_OK&&(this.options.to==="string"?this.result=this.chunks.join(""):this.result=a.flattenChunks(this.chunks)),this.chunks=[],this.err=_,this.msg=this.strm.msg};function b(_,x){var v=new g(x);if(v.push(_,!0),v.err)throw v.msg||c[v.err];return v.result}function w(_,x){return x=x||{},x.raw=!0,b(_,x)}i.Inflate=g,i.inflate=b,i.inflateRaw=w,i.ungzip=b},{"./utils/common":1,"./utils/strings":2,"./zlib/constants":4,"./zlib/gzheader":6,"./zlib/inflate":8,"./zlib/messages":10,"./zlib/zstream":11}]},{},[])("/lib/inflate.js")})();var wM=globalThis.fetch,ca=class{constructor(e,t={},r){this.type=e,this.detail=t,this.msg=r,Object.defineProperty(this,"__mayPropagate",{enumerable:!1,writable:!0}),this.__mayPropagate=!0}preventDefault(){}stopPropagation(){this.__mayPropagate=!1}valueOf(){return this}toString(){return this.msg?`[${this.type} event]: ${this.msg}`:`[${this.type} event]`}},TS=class{constructor(){this.listeners={}}addEventListener(e,t,r){let o=this.listeners[e]||[];r?o.unshift(t):o.push(t),this.listeners[e]=o}removeEventListener(e,t){let r=this.listeners[e]||[],o=r.findIndex(n=>n===t);o>-1&&(r.splice(o,1),this.listeners[e]=r)}dispatch(e){let t=this.listeners[e.type];if(t)for(let r=0,o=t.length;rString.fromCharCode(t)).join("")}var kS=class{constructor(e,t,r){this.name=(r||e.tag||"").trim(),this.length=e.length,this.start=e.offset,this.offset=0,this.data=t,["getInt8","getUint8","getInt16","getUint16","getInt32","getUint32","getBigInt64","getBigUint64"].forEach(o=>{let n=o.replace(/get(Big)?/,"").toLowerCase(),i=parseInt(o.replace(/[^\d]/g,""))/8;Object.defineProperty(this,n,{get:()=>this.getValue(o,i)})})}get currentPosition(){return this.start+this.offset}set currentPosition(e){this.start=e,this.offset=0}skip(e=0,t=8){this.offset+=e*t/8}getValue(e,t){let r=this.start+this.offset;this.offset+=t;try{return this.data[e](r)}catch(o){throw console.error("parser",e,t,this),console.error("parser",this.start,this.offset),o}}flags(e){if(e===8||e===16||e===32||e===64)return this[`uint${e}`].toString(2).padStart(e,0).split("").map(t=>t==="1");console.error("Error parsing flags: flag types can only be 1, 2, 4, or 8 bytes long"),console.trace()}get tag(){let e=this.uint32;return OS([e>>24&255,e>>16&255,e>>8&255,e&255])}get fixed(){let e=this.int16,t=Math.round(1e3*this.uint16/65356);return e+t/1e3}get legacyFixed(){let e=this.uint16,t=this.uint16.toString(16).padStart(4,0);return parseFloat(`${e}.${t}`)}get uint24(){return(this.uint8<<16)+(this.uint8<<8)+this.uint8}get uint128(){let e=0;for(let t=0;t<5;t++){let r=this.uint8;if(e=e*128+(r&127),r<128)break}return e}get longdatetime(){return new Date(PS+1e3*parseInt(this.int64.toString()))}get fword(){return this.int16}get ufword(){return this.uint16}get Offset16(){return this.uint16}get Offset32(){return this.uint32}get F2DOT14(){let e=p.uint16,t=[0,1,-2,-1][e>>14],r=e&16383;return t+r/16384}verifyLength(){this.offset!=this.length&&console.error(`unexpected parsed table size (${this.offset}) for "${this.name}" (expected ${this.length})`)}readBytes(e=0,t=0,r=8,o=!1){if(e=e||this.length,e===0)return[];t&&(this.currentPosition=t);let n=`${o?"":"u"}int${r}`,i=[];for(;e--;)i.push(this[n]);return i}},lt=class{constructor(e){Object.defineProperty(this,"parser",{enumerable:!1,get:()=>e});let r=e.currentPosition;Object.defineProperty(this,"start",{enumerable:!1,get:()=>r})}load(e){Object.keys(e).forEach(t=>{let r=Object.getOwnPropertyDescriptor(e,t);r.get?this[t]=r.get.bind(this):r.value!==void 0&&(this[t]=r.value)}),this.parser.length&&this.parser.verifyLength()}},ke=class extends lt{constructor(e,t,r){let{parser:o,start:n}=super(new kS(e,t,r));Object.defineProperty(this,"p",{enumerable:!1,get:()=>o}),Object.defineProperty(this,"tableStart",{enumerable:!1,get:()=>n})}};function ae(e,t,r){let o;Object.defineProperty(e,t,{get:()=>o||(o=r(),o),enumerable:!0})}var FS=class extends ke{constructor(e,t,r){let{p:o}=super({offset:0,length:12},t,"sfnt");this.version=o.uint32,this.numTables=o.uint16,this.searchRange=o.uint16,this.entrySelector=o.uint16,this.rangeShift=o.uint16,o.verifyLength(),this.directory=[...new Array(this.numTables)].map(n=>new AS(o)),this.tables={},this.directory.forEach(n=>{let i=()=>r(this.tables,{tag:n.tag,offset:n.offset,length:n.length},t);ae(this.tables,n.tag.trim(),i)})}},AS=class{constructor(e){this.tag=e.tag,this.checksum=e.uint32,this.offset=e.uint32,this.length=e.uint32}},my=py.inflate||void 0,hy=void 0,IS=class extends ke{constructor(e,t,r){let{p:o}=super({offset:0,length:44},t,"woff");this.signature=o.tag,this.flavor=o.uint32,this.length=o.uint32,this.numTables=o.uint16,o.uint16,this.totalSfntSize=o.uint32,this.majorVersion=o.uint16,this.minorVersion=o.uint16,this.metaOffset=o.uint32,this.metaLength=o.uint32,this.metaOrigLength=o.uint32,this.privOffset=o.uint32,this.privLength=o.uint32,o.verifyLength(),this.directory=[...new Array(this.numTables)].map(n=>new LS(o)),NS(this,t,r)}},LS=class{constructor(e){this.tag=e.tag,this.offset=e.uint32,this.compLength=e.uint32,this.origLength=e.uint32,this.origChecksum=e.uint32}};function NS(e,t,r){e.tables={},e.directory.forEach(o=>{ae(e.tables,o.tag.trim(),()=>{let n=0,i=t;if(o.compLength!==o.origLength){let s=t.buffer.slice(o.offset,o.offset+o.compLength),a;if(my)a=my(new Uint8Array(s));else if(hy)a=hy(new Uint8Array(s));else{let u="no brotli decoder available to decode WOFF2 font";throw font.onerror&&font.onerror(u),new Error(u)}i=new DataView(a.buffer)}else n=o.offset;return r(e.tables,{tag:o.tag,offset:n,length:o.origLength},i)})})}var gy=dy,yy=void 0,MS=class extends ke{constructor(e,t,r){let{p:o}=super({offset:0,length:48},t,"woff2");this.signature=o.tag,this.flavor=o.uint32,this.length=o.uint32,this.numTables=o.uint16,o.uint16,this.totalSfntSize=o.uint32,this.totalCompressedSize=o.uint32,this.majorVersion=o.uint16,this.minorVersion=o.uint16,this.metaOffset=o.uint32,this.metaLength=o.uint32,this.metaOrigLength=o.uint32,this.privOffset=o.uint32,this.privLength=o.uint32,o.verifyLength(),this.directory=[...new Array(this.numTables)].map(a=>new VS(o));let n=o.currentPosition;this.directory[0].offset=0,this.directory.forEach((a,u)=>{let l=this.directory[u+1];l&&(l.offset=a.offset+(a.transformLength!==void 0?a.transformLength:a.origLength))});let i,s=t.buffer.slice(n);if(gy)i=gy(new Uint8Array(s));else if(yy)i=new Uint8Array(yy(s));else{let a="no brotli decoder available to decode WOFF2 font";throw e.onerror&&e.onerror(a),new Error(a)}DS(this,i,r)}},VS=class{constructor(e){this.flags=e.uint8;let t=this.tagNumber=this.flags&63;t===63?this.tag=e.tag:this.tag=BS(t);let o=(this.transformVersion=(this.flags&192)>>6)!==0;(this.tag==="glyf"||this.tag==="loca")&&(o=this.transformVersion!==3),this.origLength=e.uint128,o&&(this.transformLength=e.uint128)}};function DS(e,t,r){e.tables={},e.directory.forEach(o=>{ae(e.tables,o.tag.trim(),()=>{let n=o.offset,i=n+(o.transformLength?o.transformLength:o.origLength),s=new DataView(t.slice(n,i).buffer);try{return r(e.tables,{tag:o.tag,offset:0,length:o.origLength},s)}catch(a){console.error(a)}})})}function BS(e){return["cmap","head","hhea","hmtx","maxp","name","OS/2","post","cvt ","fpgm","glyf","loca","prep","CFF ","VORG","EBDT","EBLC","gasp","hdmx","kern","LTSH","PCLT","VDMX","vhea","vmtx","BASE","GDEF","GPOS","GSUB","EBSC","JSTF","MATH","CBDT","CBLC","COLR","CPAL","SVG ","sbix","acnt","avar","bdat","bloc","bsln","cvar","fdsc","feat","fmtx","fvar","gvar","hsty","just","lcar","mort","morx","opbd","prop","trak","Zapf","Silf","Glat","Gloc","Feat","Sill"][e&63]}var Cy={},Ry=!1;Promise.all([Promise.resolve().then(function(){return p_}),Promise.resolve().then(function(){return h_}),Promise.resolve().then(function(){return y_}),Promise.resolve().then(function(){return w_}),Promise.resolve().then(function(){return S_}),Promise.resolve().then(function(){return T_}),Promise.resolve().then(function(){return O_}),Promise.resolve().then(function(){return F_}),Promise.resolve().then(function(){return z_}),Promise.resolve().then(function(){return Q_}),Promise.resolve().then(function(){return BC}),Promise.resolve().then(function(){return zC}),Promise.resolve().then(function(){return GC}),Promise.resolve().then(function(){return XC}),Promise.resolve().then(function(){return JC}),Promise.resolve().then(function(){return $C}),Promise.resolve().then(function(){return rR}),Promise.resolve().then(function(){return nR}),Promise.resolve().then(function(){return sR}),Promise.resolve().then(function(){return lR}),Promise.resolve().then(function(){return uR}),Promise.resolve().then(function(){return dR}),Promise.resolve().then(function(){return hR}),Promise.resolve().then(function(){return vR}),Promise.resolve().then(function(){return bR}),Promise.resolve().then(function(){return xR}),Promise.resolve().then(function(){return _R}),Promise.resolve().then(function(){return RR}),Promise.resolve().then(function(){return TR}),Promise.resolve().then(function(){return kR}),Promise.resolve().then(function(){return MR}),Promise.resolve().then(function(){return jR}),Promise.resolve().then(function(){return UR}),Promise.resolve().then(function(){return qR}),Promise.resolve().then(function(){return XR}),Promise.resolve().then(function(){return JR}),Promise.resolve().then(function(){return e2}),Promise.resolve().then(function(){return r2}),Promise.resolve().then(function(){return a2}),Promise.resolve().then(function(){return c2}),Promise.resolve().then(function(){return d2})]).then(e=>{e.forEach(t=>{let r=Object.keys(t)[0];Cy[r]=t[r]}),Ry=!0});function jS(e,t,r){let o=t.tag.replace(/[^\w\d]/g,""),n=Cy[o];return n?new n(t,r,e):(console.warn(`lib-font has no definition for ${o}. The table was skipped.`),{})}function zS(){let e=0;function t(r,o){if(!Ry)return e>10?o(new Error("loading took too long")):(e++,setTimeout(()=>t(r),250));r(jS)}return new Promise((r,o)=>t(r))}function HS(e,t){let r=e.lastIndexOf("."),o=(e.substring(r+1)||"").toLowerCase(),n={ttf:"truetype",otf:"opentype",woff:"woff",woff2:"woff2"}[o];if(n)return n;let i={eot:"The .eot format is not supported: it died in January 12, 2016, when Microsoft retired all versions of IE that didn't already support WOFF.",svg:"The .svg format is not supported: SVG fonts (not to be confused with OpenType with embedded SVG) were so bad we took the entire fonts chapter out of the SVG specification again.",fon:"The .fon format is not supported: this is an ancient Windows bitmap font format.",ttc:"Based on the current CSS specification, font collections are not (yet?) supported."}[o];if(i||(i=`${e} is not a known webfont format.`),t)throw new Error(i);console.warn(`Could not load font: ${i}`)}async function US(e,t,r={}){if(!globalThis.document)return;let o=HS(t,r.errorOnStyle);if(!o)return;let n=document.createElement("style");n.className="injected-by-Font-js";let i=[];return r.styleRules&&(i=Object.entries(r.styleRules).map(([s,a])=>`${s}: ${a};`)),n.textContent=` @font-face { font-family: "${e}"; ${i.join(` `)} src: url("${t}") format("${o}"); -}`,globalThis.document.head.appendChild(n),n}var ZS=[0,1,0,0],XS=[79,84,84,79],KS=[119,79,70,70],JS=[119,79,70,50];function ua(e,t){if(e.length===t.length){for(let r=0;r(globalThis.document&&!this.options.skipStyleSheet&&await qS(this.name,e,this.options),this.loadFont(e)))()}async loadFont(e,t){fetch(e).then(r=>$S(r)&&r.arrayBuffer()).then(r=>this.fromDataBuffer(r,t||e)).catch(r=>{let o=new ca("error",r,`Failed to load font at ${t||e}`);this.dispatch(o),this.onerror&&this.onerror(o)})}async fromDataBuffer(e,t){this.fontData=new DataView(e);let r=QS(this.fontData);if(!r)throw new Error(`${t} is either an unsupported font format, or not a font at all.`);await this.parseBasicData(r);let o=new ca("load",{font:this});this.dispatch(o),this.onload&&this.onload(o)}async parseBasicData(e){return GS().then(t=>(e==="SFNT"&&(this.opentype=new NS(this,this.fontData,t)),e==="WOFF"&&(this.opentype=new VS(this,this.fontData,t)),e==="WOFF2"&&(this.opentype=new jS(this,this.fontData,t)),this.opentype))}getGlyphId(e){return this.opentype.tables.cmap.getGlyphId(e)}reverse(e){return this.opentype.tables.cmap.reverse(e)}supports(e){return this.getGlyphId(e)!==0}supportsVariation(e){return this.opentype.tables.cmap.supportsVariation(e)!==!1}measureText(e,t=16){if(this.__unloaded)throw new Error("Cannot measure text: font was unloaded. Please reload before calling measureText()");let r=document.createElement("div");r.textContent=e,r.style.fontFamily=this.name,r.style.fontSize=`${t}px`,r.style.color="transparent",r.style.background="transparent",r.style.top="0",r.style.left="0",r.style.position="absolute",document.body.appendChild(r);let o=r.getBoundingClientRect();document.body.removeChild(r);let n=this.opentype.tables["OS/2"];return o.fontSize=t,o.ascender=n.sTypoAscender,o.descender=n.sTypoDescender,o}unload(){if(this.styleElement.parentNode){this.styleElement.parentNode.removeElement(this.styleElement);let e=new ca("unload",{font:this});this.dispatch(e),this.onunload&&this.onunload(e)}this._unloaded=!0}load(){if(this.__unloaded){delete this.__unloaded,document.head.appendChild(this.styleElement);let e=new ca("load",{font:this});this.dispatch(e),this.onload&&this.onload(e)}}};globalThis.Font=da;var oo=class extends lt{constructor(e,t,r){super(e),this.plaformID=t,this.encodingID=r}},eC=class extends oo{constructor(e,t,r){super(e,t,r),this.format=0,this.length=e.uint16,this.language=e.uint16,this.glyphIdArray=[...new Array(256)].map(o=>e.uint8)}supports(e){return e.charCodeAt&&(e=-1,console.warn("supports(character) not implemented for cmap subtable format 0. only supports(id) is implemented.")),0<=e&&e<=255}reverse(e){return console.warn("reverse not implemented for cmap subtable format 0"),{}}getSupportedCharCodes(){return[{start:1,end:256}]}},tC=class extends oo{constructor(e,t,r){super(e,t,r),this.format=2,this.length=e.uint16,this.language=e.uint16,this.subHeaderKeys=[...new Array(256)].map(s=>e.uint16);let o=Math.max(...this.subHeaderKeys),n=e.currentPosition;ae(this,"subHeaders",()=>(e.currentPosition=n,[...new Array(o)].map(s=>new rC(e))));let i=n+o*8;ae(this,"glyphIndexArray",()=>(e.currentPosition=i,[...new Array(o)].map(s=>e.uint16)))}supports(e){e.charCodeAt&&(e=-1,console.warn("supports(character) not implemented for cmap subtable format 2. only supports(id) is implemented."));let t=e&&255,r=e&&65280,o=this.subHeaders[r],n=this.subHeaders[o],i=n.firstCode,s=i+n.entryCount;return i<=t&&t<=s}reverse(e){return console.warn("reverse not implemented for cmap subtable format 2"),{}}getSupportedCharCodes(e=!1){return e?this.subHeaders.map(t=>({firstCode:t.firstCode,lastCode:t.lastCode})):this.subHeaders.map(t=>({start:t.firstCode,end:t.lastCode}))}},rC=class{constructor(e){this.firstCode=e.uint16,this.entryCount=e.uint16,this.lastCode=this.first+this.entryCount,this.idDelta=e.int16,this.idRangeOffset=e.uint16}},oC=class extends oo{constructor(e,t,r){super(e,t,r),this.format=4,this.length=e.uint16,this.language=e.uint16,this.segCountX2=e.uint16,this.segCount=this.segCountX2/2,this.searchRange=e.uint16,this.entrySelector=e.uint16,this.rangeShift=e.uint16;let o=e.currentPosition;ae(this,"endCode",()=>e.readBytes(this.segCount,o,16));let n=o+2+this.segCountX2;ae(this,"startCode",()=>e.readBytes(this.segCount,n,16));let i=n+this.segCountX2;ae(this,"idDelta",()=>e.readBytes(this.segCount,i,16,!0));let s=i+this.segCountX2;ae(this,"idRangeOffset",()=>e.readBytes(this.segCount,s,16));let a=s+this.segCountX2,u=this.length-(a-this.tableStart);ae(this,"glyphIdArray",()=>e.readBytes(u,a,16)),ae(this,"segments",()=>this.buildSegments(s,a,e))}buildSegments(e,t,r){let o=(n,i)=>{let s=this.startCode[i],a=this.endCode[i],u=this.idDelta[i],l=this.idRangeOffset[i],c=e+2*i,m=[];if(l===0)for(let d=s+u,h=a+u;d<=h;d++)m.push(d);else for(let d=0,h=a-s;d<=h;d++)r.currentPosition=c+l+d*2,m.push(r.uint16);return{startCode:s,endCode:a,idDelta:u,idRangeOffset:l,glyphIDs:m}};return[...new Array(this.segCount)].map(o)}reverse(e){let t=this.segments.find(o=>o.glyphIDs.includes(e));if(!t)return{};let r=t.startCode+t.glyphIDs.indexOf(e);return{code:r,unicode:String.fromCodePoint(r)}}getGlyphId(e){if(e.charCodeAt&&(e=e.charCodeAt(0)),55296<=e&&e<=57343||(e&65534)===65534||(e&65535)===65535)return 0;let t=this.segments.find(r=>r.startCode<=e&&e<=r.endCode);return t?t.glyphIDs[e-t.startCode]:0}supports(e){return this.getGlyphId(e)!==0}getSupportedCharCodes(e=!1){return e?this.segments:this.segments.map(t=>({start:t.startCode,end:t.endCode}))}},nC=class extends oo{constructor(e,t,r){super(e,t,r),this.format=6,this.length=e.uint16,this.language=e.uint16,this.firstCode=e.uint16,this.entryCount=e.uint16,this.lastCode=this.firstCode+this.entryCount-1,ae(this,"glyphIdArray",()=>[...new Array(this.entryCount)].map(n=>e.uint16))}supports(e){if(e.charCodeAt&&(e=-1,console.warn("supports(character) not implemented for cmap subtable format 6. only supports(id) is implemented.")),ethis.firstCode+this.entryCount)return{};let t=e-this.firstCode;return{code:t,unicode:String.fromCodePoint(t)}}reverse(e){let t=this.glyphIdArray.indexOf(e);if(t>-1)return this.firstCode+t}getSupportedCharCodes(e=!1){return e?[{firstCode:this.firstCode,lastCode:this.lastCode}]:[{start:this.firstCode,end:this.lastCode}]}},iC=class extends oo{constructor(e,t,r){super(e,t,r),this.format=8,e.uint16,this.length=e.uint32,this.language=e.uint32,this.is32=[...new Array(8192)].map(n=>e.uint8),this.numGroups=e.uint32,ae(this,"groups",()=>[...new Array(this.numGroups)].map(n=>new sC(e)))}supports(e){return e.charCodeAt&&(e=-1,console.warn("supports(character) not implemented for cmap subtable format 8. only supports(id) is implemented.")),this.groups.findIndex(t=>t.startcharCode<=e&&e<=t.endcharCode)!==-1}reverse(e){return console.warn("reverse not implemented for cmap subtable format 8"),{}}getSupportedCharCodes(e=!1){return e?this.groups:this.groups.map(t=>({start:t.startcharCode,end:t.endcharCode}))}},sC=class{constructor(e){this.startcharCode=e.uint32,this.endcharCode=e.uint32,this.startGlyphID=e.uint32}},aC=class extends oo{constructor(e,t,r){super(e,t,r),this.format=10,e.uint16,this.length=e.uint32,this.language=e.uint32,this.startCharCode=e.uint32,this.numChars=e.uint32,this.endCharCode=this.startCharCode+this.numChars,ae(this,"glyphs",()=>[...new Array(this.numChars)].map(n=>e.uint16))}supports(e){return e.charCodeAt&&(e=-1,console.warn("supports(character) not implemented for cmap subtable format 10. only supports(id) is implemented.")),ethis.startCharCode+this.numChars?!1:e-this.startCharCode}reverse(e){return console.warn("reverse not implemented for cmap subtable format 10"),{}}getSupportedCharCodes(e=!1){return e?[{startCharCode:this.startCharCode,endCharCode:this.endCharCode}]:[{start:this.startCharCode,end:this.endCharCode}]}},lC=class extends oo{constructor(e,t,r){super(e,t,r),this.format=12,e.uint16,this.length=e.uint32,this.language=e.uint32,this.numGroups=e.uint32,ae(this,"groups",()=>[...new Array(this.numGroups)].map(n=>new cC(e)))}supports(e){return e.charCodeAt&&(e=e.charCodeAt(0)),55296<=e&&e<=57343||(e&65534)===65534||(e&65535)===65535?0:this.groups.findIndex(t=>t.startCharCode<=e&&e<=t.endCharCode)!==-1}reverse(e){for(let t of this.groups){let r=t.startGlyphID;if(r>e)continue;if(r===e)return t.startCharCode;if(r+(t.endCharCode-t.startCharCode)({start:t.startCharCode,end:t.endCharCode}))}},cC=class{constructor(e){this.startCharCode=e.uint32,this.endCharCode=e.uint32,this.startGlyphID=e.uint32}},uC=class extends oo{constructor(e,t,r){super(e,t,r),this.format=13,e.uint16,this.length=e.uint32,this.language=e.uint32,this.numGroups=e.uint32;let o=[...new Array(this.numGroups)].map(n=>new fC(e));ae(this,"groups",o)}supports(e){return e.charCodeAt&&(e=e.charCodeAt(0)),this.groups.findIndex(t=>t.startCharCode<=e&&e<=t.endCharCode)!==-1}reverse(e){return console.warn("reverse not implemented for cmap subtable format 13"),{}}getSupportedCharCodes(e=!1){return e?this.groups:this.groups.map(t=>({start:t.startCharCode,end:t.endCharCode}))}},fC=class{constructor(e){this.startCharCode=e.uint32,this.endCharCode=e.uint32,this.glyphID=e.uint32}},dC=class extends oo{constructor(e,t,r){super(e,t,r),this.subTableStart=e.currentPosition,this.format=14,this.length=e.uint32,this.numVarSelectorRecords=e.uint32,ae(this,"varSelectors",()=>[...new Array(this.numVarSelectorRecords)].map(o=>new pC(e)))}supports(){return console.warn("supports not implemented for cmap subtable format 14"),0}getSupportedCharCodes(){return console.warn("getSupportedCharCodes not implemented for cmap subtable format 14"),[]}reverse(e){return console.warn("reverse not implemented for cmap subtable format 14"),{}}supportsVariation(e){let t=this.varSelector.find(r=>r.varSelector===e);return t||!1}getSupportedVariations(){return this.varSelectors.map(e=>e.varSelector)}},pC=class{constructor(e){this.varSelector=e.uint24,this.defaultUVSOffset=e.Offset32,this.nonDefaultUVSOffset=e.Offset32}};function mC(e,t,r){let o=e.uint16;return o===0?new eC(e,t,r):o===2?new tC(e,t,r):o===4?new oC(e,t,r):o===6?new nC(e,t,r):o===8?new iC(e,t,r):o===10?new aC(e,t,r):o===12?new lC(e,t,r):o===13?new uC(e,t,r):o===14?new dC(e,t,r):{}}var hC=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.numTables=r.uint16,this.encodingRecords=[...new Array(this.numTables)].map(o=>new gC(r,this.tableStart))}getSubTable(e){return this.encodingRecords[e].table}getSupportedEncodings(){return this.encodingRecords.map(e=>({platformID:e.platformID,encodingId:e.encodingID}))}getSupportedCharCodes(e,t){let r=this.encodingRecords.findIndex(n=>n.platformID===e&&n.encodingID===t);return r===-1?!1:this.getSubTable(r).getSupportedCharCodes()}reverse(e){for(let t=0;t{let n=this.getSubTable(o);return n.getGlyphId?(t=n.getGlyphId(e),t!==0):!1}),t}supports(e){return this.encodingRecords.some((t,r)=>{let o=this.getSubTable(r);return o.supports&&o.supports(e)!==!1})}supportsVariation(e){return this.encodingRecords.some((t,r)=>{let o=this.getSubTable(r);return o.supportsVariation&&o.supportsVariation(e)!==!1})}},gC=class{constructor(e,t){let r=this.platformID=e.uint16,o=this.encodingID=e.uint16,n=this.offset=e.Offset32;ae(this,"table",()=>(e.currentPosition=t+n,mC(e,r,o)))}},yC=Object.freeze({__proto__:null,cmap:hC}),vC=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.load({majorVersion:r.uint16,minorVersion:r.uint16,fontRevision:r.fixed,checkSumAdjustment:r.uint32,magicNumber:r.uint32,flags:r.flags(16),unitsPerEm:r.uint16,created:r.longdatetime,modified:r.longdatetime,xMin:r.int16,yMin:r.int16,xMax:r.int16,yMax:r.int16,macStyle:r.flags(16),lowestRecPPEM:r.uint16,fontDirectionHint:r.uint16,indexToLocFormat:r.uint16,glyphDataFormat:r.uint16})}},bC=Object.freeze({__proto__:null,head:vC}),wC=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.majorVersion=r.uint16,this.minorVersion=r.uint16,this.ascender=r.fword,this.descender=r.fword,this.lineGap=r.fword,this.advanceWidthMax=r.ufword,this.minLeftSideBearing=r.fword,this.minRightSideBearing=r.fword,this.xMaxExtent=r.fword,this.caretSlopeRise=r.int16,this.caretSlopeRun=r.int16,this.caretOffset=r.int16,r.int16,r.int16,r.int16,r.int16,this.metricDataFormat=r.int16,this.numberOfHMetrics=r.uint16,r.verifyLength()}},xC=Object.freeze({__proto__:null,hhea:wC}),SC=class extends ke{constructor(e,t,r){let{p:o}=super(e,t),n=r.hhea.numberOfHMetrics,i=r.maxp.numGlyphs,s=o.currentPosition;if(ae(this,"hMetrics",()=>(o.currentPosition=s,[...new Array(n)].map(a=>new CC(o.uint16,o.int16)))),n(o.currentPosition=a,[...new Array(i-n)].map(u=>o.int16)))}}},CC=class{constructor(e,t){this.advanceWidth=e,this.lsb=t}},_C=Object.freeze({__proto__:null,hmtx:SC}),RC=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.legacyFixed,this.numGlyphs=r.uint16,this.version===1&&(this.maxPoints=r.uint16,this.maxContours=r.uint16,this.maxCompositePoints=r.uint16,this.maxCompositeContours=r.uint16,this.maxZones=r.uint16,this.maxTwilightPoints=r.uint16,this.maxStorage=r.uint16,this.maxFunctionDefs=r.uint16,this.maxInstructionDefs=r.uint16,this.maxStackElements=r.uint16,this.maxSizeOfInstructions=r.uint16,this.maxComponentElements=r.uint16,this.maxComponentDepth=r.uint16),r.verifyLength()}},EC=Object.freeze({__proto__:null,maxp:RC}),TC=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.format=r.uint16,this.count=r.uint16,this.stringOffset=r.Offset16,this.nameRecords=[...new Array(this.count)].map(o=>new OC(r,this)),this.format===1&&(this.langTagCount=r.uint16,this.langTagRecords=[...new Array(this.langTagCount)].map(o=>new PC(r.uint16,r.Offset16))),this.stringStart=this.tableStart+this.stringOffset}get(e){let t=this.nameRecords.find(r=>r.nameID===e);if(t)return t.string}},PC=class{constructor(e,t){this.length=e,this.offset=t}},OC=class{constructor(e,t){this.platformID=e.uint16,this.encodingID=e.uint16,this.languageID=e.uint16,this.nameID=e.uint16,this.length=e.uint16,this.offset=e.Offset16,ae(this,"string",()=>(e.currentPosition=t.stringStart+this.offset,kC(e,this)))}};function kC(e,t){let{platformID:r,length:o}=t;if(o===0)return"";if(r===0||r===3){let s=[];for(let a=0,u=o/2;ar.uint8),this.ulUnicodeRange1=r.flags(32),this.ulUnicodeRange2=r.flags(32),this.ulUnicodeRange3=r.flags(32),this.ulUnicodeRange4=r.flags(32),this.achVendID=r.tag,this.fsSelection=r.uint16,this.usFirstCharIndex=r.uint16,this.usLastCharIndex=r.uint16,this.sTypoAscender=r.int16,this.sTypoDescender=r.int16,this.sTypoLineGap=r.int16,this.usWinAscent=r.uint16,this.usWinDescent=r.uint16,this.version===0||(this.ulCodePageRange1=r.flags(32),this.ulCodePageRange2=r.flags(32),this.version===1)||(this.sxHeight=r.int16,this.sCapHeight=r.int16,this.usDefaultChar=r.uint16,this.usBreakChar=r.uint16,this.usMaxContext=r.uint16,this.version<=4)||(this.usLowerOpticalPointSize=r.uint16,this.usUpperOpticalPointSize=r.uint16,this.version===5))return r.verifyLength()}},IC=Object.freeze({__proto__:null,OS2:AC}),LC=class extends ke{constructor(e,t){let{p:r}=super(e,t);if(this.version=r.legacyFixed,this.italicAngle=r.fixed,this.underlinePosition=r.fword,this.underlineThickness=r.fword,this.isFixedPitch=r.uint32,this.minMemType42=r.uint32,this.maxMemType42=r.uint32,this.minMemType1=r.uint32,this.maxMemType1=r.uint32,this.version===1||this.version===3)return r.verifyLength();if(this.numGlyphs=r.uint16,this.version===2){this.glyphNameIndex=[...new Array(this.numGlyphs)].map(o=>r.uint16),this.namesOffset=r.currentPosition,this.glyphNameOffsets=[1];for(let o=0;or.int8))}getGlyphName(e){if(this.version!==2)return console.warn(`post table version ${this.version} does not support glyph name lookups`),"";let t=this.glyphNameIndex[e];if(t<258)return Ry[t];let r=this.glyphNameOffsets[e],n=this.glyphNameOffsets[e+1]-r-1;return n===0?".notdef.":(this.parser.currentPosition=this.namesOffset+r,this.parser.readBytes(n,this.namesOffset+r,8,!0).map(s=>String.fromCharCode(s)).join(""))}},Ry=[".notdef",".null","nonmarkingreturn","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quotesingle","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","grave","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","Adieresis","Aring","Ccedilla","Eacute","Ntilde","Odieresis","Udieresis","aacute","agrave","acircumflex","adieresis","atilde","aring","ccedilla","eacute","egrave","ecircumflex","edieresis","iacute","igrave","icircumflex","idieresis","ntilde","oacute","ograve","ocircumflex","odieresis","otilde","uacute","ugrave","ucircumflex","udieresis","dagger","degree","cent","sterling","section","bullet","paragraph","germandbls","registered","copyright","trademark","acute","dieresis","notequal","AE","Oslash","infinity","plusminus","lessequal","greaterequal","yen","mu","partialdiff","summation","product","pi","integral","ordfeminine","ordmasculine","Omega","ae","oslash","questiondown","exclamdown","logicalnot","radical","florin","approxequal","Delta","guillemotleft","guillemotright","ellipsis","nonbreakingspace","Agrave","Atilde","Otilde","OE","oe","endash","emdash","quotedblleft","quotedblright","quoteleft","quoteright","divide","lozenge","ydieresis","Ydieresis","fraction","currency","guilsinglleft","guilsinglright","fi","fl","daggerdbl","periodcentered","quotesinglbase","quotedblbase","perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave","Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex","apple","Ograve","Uacute","Ucircumflex","Ugrave","dotlessi","circumflex","tilde","macron","breve","dotaccent","ring","cedilla","hungarumlaut","ogonek","caron","Lslash","lslash","Scaron","scaron","Zcaron","zcaron","brokenbar","Eth","eth","Yacute","yacute","Thorn","thorn","minus","multiply","onesuperior","twosuperior","threesuperior","onehalf","onequarter","threequarters","franc","Gbreve","gbreve","Idotaccent","Scedilla","scedilla","Cacute","cacute","Ccaron","ccaron","dcroat"],NC=Object.freeze({__proto__:null,post:LC}),MC=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.majorVersion=r.uint16,this.minorVersion=r.uint16,this.horizAxisOffset=r.Offset16,this.vertAxisOffset=r.Offset16,ae(this,"horizAxis",()=>new nu({offset:e.offset+this.horizAxisOffset},t)),ae(this,"vertAxis",()=>new nu({offset:e.offset+this.vertAxisOffset},t)),this.majorVersion===1&&this.minorVersion===1&&(this.itemVarStoreOffset=r.Offset32,ae(this,"itemVarStore",()=>new nu({offset:e.offset+this.itemVarStoreOffset},t)))}},nu=class extends ke{constructor(e,t){let{p:r}=super(e,t,"AxisTable");this.baseTagListOffset=r.Offset16,this.baseScriptListOffset=r.Offset16,ae(this,"baseTagList",()=>new VC({offset:e.offset+this.baseTagListOffset},t)),ae(this,"baseScriptList",()=>new DC({offset:e.offset+this.baseScriptListOffset},t))}},VC=class extends ke{constructor(e,t){let{p:r}=super(e,t,"BaseTagListTable");this.baseTagCount=r.uint16,this.baselineTags=[...new Array(this.baseTagCount)].map(o=>r.tag)}},DC=class extends ke{constructor(e,t){let{p:r}=super(e,t,"BaseScriptListTable");this.baseScriptCount=r.uint16;let o=r.currentPosition;ae(this,"baseScriptRecords",()=>(r.currentPosition=o,[...new Array(this.baseScriptCount)].map(n=>new BC(this.start,r))))}},BC=class{constructor(e,t){this.baseScriptTag=t.tag,this.baseScriptOffset=t.Offset16,ae(this,"baseScriptTable",()=>(t.currentPosition=e+this.baseScriptOffset,new jC(t)))}},jC=class{constructor(e){this.start=e.currentPosition,this.baseValuesOffset=e.Offset16,this.defaultMinMaxOffset=e.Offset16,this.baseLangSysCount=e.uint16,this.baseLangSysRecords=[...new Array(this.baseLangSysCount)].map(t=>new zC(this.start,e)),ae(this,"baseValues",()=>(e.currentPosition=this.start+this.baseValuesOffset,new HC(e))),ae(this,"defaultMinMax",()=>(e.currentPosition=this.start+this.defaultMinMaxOffset,new Iy(e)))}},zC=class{constructor(e,t){this.baseLangSysTag=t.tag,this.minMaxOffset=t.Offset16,ae(this,"minMax",()=>(t.currentPosition=e+this.minMaxOffset,new Iy(t)))}},HC=class{constructor(e){this.parser=e,this.start=e.currentPosition,this.defaultBaselineIndex=e.uint16,this.baseCoordCount=e.uint16,this.baseCoords=[...new Array(this.baseCoordCount)].map(t=>e.Offset16)}getTable(e){return this.parser.currentPosition=this.start+this.baseCoords[e],new WC(this.parser)}},Iy=class{constructor(e){this.minCoord=e.Offset16,this.maxCoord=e.Offset16,this.featMinMaxCount=e.uint16;let t=e.currentPosition;ae(this,"featMinMaxRecords",()=>(e.currentPosition=t,[...new Array(this.featMinMaxCount)].map(r=>new UC(e))))}},UC=class{constructor(e){this.featureTableTag=e.tag,this.minCoord=e.Offset16,this.maxCoord=e.Offset16}},WC=class{constructor(e){this.baseCoordFormat=e.uint16,this.coordinate=e.int16,this.baseCoordFormat===2&&(this.referenceGlyph=e.uint16,this.baseCoordPoint=e.uint16),this.baseCoordFormat===3&&(this.deviceTable=e.Offset16)}},GC=Object.freeze({__proto__:null,BASE:MC}),Ey=class{constructor(e){this.classFormat=e.uint16,this.classFormat===1&&(this.startGlyphID=e.uint16,this.glyphCount=e.uint16,this.classValueArray=[...new Array(this.glyphCount)].map(t=>e.uint16)),this.classFormat===2&&(this.classRangeCount=e.uint16,this.classRangeRecords=[...new Array(this.classRangeCount)].map(t=>new YC(e)))}},YC=class{constructor(e){this.startGlyphID=e.uint16,this.endGlyphID=e.uint16,this.class=e.uint16}},Ci=class extends lt{constructor(e){super(e),this.coverageFormat=e.uint16,this.coverageFormat===1&&(this.glyphCount=e.uint16,this.glyphArray=[...new Array(this.glyphCount)].map(t=>e.uint16)),this.coverageFormat===2&&(this.rangeCount=e.uint16,this.rangeRecords=[...new Array(this.rangeCount)].map(t=>new qC(e)))}},qC=class{constructor(e){this.startGlyphID=e.uint16,this.endGlyphID=e.uint16,this.startCoverageIndex=e.uint16}},ZC=class{constructor(e,t){this.table=e,this.parser=t,this.start=t.currentPosition,this.format=t.uint16,this.variationRegionListOffset=t.Offset32,this.itemVariationDataCount=t.uint16,this.itemVariationDataOffsets=[...new Array(this.itemVariationDataCount)].map(r=>t.Offset32)}},XC=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.majorVersion=r.uint16,this.minorVersion=r.uint16,this.glyphClassDefOffset=r.Offset16,ae(this,"glyphClassDefs",()=>{if(this.glyphClassDefOffset!==0)return r.currentPosition=this.tableStart+this.glyphClassDefOffset,new Ey(r)}),this.attachListOffset=r.Offset16,ae(this,"attachList",()=>{if(this.attachListOffset!==0)return r.currentPosition=this.tableStart+this.attachListOffset,new KC(r)}),this.ligCaretListOffset=r.Offset16,ae(this,"ligCaretList",()=>{if(this.ligCaretListOffset!==0)return r.currentPosition=this.tableStart+this.ligCaretListOffset,new QC(r)}),this.markAttachClassDefOffset=r.Offset16,ae(this,"markAttachClassDef",()=>{if(this.markAttachClassDefOffset!==0)return r.currentPosition=this.tableStart+this.markAttachClassDefOffset,new Ey(r)}),this.minorVersion>=2&&(this.markGlyphSetsDefOffset=r.Offset16,ae(this,"markGlyphSetsDef",()=>{if(this.markGlyphSetsDefOffset!==0)return r.currentPosition=this.tableStart+this.markGlyphSetsDefOffset,new t_(r)})),this.minorVersion===3&&(this.itemVarStoreOffset=r.Offset32,ae(this,"itemVarStore",()=>{if(this.itemVarStoreOffset!==0)return r.currentPosition=this.tableStart+this.itemVarStoreOffset,new ZC(r)}))}},KC=class extends lt{constructor(e){super(e),this.coverageOffset=e.Offset16,this.glyphCount=e.uint16,this.attachPointOffsets=[...new Array(this.glyphCount)].map(t=>e.Offset16)}getPoint(e){return this.parser.currentPosition=this.start+this.attachPointOffsets[e],new JC(this.parser)}},JC=class{constructor(e){this.pointCount=e.uint16,this.pointIndices=[...new Array(this.pointCount)].map(t=>e.uint16)}},QC=class extends lt{constructor(e){super(e),this.coverageOffset=e.Offset16,ae(this,"coverage",()=>(e.currentPosition=this.start+this.coverageOffset,new Ci(e))),this.ligGlyphCount=e.uint16,this.ligGlyphOffsets=[...new Array(this.ligGlyphCount)].map(t=>e.Offset16)}getLigGlyph(e){return this.parser.currentPosition=this.start+this.ligGlyphOffsets[e],new $C(this.parser)}},$C=class extends lt{constructor(e){super(e),this.caretCount=e.uint16,this.caretValueOffsets=[...new Array(this.caretCount)].map(t=>e.Offset16)}getCaretValue(e){return this.parser.currentPosition=this.start+this.caretValueOffsets[e],new e_(this.parser)}},e_=class{constructor(e){this.caretValueFormat=e.uint16,this.caretValueFormat===1&&(this.coordinate=e.int16),this.caretValueFormat===2&&(this.caretValuePointIndex=e.uint16),this.caretValueFormat===3&&(this.coordinate=e.int16,this.deviceOffset=e.Offset16)}},t_=class extends lt{constructor(e){super(e),this.markGlyphSetTableFormat=e.uint16,this.markGlyphSetCount=e.uint16,this.coverageOffsets=[...new Array(this.markGlyphSetCount)].map(t=>e.Offset32)}getMarkGlyphSet(e){return this.parser.currentPosition=this.start+this.coverageOffsets[e],new Ci(this.parser)}},r_=Object.freeze({__proto__:null,GDEF:XC}),Ty=class extends lt{static EMPTY={scriptCount:0,scriptRecords:[]};constructor(e){super(e),this.scriptCount=e.uint16,this.scriptRecords=[...new Array(this.scriptCount)].map(t=>new o_(e))}},o_=class{constructor(e){this.scriptTag=e.tag,this.scriptOffset=e.Offset16}},n_=class extends lt{constructor(e){super(e),this.defaultLangSys=e.Offset16,this.langSysCount=e.uint16,this.langSysRecords=[...new Array(this.langSysCount)].map(t=>new i_(e))}},i_=class{constructor(e){this.langSysTag=e.tag,this.langSysOffset=e.Offset16}},Py=class{constructor(e){this.lookupOrder=e.Offset16,this.requiredFeatureIndex=e.uint16,this.featureIndexCount=e.uint16,this.featureIndices=[...new Array(this.featureIndexCount)].map(t=>e.uint16)}},Oy=class extends lt{static EMPTY={featureCount:0,featureRecords:[]};constructor(e){super(e),this.featureCount=e.uint16,this.featureRecords=[...new Array(this.featureCount)].map(t=>new s_(e))}},s_=class{constructor(e){this.featureTag=e.tag,this.featureOffset=e.Offset16}},a_=class extends lt{constructor(e){super(e),this.featureParams=e.Offset16,this.lookupIndexCount=e.uint16,this.lookupListIndices=[...new Array(this.lookupIndexCount)].map(t=>e.uint16)}getFeatureParams(){if(this.featureParams>0){let e=this.parser;e.currentPosition=this.start+this.featureParams;let t=this.featureTag;if(t==="size")return new c_(e);if(t.startsWith("cc"))return new l_(e);if(t.startsWith("ss"))return new u_(e)}}},l_=class{constructor(e){this.format=e.uint16,this.featUiLabelNameId=e.uint16,this.featUiTooltipTextNameId=e.uint16,this.sampleTextNameId=e.uint16,this.numNamedParameters=e.uint16,this.firstParamUiLabelNameId=e.uint16,this.charCount=e.uint16,this.character=[...new Array(this.charCount)].map(t=>e.uint24)}},c_=class{constructor(e){this.designSize=e.uint16,this.subfamilyIdentifier=e.uint16,this.subfamilyNameID=e.uint16,this.smallEnd=e.uint16,this.largeEnd=e.uint16}},u_=class{constructor(e){this.version=e.uint16,this.UINameID=e.uint16}};function Ly(e){e.parser.currentPosition-=2,delete e.coverageOffset,delete e.getCoverageTable}var Qo=class extends lt{constructor(e){super(e),this.substFormat=e.uint16,this.coverageOffset=e.Offset16}getCoverageTable(){let e=this.parser;return e.currentPosition=this.start+this.coverageOffset,new Ci(e)}},su=class{constructor(e){this.glyphSequenceIndex=e.uint16,this.lookupListIndex=e.uint16}},f_=class extends Qo{constructor(e){super(e),this.deltaGlyphID=e.int16}},d_=class extends Qo{constructor(e){super(e),this.sequenceCount=e.uint16,this.sequenceOffsets=[...new Array(this.sequenceCount)].map(t=>e.Offset16)}getSequence(e){let t=this.parser;return t.currentPosition=this.start+this.sequenceOffsets[e],new p_(t)}},p_=class{constructor(e){this.glyphCount=e.uint16,this.substituteGlyphIDs=[...new Array(this.glyphCount)].map(t=>e.uint16)}},m_=class extends Qo{constructor(e){super(e),this.alternateSetCount=e.uint16,this.alternateSetOffsets=[...new Array(this.alternateSetCount)].map(t=>e.Offset16)}getAlternateSet(e){let t=this.parser;return t.currentPosition=this.start+this.alternateSetOffsets[e],new h_(t)}},h_=class{constructor(e){this.glyphCount=e.uint16,this.alternateGlyphIDs=[...new Array(this.glyphCount)].map(t=>e.uint16)}},g_=class extends Qo{constructor(e){super(e),this.ligatureSetCount=e.uint16,this.ligatureSetOffsets=[...new Array(this.ligatureSetCount)].map(t=>e.Offset16)}getLigatureSet(e){let t=this.parser;return t.currentPosition=this.start+this.ligatureSetOffsets[e],new y_(t)}},y_=class extends lt{constructor(e){super(e),this.ligatureCount=e.uint16,this.ligatureOffsets=[...new Array(this.ligatureCount)].map(t=>e.Offset16)}getLigature(e){let t=this.parser;return t.currentPosition=this.start+this.ligatureOffsets[e],new v_(t)}},v_=class{constructor(e){this.ligatureGlyph=e.uint16,this.componentCount=e.uint16,this.componentGlyphIDs=[...new Array(this.componentCount-1)].map(t=>e.uint16)}},b_=class extends Qo{constructor(e){super(e),this.substFormat===1&&(this.subRuleSetCount=e.uint16,this.subRuleSetOffsets=[...new Array(this.subRuleSetCount)].map(t=>e.Offset16)),this.substFormat===2&&(this.classDefOffset=e.Offset16,this.subClassSetCount=e.uint16,this.subClassSetOffsets=[...new Array(this.subClassSetCount)].map(t=>e.Offset16)),this.substFormat===3&&(Ly(this),this.glyphCount=e.uint16,this.substitutionCount=e.uint16,this.coverageOffsets=[...new Array(this.glyphCount)].map(t=>e.Offset16),this.substLookupRecords=[...new Array(this.substitutionCount)].map(t=>new su(e)))}getSubRuleSet(e){if(this.substFormat!==1)throw new Error(`lookup type 5.${this.substFormat} has no subrule sets.`);let t=this.parser;return t.currentPosition=this.start+this.subRuleSetOffsets[e],new w_(t)}getSubClassSet(e){if(this.substFormat!==2)throw new Error(`lookup type 5.${this.substFormat} has no subclass sets.`);let t=this.parser;return t.currentPosition=this.start+this.subClassSetOffsets[e],new x_(t)}getCoverageTable(e){if(this.substFormat!==3&&!e)return super.getCoverageTable();if(!e)throw new Error(`lookup type 5.${this.substFormat} requires an coverage table index.`);let t=this.parser;return t.currentPosition=this.start+this.coverageOffsets[e],new Ci(t)}},w_=class extends lt{constructor(e){super(e),this.subRuleCount=e.uint16,this.subRuleOffsets=[...new Array(this.subRuleCount)].map(t=>e.Offset16)}getSubRule(e){let t=this.parser;return t.currentPosition=this.start+this.subRuleOffsets[e],new Ny(t)}},Ny=class{constructor(e){this.glyphCount=e.uint16,this.substitutionCount=e.uint16,this.inputSequence=[...new Array(this.glyphCount-1)].map(t=>e.uint16),this.substLookupRecords=[...new Array(this.substitutionCount)].map(t=>new su(e))}},x_=class extends lt{constructor(e){super(e),this.subClassRuleCount=e.uint16,this.subClassRuleOffsets=[...new Array(this.subClassRuleCount)].map(t=>e.Offset16)}getSubClass(e){let t=this.parser;return t.currentPosition=this.start+this.subClassRuleOffsets[e],new S_(t)}},S_=class extends Ny{constructor(e){super(e)}},C_=class extends Qo{constructor(e){super(e),this.substFormat===1&&(this.chainSubRuleSetCount=e.uint16,this.chainSubRuleSetOffsets=[...new Array(this.chainSubRuleSetCount)].map(t=>e.Offset16)),this.substFormat===2&&(this.backtrackClassDefOffset=e.Offset16,this.inputClassDefOffset=e.Offset16,this.lookaheadClassDefOffset=e.Offset16,this.chainSubClassSetCount=e.uint16,this.chainSubClassSetOffsets=[...new Array(this.chainSubClassSetCount)].map(t=>e.Offset16)),this.substFormat===3&&(Ly(this),this.backtrackGlyphCount=e.uint16,this.backtrackCoverageOffsets=[...new Array(this.backtrackGlyphCount)].map(t=>e.Offset16),this.inputGlyphCount=e.uint16,this.inputCoverageOffsets=[...new Array(this.inputGlyphCount)].map(t=>e.Offset16),this.lookaheadGlyphCount=e.uint16,this.lookaheadCoverageOffsets=[...new Array(this.lookaheadGlyphCount)].map(t=>e.Offset16),this.seqLookupCount=e.uint16,this.seqLookupRecords=[...new Array(this.substitutionCount)].map(t=>new My(e)))}getChainSubRuleSet(e){if(this.substFormat!==1)throw new Error(`lookup type 6.${this.substFormat} has no chainsubrule sets.`);let t=this.parser;return t.currentPosition=this.start+this.chainSubRuleSetOffsets[e],new __(t)}getChainSubClassSet(e){if(this.substFormat!==2)throw new Error(`lookup type 6.${this.substFormat} has no chainsubclass sets.`);let t=this.parser;return t.currentPosition=this.start+this.chainSubClassSetOffsets[e],new E_(t)}getCoverageFromOffset(e){if(this.substFormat!==3)throw new Error(`lookup type 6.${this.substFormat} does not use contextual coverage offsets.`);let t=this.parser;return t.currentPosition=this.start+e,new Ci(t)}},__=class extends lt{constructor(e){super(e),this.chainSubRuleCount=e.uint16,this.chainSubRuleOffsets=[...new Array(this.chainSubRuleCount)].map(t=>e.Offset16)}getSubRule(e){let t=this.parser;return t.currentPosition=this.start+this.chainSubRuleOffsets[e],new R_(t)}},R_=class{constructor(e){this.backtrackGlyphCount=e.uint16,this.backtrackSequence=[...new Array(this.backtrackGlyphCount)].map(t=>e.uint16),this.inputGlyphCount=e.uint16,this.inputSequence=[...new Array(this.inputGlyphCount-1)].map(t=>e.uint16),this.lookaheadGlyphCount=e.uint16,this.lookAheadSequence=[...new Array(this.lookAheadGlyphCount)].map(t=>e.uint16),this.substitutionCount=e.uint16,this.substLookupRecords=[...new Array(this.SubstCount)].map(t=>new su(e))}},E_=class extends lt{constructor(e){super(e),this.chainSubClassRuleCount=e.uint16,this.chainSubClassRuleOffsets=[...new Array(this.chainSubClassRuleCount)].map(t=>e.Offset16)}getSubClass(e){let t=this.parser;return t.currentPosition=this.start+this.chainSubRuleOffsets[e],new T_(t)}},T_=class{constructor(e){this.backtrackGlyphCount=e.uint16,this.backtrackSequence=[...new Array(this.backtrackGlyphCount)].map(t=>e.uint16),this.inputGlyphCount=e.uint16,this.inputSequence=[...new Array(this.inputGlyphCount-1)].map(t=>e.uint16),this.lookaheadGlyphCount=e.uint16,this.lookAheadSequence=[...new Array(this.lookAheadGlyphCount)].map(t=>e.uint16),this.substitutionCount=e.uint16,this.substLookupRecords=[...new Array(this.substitutionCount)].map(t=>new My(e))}},My=class extends lt{constructor(e){super(e),this.sequenceIndex=e.uint16,this.lookupListIndex=e.uint16}},P_=class extends lt{constructor(e){super(e),this.substFormat=e.uint16,this.extensionLookupType=e.uint16,this.extensionOffset=e.Offset32}},O_=class extends Qo{constructor(e){super(e),this.backtrackGlyphCount=e.uint16,this.backtrackCoverageOffsets=[...new Array(this.backtrackGlyphCount)].map(t=>e.Offset16),this.lookaheadGlyphCount=e.uint16,this.lookaheadCoverageOffsets=[new Array(this.lookaheadGlyphCount)].map(t=>e.Offset16),this.glyphCount=e.uint16,this.substituteGlyphIDs=[...new Array(this.glyphCount)].map(t=>e.uint16)}},k_={buildSubtable:function(e,t){let r=new[void 0,f_,d_,m_,g_,b_,C_,P_,O_][e](t);return r.type=e,r}},no=class extends lt{constructor(e){super(e)}},F_=class extends no{constructor(e){super(e),console.log("lookup type 1")}},A_=class extends no{constructor(e){super(e),console.log("lookup type 2")}},I_=class extends no{constructor(e){super(e),console.log("lookup type 3")}},L_=class extends no{constructor(e){super(e),console.log("lookup type 4")}},N_=class extends no{constructor(e){super(e),console.log("lookup type 5")}},M_=class extends no{constructor(e){super(e),console.log("lookup type 6")}},V_=class extends no{constructor(e){super(e),console.log("lookup type 7")}},D_=class extends no{constructor(e){super(e),console.log("lookup type 8")}},B_=class extends no{constructor(e){super(e),console.log("lookup type 9")}},j_={buildSubtable:function(e,t){let r=new[void 0,F_,A_,I_,L_,N_,M_,V_,D_,B_][e](t);return r.type=e,r}},ky=class extends lt{static EMPTY={lookupCount:0,lookups:[]};constructor(e){super(e),this.lookupCount=e.uint16,this.lookups=[...new Array(this.lookupCount)].map(t=>e.Offset16)}},z_=class extends lt{constructor(e,t){super(e),this.ctType=t,this.lookupType=e.uint16,this.lookupFlag=e.uint16,this.subTableCount=e.uint16,this.subtableOffsets=[...new Array(this.subTableCount)].map(r=>e.Offset16),this.markFilteringSet=e.uint16}get rightToLeft(){return this.lookupFlag&!0}get ignoreBaseGlyphs(){return this.lookupFlag&!0}get ignoreLigatures(){return this.lookupFlag&!0}get ignoreMarks(){return this.lookupFlag&!0}get useMarkFilteringSet(){return this.lookupFlag&!0}get markAttachmentType(){return this.lookupFlag&!0}getSubTable(e){let t=this.ctType==="GSUB"?k_:j_;return this.parser.currentPosition=this.start+this.subtableOffsets[e],t.buildSubtable(this.lookupType,this.parser)}},Vy=class extends ke{constructor(e,t,r){let{p:o,tableStart:n}=super(e,t,r);this.majorVersion=o.uint16,this.minorVersion=o.uint16,this.scriptListOffset=o.Offset16,this.featureListOffset=o.Offset16,this.lookupListOffset=o.Offset16,this.majorVersion===1&&this.minorVersion===1&&(this.featureVariationsOffset=o.Offset32);let i=!(this.scriptListOffset||this.featureListOffset||this.lookupListOffset);ae(this,"scriptList",()=>i?Ty.EMPTY:(o.currentPosition=n+this.scriptListOffset,new Ty(o))),ae(this,"featureList",()=>i?Oy.EMPTY:(o.currentPosition=n+this.featureListOffset,new Oy(o))),ae(this,"lookupList",()=>i?ky.EMPTY:(o.currentPosition=n+this.lookupListOffset,new ky(o))),this.featureVariationsOffset&&ae(this,"featureVariations",()=>i?FeatureVariations.EMPTY:(o.currentPosition=n+this.featureVariationsOffset,new FeatureVariations(o)))}getSupportedScripts(){return this.scriptList.scriptRecords.map(e=>e.scriptTag)}getScriptTable(e){let t=this.scriptList.scriptRecords.find(o=>o.scriptTag===e);this.parser.currentPosition=this.scriptList.start+t.scriptOffset;let r=new n_(this.parser);return r.scriptTag=e,r}ensureScriptTable(e){return typeof e=="string"?this.getScriptTable(e):e}getSupportedLangSys(e){e=this.ensureScriptTable(e);let t=e.defaultLangSys!==0,r=e.langSysRecords.map(o=>o.langSysTag);return t&&r.unshift("dflt"),r}getDefaultLangSysTable(e){e=this.ensureScriptTable(e);let t=e.defaultLangSys;if(t!==0){this.parser.currentPosition=e.start+t;let r=new Py(this.parser);return r.langSysTag="",r.defaultForScript=e.scriptTag,r}}getLangSysTable(e,t="dflt"){if(t==="dflt")return this.getDefaultLangSysTable(e);e=this.ensureScriptTable(e);let r=e.langSysRecords.find(n=>n.langSysTag===t);this.parser.currentPosition=e.start+r.langSysOffset;let o=new Py(this.parser);return o.langSysTag=t,o}getFeatures(e){return e.featureIndices.map(t=>this.getFeature(t))}getFeature(e){let t;if(parseInt(e)==e?t=this.featureList.featureRecords[e]:t=this.featureList.featureRecords.find(o=>o.featureTag===e),!t)return;this.parser.currentPosition=this.featureList.start+t.featureOffset;let r=new a_(this.parser);return r.featureTag=t.featureTag,r}getLookups(e){return e.lookupListIndices.map(t=>this.getLookup(t))}getLookup(e,t){let r=this.lookupList.lookups[e];return this.parser.currentPosition=this.lookupList.start+r,new z_(this.parser,t)}},H_=class extends Vy{constructor(e,t){super(e,t,"GSUB")}getLookup(e){return super.getLookup(e,"GSUB")}},U_=Object.freeze({__proto__:null,GSUB:H_}),W_=class extends Vy{constructor(e,t){super(e,t,"GPOS")}getLookup(e){return super.getLookup(e,"GPOS")}},G_=Object.freeze({__proto__:null,GPOS:W_}),Y_=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.offsetToSVGDocumentList=r.Offset32,r.currentPosition=this.tableStart+this.offsetToSVGDocumentList,this.documentList=new q_(r)}},q_=class extends lt{constructor(e){super(e),this.numEntries=e.uint16,this.documentRecords=[...new Array(this.numEntries)].map(t=>new Z_(e))}getDocument(e){let t=this.documentRecords[e];if(!t)return"";let r=this.start+t.svgDocOffset;return this.parser.currentPosition=r,this.parser.readBytes(t.svgDocLength)}getDocumentForGlyph(e){let t=this.documentRecords.findIndex(r=>r.startGlyphID<=e&&e<=r.endGlyphID);return t===-1?"":this.getDocument(t)}},Z_=class{constructor(e){this.startGlyphID=e.uint16,this.endGlyphID=e.uint16,this.svgDocOffset=e.Offset32,this.svgDocLength=e.uint32}},X_=Object.freeze({__proto__:null,SVG:Y_}),K_=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.majorVersion=r.uint16,this.minorVersion=r.uint16,this.axesArrayOffset=r.Offset16,r.uint16,this.axisCount=r.uint16,this.axisSize=r.uint16,this.instanceCount=r.uint16,this.instanceSize=r.uint16;let o=this.tableStart+this.axesArrayOffset;ae(this,"axes",()=>(r.currentPosition=o,[...new Array(this.axisCount)].map(i=>new J_(r))));let n=o+this.axisCount*this.axisSize;ae(this,"instances",()=>{let i=[];for(let s=0;se.tag)}getAxis(e){return this.axes.find(t=>t.tag===e)}},J_=class{constructor(e){this.tag=e.tag,this.minValue=e.fixed,this.defaultValue=e.fixed,this.maxValue=e.fixed,this.flags=e.flags(16),this.axisNameID=e.uint16}},Q_=class{constructor(e,t,r){let o=e.currentPosition;this.subfamilyNameID=e.uint16,e.uint16,this.coordinates=[...new Array(t)].map(n=>e.fixed),e.currentPosition-o[...new Array(o)].map(n=>r.fword))}},tR=Object.freeze({__proto__:null,cvt:eR}),rR=class extends ke{constructor(e,t){let{p:r}=super(e,t);ae(this,"instructions",()=>[...new Array(e.length)].map(o=>r.uint8))}},oR=Object.freeze({__proto__:null,fpgm:rR}),nR=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.numRanges=r.uint16,ae(this,"gaspRanges",()=>[...new Array(this.numRanges)].map(n=>new iR(r)))}},iR=class{constructor(e){this.rangeMaxPPEM=e.uint16,this.rangeGaspBehavior=e.uint16}},sR=Object.freeze({__proto__:null,gasp:nR}),aR=class extends ke{constructor(e,t){super(e,t)}getGlyphData(e,t){return this.parser.currentPosition=this.tableStart+e,this.parser.readBytes(t)}},lR=Object.freeze({__proto__:null,glyf:aR}),cR=class extends ke{constructor(e,t,r){let{p:o}=super(e,t),n=r.maxp.numGlyphs+1;r.head.indexToLocFormat===0?(this.x2=!0,ae(this,"offsets",()=>[...new Array(n)].map(i=>o.Offset16))):ae(this,"offsets",()=>[...new Array(n)].map(i=>o.Offset32))}getGlyphDataOffsetAndLength(e){let t=this.offsets[e]*this.x2?2:1,r=this.offsets[e+1]*this.x2?2:1;return{offset:t,length:r-t}}},uR=Object.freeze({__proto__:null,loca:cR}),fR=class extends ke{constructor(e,t){let{p:r}=super(e,t);ae(this,"instructions",()=>[...new Array(e.length)].map(o=>r.uint8))}},dR=Object.freeze({__proto__:null,prep:fR}),pR=class extends ke{constructor(e,t){let{p:r}=super(e,t);ae(this,"data",()=>r.readBytes())}},mR=Object.freeze({__proto__:null,CFF:pR}),hR=class extends ke{constructor(e,t){let{p:r}=super(e,t);ae(this,"data",()=>r.readBytes())}},gR=Object.freeze({__proto__:null,CFF2:hR}),yR=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.majorVersion=r.uint16,this.minorVersion=r.uint16,this.defaultVertOriginY=r.int16,this.numVertOriginYMetrics=r.uint16,ae(this,"vertORiginYMetrics",()=>[...new Array(this.numVertOriginYMetrics)].map(o=>new vR(r)))}},vR=class{constructor(e){this.glyphIndex=e.uint16,this.vertOriginY=e.int16}},bR=Object.freeze({__proto__:null,VORG:yR}),wR=class{constructor(e){this.indexSubTableArrayOffset=e.Offset32,this.indexTablesSize=e.uint32,this.numberofIndexSubTables=e.uint32,this.colorRef=e.uint32,this.hori=new fa(e),this.vert=new fa(e),this.startGlyphIndex=e.uint16,this.endGlyphIndex=e.uint16,this.ppemX=e.uint8,this.ppemY=e.uint8,this.bitDepth=e.uint8,this.flags=e.int8}},xR=class{constructor(e){this.hori=new fa(e),this.vert=new fa(e),this.ppemX=e.uint8,this.ppemY=e.uint8,this.substitutePpemX=e.uint8,this.substitutePpemY=e.uint8}},fa=class{constructor(e){this.ascender=e.int8,this.descender=e.int8,this.widthMax=e.uint8,this.caretSlopeNumerator=e.int8,this.caretSlopeDenominator=e.int8,this.caretOffset=e.int8,this.minOriginSB=e.int8,this.minAdvanceSB=e.int8,this.maxBeforeBL=e.int8,this.minAfterBL=e.int8,this.pad1=e.int8,this.pad2=e.int8}},Dy=class extends ke{constructor(e,t,r){let{p:o}=super(e,t,r);this.majorVersion=o.uint16,this.minorVersion=o.uint16,this.numSizes=o.uint32,ae(this,"bitMapSizes",()=>[...new Array(this.numSizes)].map(n=>new wR(o)))}},SR=Object.freeze({__proto__:null,EBLC:Dy}),By=class extends ke{constructor(e,t,r){let{p:o}=super(e,t,r);this.majorVersion=o.uint16,this.minorVersion=o.uint16}},CR=Object.freeze({__proto__:null,EBDT:By}),_R=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.majorVersion=r.uint16,this.minorVersion=r.uint16,this.numSizes=r.uint32,ae(this,"bitmapScales",()=>[...new Array(this.numSizes)].map(o=>new xR(r)))}},RR=Object.freeze({__proto__:null,EBSC:_R}),ER=class extends Dy{constructor(e,t){super(e,t,"CBLC")}},TR=Object.freeze({__proto__:null,CBLC:ER}),PR=class extends By{constructor(e,t){super(e,t,"CBDT")}},OR=Object.freeze({__proto__:null,CBDT:PR}),kR=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.flags=r.flags(16),this.numStrikes=r.uint32,ae(this,"strikeOffsets",()=>[...new Array(this.numStrikes)].map(o=>r.Offset32))}},FR=Object.freeze({__proto__:null,sbix:kR}),AR=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.numBaseGlyphRecords=r.uint16,this.baseGlyphRecordsOffset=r.Offset32,this.layerRecordsOffset=r.Offset32,this.numLayerRecords=r.uint16}getBaseGlyphRecord(e){let t=this.tableStart+this.baseGlyphRecordsOffset;this.parser.currentPosition=t;let r=new iu(this.parser),o=r.gID,n=this.tableStart+this.layerRecordsOffset-6;this.parser.currentPosition=n;let i=new iu(this.parser),s=i.gID;if(o===e)return r;if(s===e)return i;for(;t!==n;){let a=t+(n-t)/12;this.parser.currentPosition=a;let u=new iu(this.parser),l=u.gID;if(l===e)return u;l>e?n=a:lnew IR(p))}},iu=class{constructor(e){this.gID=e.uint16,this.firstLayerIndex=e.uint16,this.numLayers=e.uint16}},IR=class{constructor(e){this.gID=e.uint16,this.paletteIndex=e.uint16}},LR=Object.freeze({__proto__:null,COLR:AR}),NR=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.numPaletteEntries=r.uint16;let o=this.numPalettes=r.uint16;this.numColorRecords=r.uint16,this.offsetFirstColorRecord=r.Offset32,this.colorRecordIndices=[...new Array(this.numPalettes)].map(n=>r.uint16),ae(this,"colorRecords",()=>(r.currentPosition=this.tableStart+this.offsetFirstColorRecord,[...new Array(this.numColorRecords)].map(n=>new MR(r)))),this.version===1&&(this.offsetPaletteTypeArray=r.Offset32,this.offsetPaletteLabelArray=r.Offset32,this.offsetPaletteEntryLabelArray=r.Offset32,ae(this,"paletteTypeArray",()=>(r.currentPosition=this.tableStart+this.offsetPaletteTypeArray,new VR(r,o))),ae(this,"paletteLabelArray",()=>(r.currentPosition=this.tableStart+this.offsetPaletteLabelArray,new DR(r,o))),ae(this,"paletteEntryLabelArray",()=>(r.currentPosition=this.tableStart+this.offsetPaletteEntryLabelArray,new BR(r,o))))}},MR=class{constructor(e){this.blue=e.uint8,this.green=e.uint8,this.red=e.uint8,this.alpha=e.uint8}},VR=class{constructor(e,t){this.paletteTypes=[...new Array(t)].map(r=>e.uint32)}},DR=class{constructor(e,t){this.paletteLabels=[...new Array(t)].map(r=>e.uint16)}},BR=class{constructor(e,t){this.paletteEntryLabels=[...new Array(t)].map(r=>e.uint16)}},jR=Object.freeze({__proto__:null,CPAL:NR}),zR=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint32,this.numSignatures=r.uint16,this.flags=r.uint16,this.signatureRecords=[...new Array(this.numSignatures)].map(o=>new HR(r))}getData(e){let t=this.signatureRecords[e];return this.parser.currentPosition=this.tableStart+t.offset,new UR(this.parser)}},HR=class{constructor(e){this.format=e.uint32,this.length=e.uint32,this.offset=e.Offset32}},UR=class{constructor(e){e.uint16,e.uint16,this.signatureLength=e.uint32,this.signature=e.readBytes(this.signatureLength)}},WR=Object.freeze({__proto__:null,DSIG:zR}),GR=class extends ke{constructor(e,t,r){let{p:o}=super(e,t),n=r.hmtx.numGlyphs;this.version=o.uint16,this.numRecords=o.int16,this.sizeDeviceRecord=o.int32,this.records=[...new Array(numRecords)].map(i=>new YR(o,n))}},YR=class{constructor(e,t){this.pixelSize=e.uint8,this.maxWidth=e.uint8,this.widths=e.readBytes(t)}},qR=Object.freeze({__proto__:null,hdmx:GR}),ZR=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.nTables=r.uint16,ae(this,"tables",()=>{let o=this.tableStart+4,n=[];for(let i=0;i[...new Array(this.nPairs)].map(t=>new KR(e)))),this.format===2&&console.warn("Kern subtable format 2 is not supported: this parser currently only parses universal table data.")}get horizontal(){return this.coverage[0]}get minimum(){return this.coverage[1]}get crossstream(){return this.coverage[2]}get override(){return this.coverage[3]}},KR=class{constructor(e){this.left=e.uint16,this.right=e.uint16,this.value=e.fword}},JR=Object.freeze({__proto__:null,kern:ZR}),QR=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.numGlyphs=r.uint16,this.yPels=r.readBytes(this.numGlyphs)}},$R=Object.freeze({__proto__:null,LTSH:QR}),e2=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.mergeClassCount=r.uint16,this.mergeDataOffset=r.Offset16,this.classDefCount=r.uint16,this.offsetToClassDefOffsets=r.Offset16,ae(this,"mergeEntryMatrix",()=>[...new Array(this.mergeClassCount)].map(o=>r.readBytes(this.mergeClassCount))),console.warn("Full MERG parsing is currently not supported."),console.warn("If you need this table parsed, please file an issue, or better yet, a PR.")}},t2=Object.freeze({__proto__:null,MERG:e2}),r2=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint32,this.flags=r.uint32,r.uint32,this.dataMapsCount=r.uint32,this.dataMaps=[...new Array(this.dataMapsCount)].map(o=>new o2(this.tableStart,r))}},o2=class{constructor(e,t){this.tableStart=e,this.parser=t,this.tag=t.tag,this.dataOffset=t.Offset32,this.dataLength=t.uint32}getData(){return this.parser.currentField=this.tableStart+this.dataOffset,this.parser.readBytes(this.dataLength)}},n2=Object.freeze({__proto__:null,meta:r2}),i2=class extends ke{constructor(e,t){super(e,t),console.warn("This font uses a PCLT table, which is currently not supported by this parser."),console.warn("If you need this table parsed, please file an issue, or better yet, a PR.")}},s2=Object.freeze({__proto__:null,PCLT:i2}),a2=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.numRecs=r.uint16,this.numRatios=r.uint16,this.ratRanges=[...new Array(this.numRatios)].map(o=>new l2(r)),this.offsets=[...new Array(this.numRatios)].map(o=>r.Offset16),this.VDMXGroups=[...new Array(this.numRecs)].map(o=>new c2(r))}},l2=class{constructor(e){this.bCharSet=e.uint8,this.xRatio=e.uint8,this.yStartRatio=e.uint8,this.yEndRatio=e.uint8}},c2=class{constructor(e){this.recs=e.uint16,this.startsz=e.uint8,this.endsz=e.uint8,this.records=[...new Array(this.recs)].map(t=>new u2(e))}},u2=class{constructor(e){this.yPelHeight=e.uint16,this.yMax=e.int16,this.yMin=e.int16}},f2=Object.freeze({__proto__:null,VDMX:a2}),d2=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.fixed,this.ascent=this.vertTypoAscender=r.int16,this.descent=this.vertTypoDescender=r.int16,this.lineGap=this.vertTypoLineGap=r.int16,this.advanceHeightMax=r.int16,this.minTopSideBearing=r.int16,this.minBottomSideBearing=r.int16,this.yMaxExtent=r.int16,this.caretSlopeRise=r.int16,this.caretSlopeRun=r.int16,this.caretOffset=r.int16,this.reserved=r.int16,this.reserved=r.int16,this.reserved=r.int16,this.reserved=r.int16,this.metricDataFormat=r.int16,this.numOfLongVerMetrics=r.uint16,r.verifyLength()}},p2=Object.freeze({__proto__:null,vhea:d2}),m2=class extends ke{constructor(e,t,r){super(e,t);let o=r.vhea.numOfLongVerMetrics,n=r.maxp.numGlyphs,i=p.currentPosition;if(lazy(this,"vMetrics",()=>(p.currentPosition=i,[...new Array(o)].map(s=>new h2(p.uint16,p.int16)))),o(p.currentPosition=s,[...new Array(n-o)].map(a=>p.int16)))}}},h2=class{constructor(e,t){this.advanceHeight=e,this.topSideBearing=t}},g2=Object.freeze({__proto__:null,vmtx:m2});function jy(e){let t=e.reduce((r,o)=>(r[o.fontFamily]||(r[o.fontFamily]={name:o.fontFamily,fontFamily:o.fontFamily,slug:Ks(o.fontFamily.toLowerCase()),fontFace:[]}),r[o.fontFamily].fontFace.push(o),r),{});return Object.values(t)}var Qt=f(Z(),1);function y2(){let{installFonts:e}=(0,_i.useContext)(jt),[t,r]=(0,_i.useState)(!1),[o,n]=(0,_i.useState)(null),i=h=>{a(h)},s=h=>{a(h.target.files)},a=async h=>{if(!h)return;n(null),r(!0);let g=new Set,b=[...h],w=!1,C=b.map(async v=>{if(!await l(v))return w=!0,null;if(g.has(v.name))return null;let k=(((v.name??"").split(".")??[]).pop()??"").toLowerCase();return eu.includes(k)?(g.add(v.name),v):null}),x=(await Promise.all(C)).filter(v=>v!==null);if(x.length>0)u(x);else{let v=w?(0,Vn.__)("Sorry, you are not allowed to upload this file type."):(0,Vn.__)("No fonts found to install.");n({type:"error",message:v}),r(!1)}},u=async h=>{let g=await Promise.all(h.map(async b=>{let w=await m(b);return await Po(w,w.file,"all"),w}));d(g)};async function l(h){let g=new da("Uploaded Font");try{let b=await c(h);return await g.fromDataBuffer(b,"font"),!0}catch{return!1}}async function c(h){return new Promise((g,b)=>{let w=new window.FileReader;w.readAsArrayBuffer(h),w.onload=()=>g(w.result),w.onerror=b})}let m=async h=>{let g=await c(h),b=new da("Uploaded Font");b.fromDataBuffer(g,h.name);let C=(await new Promise(I=>b.onload=I)).detail.font,{name:x}=C.opentype.tables,v=x.get(16)||x.get(1),_=x.get(2).toLowerCase().includes("italic"),k=C.opentype.tables["OS/2"].usWeightClass||"normal",T=!!C.opentype.tables.fvar&&C.opentype.tables.fvar.axes.find(({tag:I})=>I==="wght"),O=T?`${T.minValue} ${T.maxValue}`:null;return{file:h,fontFamily:v,fontStyle:_?"italic":"normal",fontWeight:O||k}},d=async h=>{let g=jy(h);try{await e(g),n({type:"success",message:(0,Vn.__)("Fonts were installed successfully.")})}catch(b){let w=b;n({type:"error",message:w.message,errors:w?.installationErrors})}r(!1)};return(0,Qt.jsxs)("div",{className:"font-library__tabpanel-layout",children:[(0,Qt.jsx)(Ot.DropZone,{onFilesDrop:i}),(0,Qt.jsxs)(Ot.__experimentalVStack,{className:"font-library__local-fonts",justify:"start",children:[o&&(0,Qt.jsxs)(Ot.Notice,{status:o.type,__unstableHTML:!0,onRemove:()=>n(null),children:[o.message,o.errors&&(0,Qt.jsx)("ul",{children:o.errors.map((h,g)=>(0,Qt.jsx)("li",{children:h},g))})]}),t&&(0,Qt.jsx)(Ot.FlexItem,{children:(0,Qt.jsx)("div",{className:"font-library__upload-area",children:(0,Qt.jsx)(Ot.ProgressBar,{})})}),!t&&(0,Qt.jsx)(Ot.FormFileUpload,{accept:eu.map(h=>`.${h}`).join(","),multiple:!0,onChange:s,render:({openFileDialog:h})=>(0,Qt.jsx)(Ot.Button,{__next40pxDefaultSize:!0,className:"font-library__upload-area",onClick:h,children:(0,Vn.__)("Upload font")})}),(0,Qt.jsx)(Ot.__experimentalText,{className:"font-library__upload-area__text",children:(0,Vn.__)("Uploaded fonts appear in your library and can be used in your theme. Supported formats: .ttf, .otf, .woff, and .woff2.")})]})]})}var pa=y2;var Hy=f(Z(),1),{Tabs:WB}=Ve(au.privateApis),GB={id:"installed-fonts",title:(0,ma._x)("Library","Font library")},YB={id:"upload-fonts",title:(0,ma._x)("Upload","noun")};var Uy=f(ge(),1),lu=f(ue(),1),b2=f(Te(),1);var Wy=f(Z(),1);var cu=f(Z(),1);var Gy=f(ge(),1),ha=f(ue(),1);var Yy=f(Z(),1);var fu=f(Z(),1);var wt=f(ge(),1),du=f(ue(),1),T2=f(Te(),1);var qy=f(Dt(),1);var R2=f(Z(),1),{useSettingsForBlockElement:Sj,TypographyPanel:Cj}=Ve(qy.privateApis);var E2=f(Z(),1);var pu=f(Z(),1),Aj={text:{description:(0,wt.__)("Manage the fonts used on the site."),title:(0,wt.__)("Text")},link:{description:(0,wt.__)("Manage the fonts and typography used on the links."),title:(0,wt.__)("Links")},heading:{description:(0,wt.__)("Manage the fonts and typography used on headings."),title:(0,wt.__)("Headings")},caption:{description:(0,wt.__)("Manage the fonts and typography used on captions."),title:(0,wt.__)("Captions")},cite:{description:(0,wt.__)("Manage the fonts and typography used on citations."),title:(0,wt.__)("Citations")},button:{description:(0,wt.__)("Manage the fonts and typography used on buttons."),title:(0,wt.__)("Buttons")},textInput:{description:(0,wt.__)("Manage the fonts and typography used on inputs."),title:(0,wt.__)("Inputs")},select:{description:(0,wt.__)("Manage the fonts and typography used on selects."),title:(0,wt.__)("Selects")}};var ga=f(ge(),1),F2=f(ue(),1),Xy=f(Dt(),1);var Dn=f(ue(),1),Zy=f(ge(),1);var k2=f(Te(),1);var P2=f(ue(),1),O2=f(Z(),1);var mu=f(Z(),1);var hu=f(Z(),1),{useSettingsForBlockElement:Zj,ColorPanel:Xj}=Ve(Xy.privateApis),Kj=[{name:"cite",label:(0,ga.__)("Citations")},{name:"textInput",label:(0,ga.__)("Inputs")},{name:"select",label:(0,ga.__)("Selects")}];var H2=f(ge(),1);var L2=f(yo(),1),gu=f(ue(),1),N2=f(ge(),1);var va=f(ue(),1);var ya=f(ue(),1);var Ky=f(Z(),1);function Jy(){let{paletteColors:e}=Pn();return e.slice(0,4).map(({slug:t,color:r},o)=>(0,Ky.jsx)("div",{style:{flexGrow:1,height:"100%",background:r}},`${t}-${o}`))}var Ei=f(Z(),1),A2={start:{scale:1,opacity:1},hover:{scale:0,opacity:0}},I2=({label:e,isFocused:t,withHoverView:r})=>(0,Ei.jsx)(Fn,{label:e,isFocused:t,withHoverView:r,children:({key:o})=>(0,Ei.jsx)(ya.__unstableMotion.div,{variants:A2,style:{height:"100%",overflow:"hidden"},children:(0,Ei.jsx)(ya.__experimentalHStack,{spacing:0,justify:"center",style:{height:"100%",overflow:"hidden"},children:(0,Ei.jsx)(Jy,{})})},o)}),Qy=I2;var $o=f(Z(),1),$y=["color"];function ba({title:e,gap:t=2}){let r=Hs($y);return r?.length<=1?null:(0,$o.jsxs)(va.__experimentalVStack,{spacing:3,children:[e&&(0,$o.jsx)(Er,{level:3,children:e}),(0,$o.jsx)(va.__experimentalGrid,{gap:t,children:r.map((o,n)=>(0,$o.jsx)(An,{variation:o,isPill:!0,properties:$y,showTooltip:!0,children:()=>(0,$o.jsx)(Qy,{})},n))})]})}var ev=f(Z(),1);var M2=f(yo(),1),tv=f(ue(),1),V2=f(ge(),1);var rv=f(Z(),1);var D2=f(yo(),1),B2=f(Te(),1),j2=f(ue(),1);var z2=f(ge(),1);var ov=f(Z(),1);var yu=f(Z(),1);var W2=f(ge(),1),iv=f(Dt(),1),G2=f(ue(),1);var nv=f(Dt(),1);var U2=f(Z(),1);var{BackgroundPanel:E9}=Ve(nv.privateApis);var vu=f(Z(),1),{useHasBackgroundPanel:I9}=Ve(iv.privateApis);var av=f(ge(),1);var Ti=f(ue(),1),X2=f(ge(),1);var K2=f(Te(),1);var Y2=f(ue(),1),q2=f(ge(),1),Z2=f(Z(),1);var sv=f(Z(),1),{Menu:z9}=Ve(Ti.privateApis);var wu=f(Z(),1);var yr=f(ue(),1),uv=f(ge(),1);var wa=f(Te(),1);var Pi=f(ue(),1);var lv=f(Z(),1),{Menu:tz}=Ve(Pi.privateApis);var $2=f(ue(),1),eE=f(ge(),1),tE=f(Z(),1);var xu=f(ue(),1),rE=f(ge(),1),oE=f(Te(),1);var cv=f(Z(),1);var Su=f(Z(),1);var aE=f(Z(),1);var uE=f(ge(),1),dv=f(Dt(),1);var fv=f(Dt(),1),lE=f(Te(),1);var cE=f(Z(),1),{useSettingsForBlockElement:Ez,DimensionsPanel:Tz}=Ve(fv.privateApis);var Cu=f(Z(),1),{useHasDimensionsPanel:Lz,useSettingsForBlockElement:Nz}=Ve(dv.privateApis);var vv=f(ue(),1),mE=f(ge(),1);var dE=f(ge(),1),pE=f(ue(),1);var pv=f(sr(),1),mv=f(Kt(),1),Sa=f(Te(),1),hv=f(ue(),1),gv=f(ge(),1);var xa=f(Z(),1);function fE({gap:e=2}){let{user:t}=(0,Sa.useContext)(gt),r=t?.styles,n=(0,mv.useSelect)(s=>{let a=s(pv.store).__experimentalGetCurrentThemeGlobalStylesVariations();return Array.isArray(a)?a:void 0},[])?.filter(s=>!yi(s,["color"])&&!yi(s,["typography","spacing"])),i=(0,Sa.useMemo)(()=>[...[{title:(0,gv.__)("Default"),settings:{},styles:{}},...n??[]].map(a=>{let u=a?.styles?.blocks?{...a.styles.blocks}:{};r?.blocks&&Object.keys(r.blocks).forEach(d=>{if(r.blocks?.[d]?.css){let h=u[d]||{},g={css:`${u[d]?.css||""} ${r.blocks?.[d]?.css?.trim()||""}`};u[d]={...h,...g}}});let l=r?.css||a.styles?.css?{css:`${a.styles?.css||""} ${r?.css||""}`}:{},c=Object.keys(u).length>0?{blocks:u}:{},m={...a.styles,...l,...c};return{...a,settings:a.settings??{},styles:m}})],[n,r?.blocks,r?.css]);return!n||n.length<1?null:(0,xa.jsx)(hv.__experimentalGrid,{columns:2,className:"global-styles-ui-style-variations-container",gap:e,children:i.map((s,a)=>(0,xa.jsx)(An,{variation:s,children:u=>(0,xa.jsx)(Wc,{label:s?.title,withHoverView:!0,isFocused:u,variation:s})},a))})}var _u=fE;var yv=f(Z(),1);var Ru=f(Z(),1);var hE=f(ge(),1),gE=f(ue(),1),bv=f(Dt(),1);var Eu=f(Z(),1),{AdvancedPanel:$z}=Ve(bv.privateApis);var Tv=f(ge(),1),Pu=f(ue(),1),Ou=f(Te(),1);var yE=f(Kt(),1),vE=f(sr(),1),wv=f(Te(),1);var Cv=f(ge(),1),Ca=f(ue(),1),_a=f(Sv(),1),bE=f(sr(),1),wE=f(Kt(),1);var _v=f(Qc(),1);var Rv=f(Z(),1),{Badge:i7}=Ve(Ca.privateApis),s7=3600*1e3*24;var Tu=f(ue(),1),Oi=f(ge(),1);var Ev=f(Z(),1);var ku=f(Z(),1);var Pv=f(ge(),1),Ov=f(ue(),1);var kv=f(Z(),1);var Av=f(ge(),1),ki=f(ue(),1),Iv=f(Te(),1);var SE=f(Dt(),1),CE=f(ge(),1);var _E=f(Z(),1);var io=f(ue(),1),Fv=f(Z(),1);var Fu=f(Z(),1);var Iu=f(Z(),1);var Lu=f(Z(),1);function Bn(e){return function({value:r,baseValue:o,onChange:n,...i}){return(0,Lu.jsx)(gi,{value:r,baseValue:o,onChange:n,children:(0,Lu.jsx)(e,{...i})})}}var PE=Bn(_u);var OE=Bn(ba);var kE=Bn(Xs);var jn=f(Z(),1);function Nu({value:e,baseValue:t,onChange:r,activeTab:o="installed-fonts"}){let n;switch(o){case"upload-fonts":n=(0,jn.jsx)(pa,{});break;case"installed-fonts":n=(0,jn.jsx)(na,{});break;default:n=(0,jn.jsx)(sa,{slug:o})}return(0,jn.jsx)(gi,{value:e,baseValue:t,onChange:r,children:(0,jn.jsx)($s,{children:n})})}var Mv=f(li()),{unlock:Mu}=(0,Mv.__dangerousOptInToUnstableAPIsOnlyForCoreModules)("I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.","@wordpress/font-list-route");if(typeof document<"u"&&!document.head.querySelector("style[data-wp-hash='8316bac515']")){let e=document.createElement("style");e.setAttribute("data-wp-hash","8316bac515"),e.appendChild(document.createTextNode('@media (min-width:782px){.font-library-modal.font-library-modal{width:65vw}}.font-library-modal .components-modal__header{border-bottom:none}.font-library-modal .components-modal__content{margin-bottom:90px;padding:0}.font-library-modal .font-library__subtitle{font-size:11px;font-weight:var(--wpds-typography-font-weight-emphasis,600);text-transform:uppercase}.font-library-modal__tab-panel{height:calc(100% - 50px)}.font-library__tabpanel-layout{display:flex;flex-direction:column;height:100%}.font-library__tabpanel-layout>div{flex-grow:1}.font-library__tabpanel-layout .font-library__loading{align-items:center;box-sizing:border-box;display:flex;height:100%;justify-content:center;left:0;padding-top:124px;position:absolute;top:0;width:100%}.font-library__footer,.font-library__tabpanel-layout .components-navigator-screen{padding:24px;width:100%}.font-library__footer{background-color:#fff;border-top:1px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);bottom:0;box-sizing:border-box;flex-grow:0!important;flex-shrink:0;height:90px;position:absolute}.font-library__page-selection{font-size:11px;font-weight:var(--wpds-typography-font-weight-emphasis,600);text-transform:uppercase}@media (min-width:600px){.font-library__page-selection .components-select-control__input{font-size:11px!important;font-weight:var(--wpds-typography-font-weight-emphasis,600)}}.font-library__search{width:240px}.font-library__fonts-title{font-size:11px;font-weight:var(--wpds-typography-font-weight-emphasis,600);margin-bottom:0;margin-top:0;text-transform:uppercase}.font-library__fonts-list{list-style:none;margin-bottom:0;margin-top:0;padding:0}.font-library__fonts-list-item{margin-bottom:0}.font-library__font-demo{position:relative}.font-library__font-card{border:1px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);box-sizing:border-box;height:auto!important;margin-top:-1px;padding:16px;width:100%}.font-library__font-card:hover{background-color:#f0f0f0}.font-library__font-card:focus{position:relative}.font-library__font-card .font-library__font-card__name{font-weight:700}.font-library__font-card .font-library__font-card__count{color:#757575}.font-library__font-card .font-library__font-variant_demo-image{display:block;height:24px;width:auto}@media not (prefers-reduced-motion){.font-library__font-card .font-library__font-variant_demo-image{transition:opacity var(--wpds-motion-duration-lg,.3s) var(--wpds-motion-easing-subtle,cubic-bezier(.15,0,.15,1))}}.font-library__font-card .font-library__font-variant_demo-image.is-loading{left:0;opacity:0;position:absolute;top:0}.font-library__font-card .font-library__font-variant-demo-skeleton{border-radius:var(--wpds-border-radius-sm,2px);height:24px}.font-library__font-card .font-library__font-variant_demo-text{flex-shrink:0;white-space:nowrap}@media not (prefers-reduced-motion){.font-library__font-card .font-library__font-variant_demo-text{transition:opacity .3s ease-in-out}}.font-library-modal__tablist-container{background:#fff;border-bottom:1px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);position:sticky;top:0;z-index:1}.font-library__upload-area{align-items:center;display:flex;height:256px!important;justify-content:center;width:100%}button.font-library__upload-area{background-color:#f0f0f0}.font-library__local-fonts{margin:24px auto;width:80%}.font-library__local-fonts .font-library__upload-area__text{color:#757575}.font-library__google-fonts-confirm{align-items:center;display:flex;justify-content:center;margin-top:64px}.font-library__google-fonts-confirm p{line-height:1.4}.font-library__google-fonts-confirm h2{font-size:1.2rem;font-weight:400}.font-library__google-fonts-confirm .components-card{padding:16px;width:400px}.font-library__google-fonts-confirm .components-button{justify-content:center;width:100%}.font-library__select-all{padding:16px 16px 16px 17px}.font-library__select-all .components-checkbox-control__label{padding-left:16px}.global-styles-ui-pagination .components-button.is-tertiary{height:32px;justify-content:center;width:32px}.global-styles-ui-screen-revisions__revisions-list{flex-grow:1;list-style:none;margin:0 16px 16px}.global-styles-ui-screen-revisions__revisions-list li{margin-bottom:0}.global-styles-ui-screen-revisions__revision-item{cursor:var(--wpds-cursor-control,pointer);display:flex;flex-direction:column;position:relative}.global-styles-ui-screen-revisions__revision-item[role=option]:active,.global-styles-ui-screen-revisions__revision-item[role=option]:focus{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid transparent}.global-styles-ui-screen-revisions__revision-item:hover{background:rgba(var(--wp-admin-theme-color--rgb),.04)}.global-styles-ui-screen-revisions__revision-item:hover .global-styles-ui-screen-revisions__date{color:var(--wp-admin-theme-color)}.global-styles-ui-screen-revisions__revision-item:after,.global-styles-ui-screen-revisions__revision-item:before{content:"\\a";display:block;position:absolute}.global-styles-ui-screen-revisions__revision-item:before{background:#ddd;border:4px solid transparent;border-radius:50%;height:8px;left:17px;top:18px;transform:translate(-50%,-50%);width:8px;z-index:1}.global-styles-ui-screen-revisions__revision-item[aria-selected=true]{background:rgba(var(--wp-admin-theme-color--rgb),.04);border-radius:2px;color:var(--wp-admin-theme-color);outline:3px solid transparent;outline-offset:-2px}.global-styles-ui-screen-revisions__revision-item[aria-selected=true] .global-styles-ui-screen-revisions__date{color:var(--wp-admin-theme-color)}.global-styles-ui-screen-revisions__revision-item[aria-selected=true]:before{background:var(--wp-admin-theme-color)}.global-styles-ui-screen-revisions__revision-item[aria-selected=true] .global-styles-ui-screen-revisions__changes>li,.global-styles-ui-screen-revisions__revision-item[aria-selected=true] .global-styles-ui-screen-revisions__meta{color:#1e1e1e}.global-styles-ui-screen-revisions__revision-item:after{border:.5px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);height:100%;left:16px;top:0;width:0}.global-styles-ui-screen-revisions__revision-item:first-child:after{top:18px}.global-styles-ui-screen-revisions__revision-item:last-child:after{height:18px}.global-styles-ui-screen-revisions__revision-item-wrapper{display:block;padding:12px 12px 4px 40px}.global-styles-ui-screen-revisions__active-badge,.global-styles-ui-screen-revisions__apply-button.is-primary{align-self:flex-start;margin:0 12px 12px 40px}.global-styles-ui-screen-revisions__changes,.global-styles-ui-screen-revisions__meta{color:#757575;font-size:12px}.global-styles-ui-screen-revisions__description{align-items:flex-start;display:flex;flex-direction:column;gap:8px}.global-styles-ui-screen-revisions__description .global-styles-ui-screen-revisions__date{font-size:12px;font-weight:var(--wpds-typography-font-weight-emphasis,600);text-transform:uppercase}.global-styles-ui-screen-revisions__meta{align-items:flex-start;display:flex;justify-content:start;margin-bottom:4px;text-align:left;width:100%}.global-styles-ui-screen-revisions__meta img{border-radius:100%;height:16px;margin-right:8px;width:16px}.global-styles-ui-screen-revisions__loading{margin:24px auto!important}.global-styles-ui-screen-revisions__changes{line-height:1.4;list-style:disc;margin-left:12px;text-align:left}.global-styles-ui-screen-revisions__changes li{margin-bottom:4px}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination{gap:2px;justify-content:space-between}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .edit-site-pagination__total{height:1px;left:-1000px;margin:-1px;overflow:hidden;position:absolute}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-text{font-size:12px;will-change:opacity}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-button.is-tertiary{color:#1e1e1e}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-button.is-tertiary:disabled,.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-button.is-tertiary[aria-disabled=true]{color:#949494}.global-styles-ui-screen-revisions__footer{background:#fff;border-top:1px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);bottom:0;box-sizing:border-box;height:56px;min-width:100%;padding:12px;position:sticky;z-index:1}.global-styles-ui-variations_item{box-sizing:border-box;cursor:var(--wpds-cursor-control,pointer)}.global-styles-ui-variations_item .global-styles-ui-variations_item-preview{border-radius:2px;outline:1px solid rgba(0,0,0,.1);outline-offset:-1px;overflow:hidden;position:relative}@media not (prefers-reduced-motion){.global-styles-ui-variations_item .global-styles-ui-variations_item-preview{transition:outline .1s linear}}.global-styles-ui-variations_item .global-styles-ui-variations_item-preview.is-pill{height:32px}.global-styles-ui-variations_item .global-styles-ui-variations_item-preview.is-pill .block-editor-iframe__scale-container{overflow:hidden}.global-styles-ui-variations_item:not(.is-active):hover .global-styles-ui-variations_item-preview{outline-color:rgba(0,0,0,.3)}.global-styles-ui-variations_item.is-active .global-styles-ui-variations_item-preview,.global-styles-ui-variations_item:focus-visible .global-styles-ui-variations_item-preview{outline-color:#1e1e1e;outline-offset:1px;outline-width:var(--wp-admin-border-width-focus)}.global-styles-ui-variations_item:focus-visible .global-styles-ui-variations_item-preview{outline-color:var(--wp-admin-theme-color)}.global-styles-ui-preview__wrapper{display:block;max-width:100%;width:100%}.global-styles-ui-preview__wrapper.is-hoverable{cursor:var(--wpds-cursor-control,pointer)}.global-styles-ui-typography-preview{align-items:center;background:#f0f0f0;border-radius:2px;display:flex;justify-content:center;margin-bottom:20px;min-height:100px;overflow:hidden}.global-styles-ui-font-size__item{line-break:anywhere;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.global-styles-ui-font-size__item-value{color:#757575}.global-styles-ui-screen-typography__indicator{align-items:center;border-radius:2px;display:flex!important;font-size:14px;height:24px;justify-content:center;width:24px}.global-styles-ui-block-types-filter{margin-bottom:12px;padding:0 16px}.global-styles-ui-block-types-search{flex-grow:1}.global-styles-ui-block-types-item-list .global-styles-ui-block-types-item__icon{min-width:24px}.global-styles-ui-block-types-item-list__no-results{padding-top:16px}.global-styles-ui-block-types-item__indicator{background:var(--wp-admin-theme-color);border-radius:50%;flex:none;height:6px;margin-left:auto;width:6px}.global-styles-ui-screen-typography__font-variants-count{color:#757575}.global-styles-ui-font-families__manage-fonts{justify-content:center}.global-styles-ui-screen .color-block-support-panel{border-top:none;padding-left:0;padding-right:0;padding-top:0;row-gap:12px}.global-styles-ui-header{line-height:1.9!important;margin-bottom:0!important}.global-styles-ui-subtitle{font-size:11px!important;font-weight:var(--wpds-typography-font-weight-emphasis,600)!important;margin-bottom:0!important;text-transform:uppercase}.global-styles-ui-section-title{color:#2f2f2f;font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:1.2;margin:0;padding:16px 16px 0}.global-styles-ui-icon-with-current-color{fill:currentColor}.global-styles-ui__color-indicator-wrapper{flex-shrink:0;height:24px}.global-styles-ui__shadows-panel__options-container,.global-styles-ui__typography-panel__options-container{height:24px}.global-styles-ui__block-preview-panel{border:1px solid #ddd;border-radius:2px;overflow:hidden;position:relative;width:100%}.global-styles-ui__shadow-preview-panel{background-image:repeating-linear-gradient(45deg,#e0e0e0 25%,transparent 0,transparent 75%,#e0e0e0 0,#e0e0e0),repeating-linear-gradient(45deg,#e0e0e0 25%,transparent 0,transparent 75%,#e0e0e0 0,#e0e0e0);background-position:0 0,8px 8px;background-size:16px 16px;border:1px solid #ddd;border-radius:2px;height:144px;overflow:auto}.global-styles-ui__shadow-preview-panel .global-styles-ui__shadow-preview-block{background-color:#fff;border:1px solid #ddd;border-radius:2px;height:60px;width:60%}.global-styles-ui__shadow-editor__dropdown-content{width:280px}.global-styles-ui__shadow-editor-panel{margin-bottom:4px}.global-styles-ui__shadow-editor__dropdown{position:relative;width:100%}.global-styles-ui__shadow-editor__dropdown-toggle{border-radius:inherit;height:auto;padding-bottom:8px;padding-top:8px;text-align:left;width:100%}.global-styles-ui__shadow-editor__dropdown-toggle.is-open{background:#f0f0f0;color:var(--wp-admin-theme-color)}.global-styles-ui__shadow-editor__remove-button{opacity:0;position:absolute;right:8px;top:8px}.global-styles-ui__shadow-editor__dropdown-toggle:hover+.global-styles-ui__shadow-editor__remove-button,.global-styles-ui__shadow-editor__remove-button:focus,.global-styles-ui__shadow-editor__remove-button:hover{opacity:1}@media (hover:none){.global-styles-ui__shadow-editor__remove-button{opacity:1}}.global-styles-ui-screen-css{display:flex;flex:1 1 auto;flex-direction:column;margin:16px}.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel{flex:1 1 auto}.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel__custom-css-input,.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel__custom-css-input .components-base-control__field{display:flex;flex:1 1 auto;flex-direction:column}.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel__custom-css-input textarea{flex:1 1 auto}.global-styles-ui-screen-css-help-link{display:inline-block;margin-top:8px}.global-styles-ui-screen-variations{border-top:1px solid #ddd;margin-top:16px}.global-styles-ui-screen-variations>*{margin:24px 16px}.global-styles-ui-sidebar__navigator-provider{height:100%}.global-styles-ui-sidebar__navigator-screen{display:flex;flex-direction:column;height:100%}.global-styles-ui-color-palette__tablist-container{border-bottom:1px solid #ddd}.global-styles-ui-color-palette__tablist{margin-bottom:-1px}.global-styles-ui-sidebar__navigator-screen .single-column{grid-column:span 1}.global-styles-ui-screen-root.global-styles-ui-screen-root,.global-styles-ui-screen-style-variations.global-styles-ui-screen-style-variations{background:unset;color:inherit}.global-styles-ui-sidebar__panel .block-editor-block-icon svg{fill:currentColor}.global-styles-ui-screen-root__active-style-tile.global-styles-ui-screen-root__active-style-tile,.global-styles-ui-screen-root__active-style-tile.global-styles-ui-screen-root__active-style-tile .global-styles-ui-screen-root__active-style-tile-preview{border-radius:2px}.global-styles-ui-screen-root__active-style-tile-preview{clip-path:border-box}.global-styles-ui-color-palette-panel,.global-styles-ui-duotone-palette-panel,.global-styles-ui-gradient-palette-panel{padding:16px}.font-library-page__tablist{border-bottom:1px solid #f0f0f0;padding:0 24px}.font-library-page__tab-panel{flex-grow:1;max-height:calc(100% - 110px);overflow:auto}.font-library-page:has(.font-library__footer) .font-library-page__tab-panel{max-height:calc(100% - 198px)}')),document.head.appendChild(e)}var Gr=f(Z()),{Tabs:Ra}=Mu(Vv.privateApis),{useGlobalStyles:FE}=Mu(Dv.privateApis);function AE(){let{records:e=[]}=(0,Ea.useEntityRecords)("root","fontCollection",{_fields:"slug,name,description"}),[t,r]=(0,jv.useState)("installed-fonts"),{base:o,user:n,setUser:i,isReady:s}=FE(),a=(0,Bv.useSelect)(l=>l(Ea.store).canUser("create",{kind:"postType",name:"wp_font_family"}),[]);if(!s)return null;let u=[{id:"installed-fonts",title:(0,zn._x)("Library","Font library")}];return a&&(u.push({id:"upload-fonts",title:(0,zn._x)("Upload","noun")}),u.push(...(e||[]).map(({slug:l,name:c})=>({id:l,title:e&&e.length===1&&l==="google-fonts"?(0,zn.__)("Install Fonts"):c})))),(0,Gr.jsx)(gc,{title:(0,zn.__)("Fonts"),className:"font-library-page",children:(0,Gr.jsxs)(Ra,{selectedTabId:t,onSelect:l=>r(l),children:[(0,Gr.jsx)("div",{className:"font-library-page__tablist",children:(0,Gr.jsx)(Ra.TabList,{children:u.map(({id:l,title:c})=>(0,Gr.jsx)(Ra.Tab,{tabId:l,children:c},l))})}),u.map(({id:l})=>(0,Gr.jsx)(Ra.TabPanel,{tabId:l,focusable:!1,className:"font-library-page__tab-panel",children:(0,Gr.jsx)(Nu,{value:n,baseValue:o,onChange:i,activeTab:l})},l))]})})}function IE(){return(0,Gr.jsx)(AE,{})}var LE=IE;export{LE as stage}; +}`,globalThis.document.head.appendChild(n),n}var WS=[0,1,0,0],GS=[79,84,84,79],YS=[119,79,70,70],qS=[119,79,70,50];function ua(e,t){if(e.length===t.length){for(let r=0;r(globalThis.document&&!this.options.skipStyleSheet&&await US(this.name,e,this.options),this.loadFont(e)))()}async loadFont(e,t){fetch(e).then(r=>XS(r)&&r.arrayBuffer()).then(r=>this.fromDataBuffer(r,t||e)).catch(r=>{let o=new ca("error",r,`Failed to load font at ${t||e}`);this.dispatch(o),this.onerror&&this.onerror(o)})}async fromDataBuffer(e,t){this.fontData=new DataView(e);let r=ZS(this.fontData);if(!r)throw new Error(`${t} is either an unsupported font format, or not a font at all.`);await this.parseBasicData(r);let o=new ca("load",{font:this});this.dispatch(o),this.onload&&this.onload(o)}async parseBasicData(e){return zS().then(t=>(e==="SFNT"&&(this.opentype=new FS(this,this.fontData,t)),e==="WOFF"&&(this.opentype=new IS(this,this.fontData,t)),e==="WOFF2"&&(this.opentype=new MS(this,this.fontData,t)),this.opentype))}getGlyphId(e){return this.opentype.tables.cmap.getGlyphId(e)}reverse(e){return this.opentype.tables.cmap.reverse(e)}supports(e){return this.getGlyphId(e)!==0}supportsVariation(e){return this.opentype.tables.cmap.supportsVariation(e)!==!1}measureText(e,t=16){if(this.__unloaded)throw new Error("Cannot measure text: font was unloaded. Please reload before calling measureText()");let r=document.createElement("div");r.textContent=e,r.style.fontFamily=this.name,r.style.fontSize=`${t}px`,r.style.color="transparent",r.style.background="transparent",r.style.top="0",r.style.left="0",r.style.position="absolute",document.body.appendChild(r);let o=r.getBoundingClientRect();document.body.removeChild(r);let n=this.opentype.tables["OS/2"];return o.fontSize=t,o.ascender=n.sTypoAscender,o.descender=n.sTypoDescender,o}unload(){if(this.styleElement.parentNode){this.styleElement.parentNode.removeElement(this.styleElement);let e=new ca("unload",{font:this});this.dispatch(e),this.onunload&&this.onunload(e)}this._unloaded=!0}load(){if(this.__unloaded){delete this.__unloaded,document.head.appendChild(this.styleElement);let e=new ca("load",{font:this});this.dispatch(e),this.onload&&this.onload(e)}}};globalThis.Font=da;var oo=class extends lt{constructor(e,t,r){super(e),this.plaformID=t,this.encodingID=r}},KS=class extends oo{constructor(e,t,r){super(e,t,r),this.format=0,this.length=e.uint16,this.language=e.uint16,this.glyphIdArray=[...new Array(256)].map(o=>e.uint8)}supports(e){return e.charCodeAt&&(e=-1,console.warn("supports(character) not implemented for cmap subtable format 0. only supports(id) is implemented.")),0<=e&&e<=255}reverse(e){return console.warn("reverse not implemented for cmap subtable format 0"),{}}getSupportedCharCodes(){return[{start:1,end:256}]}},JS=class extends oo{constructor(e,t,r){super(e,t,r),this.format=2,this.length=e.uint16,this.language=e.uint16,this.subHeaderKeys=[...new Array(256)].map(s=>e.uint16);let o=Math.max(...this.subHeaderKeys),n=e.currentPosition;ae(this,"subHeaders",()=>(e.currentPosition=n,[...new Array(o)].map(s=>new QS(e))));let i=n+o*8;ae(this,"glyphIndexArray",()=>(e.currentPosition=i,[...new Array(o)].map(s=>e.uint16)))}supports(e){e.charCodeAt&&(e=-1,console.warn("supports(character) not implemented for cmap subtable format 2. only supports(id) is implemented."));let t=e&&255,r=e&&65280,o=this.subHeaders[r],n=this.subHeaders[o],i=n.firstCode,s=i+n.entryCount;return i<=t&&t<=s}reverse(e){return console.warn("reverse not implemented for cmap subtable format 2"),{}}getSupportedCharCodes(e=!1){return e?this.subHeaders.map(t=>({firstCode:t.firstCode,lastCode:t.lastCode})):this.subHeaders.map(t=>({start:t.firstCode,end:t.lastCode}))}},QS=class{constructor(e){this.firstCode=e.uint16,this.entryCount=e.uint16,this.lastCode=this.first+this.entryCount,this.idDelta=e.int16,this.idRangeOffset=e.uint16}},$S=class extends oo{constructor(e,t,r){super(e,t,r),this.format=4,this.length=e.uint16,this.language=e.uint16,this.segCountX2=e.uint16,this.segCount=this.segCountX2/2,this.searchRange=e.uint16,this.entrySelector=e.uint16,this.rangeShift=e.uint16;let o=e.currentPosition;ae(this,"endCode",()=>e.readBytes(this.segCount,o,16));let n=o+2+this.segCountX2;ae(this,"startCode",()=>e.readBytes(this.segCount,n,16));let i=n+this.segCountX2;ae(this,"idDelta",()=>e.readBytes(this.segCount,i,16,!0));let s=i+this.segCountX2;ae(this,"idRangeOffset",()=>e.readBytes(this.segCount,s,16));let a=s+this.segCountX2,u=this.length-(a-this.tableStart);ae(this,"glyphIdArray",()=>e.readBytes(u,a,16)),ae(this,"segments",()=>this.buildSegments(s,a,e))}buildSegments(e,t,r){let o=(n,i)=>{let s=this.startCode[i],a=this.endCode[i],u=this.idDelta[i],l=this.idRangeOffset[i],c=e+2*i,m=[];if(l===0)for(let d=s+u,h=a+u;d<=h;d++)m.push(d);else for(let d=0,h=a-s;d<=h;d++)r.currentPosition=c+l+d*2,m.push(r.uint16);return{startCode:s,endCode:a,idDelta:u,idRangeOffset:l,glyphIDs:m}};return[...new Array(this.segCount)].map(o)}reverse(e){let t=this.segments.find(o=>o.glyphIDs.includes(e));if(!t)return{};let r=t.startCode+t.glyphIDs.indexOf(e);return{code:r,unicode:String.fromCodePoint(r)}}getGlyphId(e){if(e.charCodeAt&&(e=e.charCodeAt(0)),55296<=e&&e<=57343||(e&65534)===65534||(e&65535)===65535)return 0;let t=this.segments.find(r=>r.startCode<=e&&e<=r.endCode);return t?t.glyphIDs[e-t.startCode]:0}supports(e){return this.getGlyphId(e)!==0}getSupportedCharCodes(e=!1){return e?this.segments:this.segments.map(t=>({start:t.startCode,end:t.endCode}))}},e_=class extends oo{constructor(e,t,r){super(e,t,r),this.format=6,this.length=e.uint16,this.language=e.uint16,this.firstCode=e.uint16,this.entryCount=e.uint16,this.lastCode=this.firstCode+this.entryCount-1,ae(this,"glyphIdArray",()=>[...new Array(this.entryCount)].map(n=>e.uint16))}supports(e){if(e.charCodeAt&&(e=-1,console.warn("supports(character) not implemented for cmap subtable format 6. only supports(id) is implemented.")),ethis.firstCode+this.entryCount)return{};let t=e-this.firstCode;return{code:t,unicode:String.fromCodePoint(t)}}reverse(e){let t=this.glyphIdArray.indexOf(e);if(t>-1)return this.firstCode+t}getSupportedCharCodes(e=!1){return e?[{firstCode:this.firstCode,lastCode:this.lastCode}]:[{start:this.firstCode,end:this.lastCode}]}},t_=class extends oo{constructor(e,t,r){super(e,t,r),this.format=8,e.uint16,this.length=e.uint32,this.language=e.uint32,this.is32=[...new Array(8192)].map(n=>e.uint8),this.numGroups=e.uint32,ae(this,"groups",()=>[...new Array(this.numGroups)].map(n=>new r_(e)))}supports(e){return e.charCodeAt&&(e=-1,console.warn("supports(character) not implemented for cmap subtable format 8. only supports(id) is implemented.")),this.groups.findIndex(t=>t.startcharCode<=e&&e<=t.endcharCode)!==-1}reverse(e){return console.warn("reverse not implemented for cmap subtable format 8"),{}}getSupportedCharCodes(e=!1){return e?this.groups:this.groups.map(t=>({start:t.startcharCode,end:t.endcharCode}))}},r_=class{constructor(e){this.startcharCode=e.uint32,this.endcharCode=e.uint32,this.startGlyphID=e.uint32}},o_=class extends oo{constructor(e,t,r){super(e,t,r),this.format=10,e.uint16,this.length=e.uint32,this.language=e.uint32,this.startCharCode=e.uint32,this.numChars=e.uint32,this.endCharCode=this.startCharCode+this.numChars,ae(this,"glyphs",()=>[...new Array(this.numChars)].map(n=>e.uint16))}supports(e){return e.charCodeAt&&(e=-1,console.warn("supports(character) not implemented for cmap subtable format 10. only supports(id) is implemented.")),ethis.startCharCode+this.numChars?!1:e-this.startCharCode}reverse(e){return console.warn("reverse not implemented for cmap subtable format 10"),{}}getSupportedCharCodes(e=!1){return e?[{startCharCode:this.startCharCode,endCharCode:this.endCharCode}]:[{start:this.startCharCode,end:this.endCharCode}]}},n_=class extends oo{constructor(e,t,r){super(e,t,r),this.format=12,e.uint16,this.length=e.uint32,this.language=e.uint32,this.numGroups=e.uint32,ae(this,"groups",()=>[...new Array(this.numGroups)].map(n=>new i_(e)))}supports(e){return e.charCodeAt&&(e=e.charCodeAt(0)),55296<=e&&e<=57343||(e&65534)===65534||(e&65535)===65535?0:this.groups.findIndex(t=>t.startCharCode<=e&&e<=t.endCharCode)!==-1}reverse(e){for(let t of this.groups){let r=t.startGlyphID;if(r>e)continue;if(r===e)return t.startCharCode;if(r+(t.endCharCode-t.startCharCode)({start:t.startCharCode,end:t.endCharCode}))}},i_=class{constructor(e){this.startCharCode=e.uint32,this.endCharCode=e.uint32,this.startGlyphID=e.uint32}},s_=class extends oo{constructor(e,t,r){super(e,t,r),this.format=13,e.uint16,this.length=e.uint32,this.language=e.uint32,this.numGroups=e.uint32;let o=[...new Array(this.numGroups)].map(n=>new a_(e));ae(this,"groups",o)}supports(e){return e.charCodeAt&&(e=e.charCodeAt(0)),this.groups.findIndex(t=>t.startCharCode<=e&&e<=t.endCharCode)!==-1}reverse(e){return console.warn("reverse not implemented for cmap subtable format 13"),{}}getSupportedCharCodes(e=!1){return e?this.groups:this.groups.map(t=>({start:t.startCharCode,end:t.endCharCode}))}},a_=class{constructor(e){this.startCharCode=e.uint32,this.endCharCode=e.uint32,this.glyphID=e.uint32}},l_=class extends oo{constructor(e,t,r){super(e,t,r),this.subTableStart=e.currentPosition,this.format=14,this.length=e.uint32,this.numVarSelectorRecords=e.uint32,ae(this,"varSelectors",()=>[...new Array(this.numVarSelectorRecords)].map(o=>new c_(e)))}supports(){return console.warn("supports not implemented for cmap subtable format 14"),0}getSupportedCharCodes(){return console.warn("getSupportedCharCodes not implemented for cmap subtable format 14"),[]}reverse(e){return console.warn("reverse not implemented for cmap subtable format 14"),{}}supportsVariation(e){let t=this.varSelector.find(r=>r.varSelector===e);return t||!1}getSupportedVariations(){return this.varSelectors.map(e=>e.varSelector)}},c_=class{constructor(e){this.varSelector=e.uint24,this.defaultUVSOffset=e.Offset32,this.nonDefaultUVSOffset=e.Offset32}};function u_(e,t,r){let o=e.uint16;return o===0?new KS(e,t,r):o===2?new JS(e,t,r):o===4?new $S(e,t,r):o===6?new e_(e,t,r):o===8?new t_(e,t,r):o===10?new o_(e,t,r):o===12?new n_(e,t,r):o===13?new s_(e,t,r):o===14?new l_(e,t,r):{}}var f_=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.numTables=r.uint16,this.encodingRecords=[...new Array(this.numTables)].map(o=>new d_(r,this.tableStart))}getSubTable(e){return this.encodingRecords[e].table}getSupportedEncodings(){return this.encodingRecords.map(e=>({platformID:e.platformID,encodingId:e.encodingID}))}getSupportedCharCodes(e,t){let r=this.encodingRecords.findIndex(n=>n.platformID===e&&n.encodingID===t);return r===-1?!1:this.getSubTable(r).getSupportedCharCodes()}reverse(e){for(let t=0;t{let n=this.getSubTable(o);return n.getGlyphId?(t=n.getGlyphId(e),t!==0):!1}),t}supports(e){return this.encodingRecords.some((t,r)=>{let o=this.getSubTable(r);return o.supports&&o.supports(e)!==!1})}supportsVariation(e){return this.encodingRecords.some((t,r)=>{let o=this.getSubTable(r);return o.supportsVariation&&o.supportsVariation(e)!==!1})}},d_=class{constructor(e,t){let r=this.platformID=e.uint16,o=this.encodingID=e.uint16,n=this.offset=e.Offset32;ae(this,"table",()=>(e.currentPosition=t+n,u_(e,r,o)))}},p_=Object.freeze({__proto__:null,cmap:f_}),m_=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.load({majorVersion:r.uint16,minorVersion:r.uint16,fontRevision:r.fixed,checkSumAdjustment:r.uint32,magicNumber:r.uint32,flags:r.flags(16),unitsPerEm:r.uint16,created:r.longdatetime,modified:r.longdatetime,xMin:r.int16,yMin:r.int16,xMax:r.int16,yMax:r.int16,macStyle:r.flags(16),lowestRecPPEM:r.uint16,fontDirectionHint:r.uint16,indexToLocFormat:r.uint16,glyphDataFormat:r.uint16})}},h_=Object.freeze({__proto__:null,head:m_}),g_=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.majorVersion=r.uint16,this.minorVersion=r.uint16,this.ascender=r.fword,this.descender=r.fword,this.lineGap=r.fword,this.advanceWidthMax=r.ufword,this.minLeftSideBearing=r.fword,this.minRightSideBearing=r.fword,this.xMaxExtent=r.fword,this.caretSlopeRise=r.int16,this.caretSlopeRun=r.int16,this.caretOffset=r.int16,r.int16,r.int16,r.int16,r.int16,this.metricDataFormat=r.int16,this.numberOfHMetrics=r.uint16,r.verifyLength()}},y_=Object.freeze({__proto__:null,hhea:g_}),v_=class extends ke{constructor(e,t,r){let{p:o}=super(e,t),n=r.hhea.numberOfHMetrics,i=r.maxp.numGlyphs,s=o.currentPosition;if(ae(this,"hMetrics",()=>(o.currentPosition=s,[...new Array(n)].map(a=>new b_(o.uint16,o.int16)))),n(o.currentPosition=a,[...new Array(i-n)].map(u=>o.int16)))}}},b_=class{constructor(e,t){this.advanceWidth=e,this.lsb=t}},w_=Object.freeze({__proto__:null,hmtx:v_}),x_=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.legacyFixed,this.numGlyphs=r.uint16,this.version===1&&(this.maxPoints=r.uint16,this.maxContours=r.uint16,this.maxCompositePoints=r.uint16,this.maxCompositeContours=r.uint16,this.maxZones=r.uint16,this.maxTwilightPoints=r.uint16,this.maxStorage=r.uint16,this.maxFunctionDefs=r.uint16,this.maxInstructionDefs=r.uint16,this.maxStackElements=r.uint16,this.maxSizeOfInstructions=r.uint16,this.maxComponentElements=r.uint16,this.maxComponentDepth=r.uint16),r.verifyLength()}},S_=Object.freeze({__proto__:null,maxp:x_}),__=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.format=r.uint16,this.count=r.uint16,this.stringOffset=r.Offset16,this.nameRecords=[...new Array(this.count)].map(o=>new R_(r,this)),this.format===1&&(this.langTagCount=r.uint16,this.langTagRecords=[...new Array(this.langTagCount)].map(o=>new C_(r.uint16,r.Offset16))),this.stringStart=this.tableStart+this.stringOffset}get(e){let t=this.nameRecords.find(r=>r.nameID===e);if(t)return t.string}},C_=class{constructor(e,t){this.length=e,this.offset=t}},R_=class{constructor(e,t){this.platformID=e.uint16,this.encodingID=e.uint16,this.languageID=e.uint16,this.nameID=e.uint16,this.length=e.uint16,this.offset=e.Offset16,ae(this,"string",()=>(e.currentPosition=t.stringStart+this.offset,E_(e,this)))}};function E_(e,t){let{platformID:r,length:o}=t;if(o===0)return"";if(r===0||r===3){let s=[];for(let a=0,u=o/2;ar.uint8),this.ulUnicodeRange1=r.flags(32),this.ulUnicodeRange2=r.flags(32),this.ulUnicodeRange3=r.flags(32),this.ulUnicodeRange4=r.flags(32),this.achVendID=r.tag,this.fsSelection=r.uint16,this.usFirstCharIndex=r.uint16,this.usLastCharIndex=r.uint16,this.sTypoAscender=r.int16,this.sTypoDescender=r.int16,this.sTypoLineGap=r.int16,this.usWinAscent=r.uint16,this.usWinDescent=r.uint16,this.version===0||(this.ulCodePageRange1=r.flags(32),this.ulCodePageRange2=r.flags(32),this.version===1)||(this.sxHeight=r.int16,this.sCapHeight=r.int16,this.usDefaultChar=r.uint16,this.usBreakChar=r.uint16,this.usMaxContext=r.uint16,this.version<=4)||(this.usLowerOpticalPointSize=r.uint16,this.usUpperOpticalPointSize=r.uint16,this.version===5))return r.verifyLength()}},O_=Object.freeze({__proto__:null,OS2:P_}),k_=class extends ke{constructor(e,t){let{p:r}=super(e,t);if(this.version=r.legacyFixed,this.italicAngle=r.fixed,this.underlinePosition=r.fword,this.underlineThickness=r.fword,this.isFixedPitch=r.uint32,this.minMemType42=r.uint32,this.maxMemType42=r.uint32,this.minMemType1=r.uint32,this.maxMemType1=r.uint32,this.version===1||this.version===3)return r.verifyLength();if(this.numGlyphs=r.uint16,this.version===2){this.glyphNameIndex=[...new Array(this.numGlyphs)].map(o=>r.uint16),this.namesOffset=r.currentPosition,this.glyphNameOffsets=[1];for(let o=0;or.int8))}getGlyphName(e){if(this.version!==2)return console.warn(`post table version ${this.version} does not support glyph name lookups`),"";let t=this.glyphNameIndex[e];if(t<258)return vy[t];let r=this.glyphNameOffsets[e],n=this.glyphNameOffsets[e+1]-r-1;return n===0?".notdef.":(this.parser.currentPosition=this.namesOffset+r,this.parser.readBytes(n,this.namesOffset+r,8,!0).map(s=>String.fromCharCode(s)).join(""))}},vy=[".notdef",".null","nonmarkingreturn","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quotesingle","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","grave","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","Adieresis","Aring","Ccedilla","Eacute","Ntilde","Odieresis","Udieresis","aacute","agrave","acircumflex","adieresis","atilde","aring","ccedilla","eacute","egrave","ecircumflex","edieresis","iacute","igrave","icircumflex","idieresis","ntilde","oacute","ograve","ocircumflex","odieresis","otilde","uacute","ugrave","ucircumflex","udieresis","dagger","degree","cent","sterling","section","bullet","paragraph","germandbls","registered","copyright","trademark","acute","dieresis","notequal","AE","Oslash","infinity","plusminus","lessequal","greaterequal","yen","mu","partialdiff","summation","product","pi","integral","ordfeminine","ordmasculine","Omega","ae","oslash","questiondown","exclamdown","logicalnot","radical","florin","approxequal","Delta","guillemotleft","guillemotright","ellipsis","nonbreakingspace","Agrave","Atilde","Otilde","OE","oe","endash","emdash","quotedblleft","quotedblright","quoteleft","quoteright","divide","lozenge","ydieresis","Ydieresis","fraction","currency","guilsinglleft","guilsinglright","fi","fl","daggerdbl","periodcentered","quotesinglbase","quotedblbase","perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave","Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex","apple","Ograve","Uacute","Ucircumflex","Ugrave","dotlessi","circumflex","tilde","macron","breve","dotaccent","ring","cedilla","hungarumlaut","ogonek","caron","Lslash","lslash","Scaron","scaron","Zcaron","zcaron","brokenbar","Eth","eth","Yacute","yacute","Thorn","thorn","minus","multiply","onesuperior","twosuperior","threesuperior","onehalf","onequarter","threequarters","franc","Gbreve","gbreve","Idotaccent","Scedilla","scedilla","Cacute","cacute","Ccaron","ccaron","dcroat"],F_=Object.freeze({__proto__:null,post:k_}),A_=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.majorVersion=r.uint16,this.minorVersion=r.uint16,this.horizAxisOffset=r.Offset16,this.vertAxisOffset=r.Offset16,ae(this,"horizAxis",()=>new eu({offset:e.offset+this.horizAxisOffset},t)),ae(this,"vertAxis",()=>new eu({offset:e.offset+this.vertAxisOffset},t)),this.majorVersion===1&&this.minorVersion===1&&(this.itemVarStoreOffset=r.Offset32,ae(this,"itemVarStore",()=>new eu({offset:e.offset+this.itemVarStoreOffset},t)))}},eu=class extends ke{constructor(e,t){let{p:r}=super(e,t,"AxisTable");this.baseTagListOffset=r.Offset16,this.baseScriptListOffset=r.Offset16,ae(this,"baseTagList",()=>new I_({offset:e.offset+this.baseTagListOffset},t)),ae(this,"baseScriptList",()=>new L_({offset:e.offset+this.baseScriptListOffset},t))}},I_=class extends ke{constructor(e,t){let{p:r}=super(e,t,"BaseTagListTable");this.baseTagCount=r.uint16,this.baselineTags=[...new Array(this.baseTagCount)].map(o=>r.tag)}},L_=class extends ke{constructor(e,t){let{p:r}=super(e,t,"BaseScriptListTable");this.baseScriptCount=r.uint16;let o=r.currentPosition;ae(this,"baseScriptRecords",()=>(r.currentPosition=o,[...new Array(this.baseScriptCount)].map(n=>new N_(this.start,r))))}},N_=class{constructor(e,t){this.baseScriptTag=t.tag,this.baseScriptOffset=t.Offset16,ae(this,"baseScriptTable",()=>(t.currentPosition=e+this.baseScriptOffset,new M_(t)))}},M_=class{constructor(e){this.start=e.currentPosition,this.baseValuesOffset=e.Offset16,this.defaultMinMaxOffset=e.Offset16,this.baseLangSysCount=e.uint16,this.baseLangSysRecords=[...new Array(this.baseLangSysCount)].map(t=>new V_(this.start,e)),ae(this,"baseValues",()=>(e.currentPosition=this.start+this.baseValuesOffset,new D_(e))),ae(this,"defaultMinMax",()=>(e.currentPosition=this.start+this.defaultMinMaxOffset,new Ey(e)))}},V_=class{constructor(e,t){this.baseLangSysTag=t.tag,this.minMaxOffset=t.Offset16,ae(this,"minMax",()=>(t.currentPosition=e+this.minMaxOffset,new Ey(t)))}},D_=class{constructor(e){this.parser=e,this.start=e.currentPosition,this.defaultBaselineIndex=e.uint16,this.baseCoordCount=e.uint16,this.baseCoords=[...new Array(this.baseCoordCount)].map(t=>e.Offset16)}getTable(e){return this.parser.currentPosition=this.start+this.baseCoords[e],new j_(this.parser)}},Ey=class{constructor(e){this.minCoord=e.Offset16,this.maxCoord=e.Offset16,this.featMinMaxCount=e.uint16;let t=e.currentPosition;ae(this,"featMinMaxRecords",()=>(e.currentPosition=t,[...new Array(this.featMinMaxCount)].map(r=>new B_(e))))}},B_=class{constructor(e){this.featureTableTag=e.tag,this.minCoord=e.Offset16,this.maxCoord=e.Offset16}},j_=class{constructor(e){this.baseCoordFormat=e.uint16,this.coordinate=e.int16,this.baseCoordFormat===2&&(this.referenceGlyph=e.uint16,this.baseCoordPoint=e.uint16),this.baseCoordFormat===3&&(this.deviceTable=e.Offset16)}},z_=Object.freeze({__proto__:null,BASE:A_}),by=class{constructor(e){this.classFormat=e.uint16,this.classFormat===1&&(this.startGlyphID=e.uint16,this.glyphCount=e.uint16,this.classValueArray=[...new Array(this.glyphCount)].map(t=>e.uint16)),this.classFormat===2&&(this.classRangeCount=e.uint16,this.classRangeRecords=[...new Array(this.classRangeCount)].map(t=>new H_(e)))}},H_=class{constructor(e){this.startGlyphID=e.uint16,this.endGlyphID=e.uint16,this.class=e.uint16}},_i=class extends lt{constructor(e){super(e),this.coverageFormat=e.uint16,this.coverageFormat===1&&(this.glyphCount=e.uint16,this.glyphArray=[...new Array(this.glyphCount)].map(t=>e.uint16)),this.coverageFormat===2&&(this.rangeCount=e.uint16,this.rangeRecords=[...new Array(this.rangeCount)].map(t=>new U_(e)))}},U_=class{constructor(e){this.startGlyphID=e.uint16,this.endGlyphID=e.uint16,this.startCoverageIndex=e.uint16}},W_=class{constructor(e,t){this.table=e,this.parser=t,this.start=t.currentPosition,this.format=t.uint16,this.variationRegionListOffset=t.Offset32,this.itemVariationDataCount=t.uint16,this.itemVariationDataOffsets=[...new Array(this.itemVariationDataCount)].map(r=>t.Offset32)}},G_=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.majorVersion=r.uint16,this.minorVersion=r.uint16,this.glyphClassDefOffset=r.Offset16,ae(this,"glyphClassDefs",()=>{if(this.glyphClassDefOffset!==0)return r.currentPosition=this.tableStart+this.glyphClassDefOffset,new by(r)}),this.attachListOffset=r.Offset16,ae(this,"attachList",()=>{if(this.attachListOffset!==0)return r.currentPosition=this.tableStart+this.attachListOffset,new Y_(r)}),this.ligCaretListOffset=r.Offset16,ae(this,"ligCaretList",()=>{if(this.ligCaretListOffset!==0)return r.currentPosition=this.tableStart+this.ligCaretListOffset,new Z_(r)}),this.markAttachClassDefOffset=r.Offset16,ae(this,"markAttachClassDef",()=>{if(this.markAttachClassDefOffset!==0)return r.currentPosition=this.tableStart+this.markAttachClassDefOffset,new by(r)}),this.minorVersion>=2&&(this.markGlyphSetsDefOffset=r.Offset16,ae(this,"markGlyphSetsDef",()=>{if(this.markGlyphSetsDefOffset!==0)return r.currentPosition=this.tableStart+this.markGlyphSetsDefOffset,new J_(r)})),this.minorVersion===3&&(this.itemVarStoreOffset=r.Offset32,ae(this,"itemVarStore",()=>{if(this.itemVarStoreOffset!==0)return r.currentPosition=this.tableStart+this.itemVarStoreOffset,new W_(r)}))}},Y_=class extends lt{constructor(e){super(e),this.coverageOffset=e.Offset16,this.glyphCount=e.uint16,this.attachPointOffsets=[...new Array(this.glyphCount)].map(t=>e.Offset16)}getPoint(e){return this.parser.currentPosition=this.start+this.attachPointOffsets[e],new q_(this.parser)}},q_=class{constructor(e){this.pointCount=e.uint16,this.pointIndices=[...new Array(this.pointCount)].map(t=>e.uint16)}},Z_=class extends lt{constructor(e){super(e),this.coverageOffset=e.Offset16,ae(this,"coverage",()=>(e.currentPosition=this.start+this.coverageOffset,new _i(e))),this.ligGlyphCount=e.uint16,this.ligGlyphOffsets=[...new Array(this.ligGlyphCount)].map(t=>e.Offset16)}getLigGlyph(e){return this.parser.currentPosition=this.start+this.ligGlyphOffsets[e],new X_(this.parser)}},X_=class extends lt{constructor(e){super(e),this.caretCount=e.uint16,this.caretValueOffsets=[...new Array(this.caretCount)].map(t=>e.Offset16)}getCaretValue(e){return this.parser.currentPosition=this.start+this.caretValueOffsets[e],new K_(this.parser)}},K_=class{constructor(e){this.caretValueFormat=e.uint16,this.caretValueFormat===1&&(this.coordinate=e.int16),this.caretValueFormat===2&&(this.caretValuePointIndex=e.uint16),this.caretValueFormat===3&&(this.coordinate=e.int16,this.deviceOffset=e.Offset16)}},J_=class extends lt{constructor(e){super(e),this.markGlyphSetTableFormat=e.uint16,this.markGlyphSetCount=e.uint16,this.coverageOffsets=[...new Array(this.markGlyphSetCount)].map(t=>e.Offset32)}getMarkGlyphSet(e){return this.parser.currentPosition=this.start+this.coverageOffsets[e],new _i(this.parser)}},Q_=Object.freeze({__proto__:null,GDEF:G_}),wy=class extends lt{static EMPTY={scriptCount:0,scriptRecords:[]};constructor(e){super(e),this.scriptCount=e.uint16,this.scriptRecords=[...new Array(this.scriptCount)].map(t=>new $_(e))}},$_=class{constructor(e){this.scriptTag=e.tag,this.scriptOffset=e.Offset16}},eC=class extends lt{constructor(e){super(e),this.defaultLangSys=e.Offset16,this.langSysCount=e.uint16,this.langSysRecords=[...new Array(this.langSysCount)].map(t=>new tC(e))}},tC=class{constructor(e){this.langSysTag=e.tag,this.langSysOffset=e.Offset16}},xy=class{constructor(e){this.lookupOrder=e.Offset16,this.requiredFeatureIndex=e.uint16,this.featureIndexCount=e.uint16,this.featureIndices=[...new Array(this.featureIndexCount)].map(t=>e.uint16)}},Sy=class extends lt{static EMPTY={featureCount:0,featureRecords:[]};constructor(e){super(e),this.featureCount=e.uint16,this.featureRecords=[...new Array(this.featureCount)].map(t=>new rC(e))}},rC=class{constructor(e){this.featureTag=e.tag,this.featureOffset=e.Offset16}},oC=class extends lt{constructor(e){super(e),this.featureParams=e.Offset16,this.lookupIndexCount=e.uint16,this.lookupListIndices=[...new Array(this.lookupIndexCount)].map(t=>e.uint16)}getFeatureParams(){if(this.featureParams>0){let e=this.parser;e.currentPosition=this.start+this.featureParams;let t=this.featureTag;if(t==="size")return new iC(e);if(t.startsWith("cc"))return new nC(e);if(t.startsWith("ss"))return new sC(e)}}},nC=class{constructor(e){this.format=e.uint16,this.featUiLabelNameId=e.uint16,this.featUiTooltipTextNameId=e.uint16,this.sampleTextNameId=e.uint16,this.numNamedParameters=e.uint16,this.firstParamUiLabelNameId=e.uint16,this.charCount=e.uint16,this.character=[...new Array(this.charCount)].map(t=>e.uint24)}},iC=class{constructor(e){this.designSize=e.uint16,this.subfamilyIdentifier=e.uint16,this.subfamilyNameID=e.uint16,this.smallEnd=e.uint16,this.largeEnd=e.uint16}},sC=class{constructor(e){this.version=e.uint16,this.UINameID=e.uint16}};function Ty(e){e.parser.currentPosition-=2,delete e.coverageOffset,delete e.getCoverageTable}var Qo=class extends lt{constructor(e){super(e),this.substFormat=e.uint16,this.coverageOffset=e.Offset16}getCoverageTable(){let e=this.parser;return e.currentPosition=this.start+this.coverageOffset,new _i(e)}},ru=class{constructor(e){this.glyphSequenceIndex=e.uint16,this.lookupListIndex=e.uint16}},aC=class extends Qo{constructor(e){super(e),this.deltaGlyphID=e.int16}},lC=class extends Qo{constructor(e){super(e),this.sequenceCount=e.uint16,this.sequenceOffsets=[...new Array(this.sequenceCount)].map(t=>e.Offset16)}getSequence(e){let t=this.parser;return t.currentPosition=this.start+this.sequenceOffsets[e],new cC(t)}},cC=class{constructor(e){this.glyphCount=e.uint16,this.substituteGlyphIDs=[...new Array(this.glyphCount)].map(t=>e.uint16)}},uC=class extends Qo{constructor(e){super(e),this.alternateSetCount=e.uint16,this.alternateSetOffsets=[...new Array(this.alternateSetCount)].map(t=>e.Offset16)}getAlternateSet(e){let t=this.parser;return t.currentPosition=this.start+this.alternateSetOffsets[e],new fC(t)}},fC=class{constructor(e){this.glyphCount=e.uint16,this.alternateGlyphIDs=[...new Array(this.glyphCount)].map(t=>e.uint16)}},dC=class extends Qo{constructor(e){super(e),this.ligatureSetCount=e.uint16,this.ligatureSetOffsets=[...new Array(this.ligatureSetCount)].map(t=>e.Offset16)}getLigatureSet(e){let t=this.parser;return t.currentPosition=this.start+this.ligatureSetOffsets[e],new pC(t)}},pC=class extends lt{constructor(e){super(e),this.ligatureCount=e.uint16,this.ligatureOffsets=[...new Array(this.ligatureCount)].map(t=>e.Offset16)}getLigature(e){let t=this.parser;return t.currentPosition=this.start+this.ligatureOffsets[e],new mC(t)}},mC=class{constructor(e){this.ligatureGlyph=e.uint16,this.componentCount=e.uint16,this.componentGlyphIDs=[...new Array(this.componentCount-1)].map(t=>e.uint16)}},hC=class extends Qo{constructor(e){super(e),this.substFormat===1&&(this.subRuleSetCount=e.uint16,this.subRuleSetOffsets=[...new Array(this.subRuleSetCount)].map(t=>e.Offset16)),this.substFormat===2&&(this.classDefOffset=e.Offset16,this.subClassSetCount=e.uint16,this.subClassSetOffsets=[...new Array(this.subClassSetCount)].map(t=>e.Offset16)),this.substFormat===3&&(Ty(this),this.glyphCount=e.uint16,this.substitutionCount=e.uint16,this.coverageOffsets=[...new Array(this.glyphCount)].map(t=>e.Offset16),this.substLookupRecords=[...new Array(this.substitutionCount)].map(t=>new ru(e)))}getSubRuleSet(e){if(this.substFormat!==1)throw new Error(`lookup type 5.${this.substFormat} has no subrule sets.`);let t=this.parser;return t.currentPosition=this.start+this.subRuleSetOffsets[e],new gC(t)}getSubClassSet(e){if(this.substFormat!==2)throw new Error(`lookup type 5.${this.substFormat} has no subclass sets.`);let t=this.parser;return t.currentPosition=this.start+this.subClassSetOffsets[e],new yC(t)}getCoverageTable(e){if(this.substFormat!==3&&!e)return super.getCoverageTable();if(!e)throw new Error(`lookup type 5.${this.substFormat} requires an coverage table index.`);let t=this.parser;return t.currentPosition=this.start+this.coverageOffsets[e],new _i(t)}},gC=class extends lt{constructor(e){super(e),this.subRuleCount=e.uint16,this.subRuleOffsets=[...new Array(this.subRuleCount)].map(t=>e.Offset16)}getSubRule(e){let t=this.parser;return t.currentPosition=this.start+this.subRuleOffsets[e],new Py(t)}},Py=class{constructor(e){this.glyphCount=e.uint16,this.substitutionCount=e.uint16,this.inputSequence=[...new Array(this.glyphCount-1)].map(t=>e.uint16),this.substLookupRecords=[...new Array(this.substitutionCount)].map(t=>new ru(e))}},yC=class extends lt{constructor(e){super(e),this.subClassRuleCount=e.uint16,this.subClassRuleOffsets=[...new Array(this.subClassRuleCount)].map(t=>e.Offset16)}getSubClass(e){let t=this.parser;return t.currentPosition=this.start+this.subClassRuleOffsets[e],new vC(t)}},vC=class extends Py{constructor(e){super(e)}},bC=class extends Qo{constructor(e){super(e),this.substFormat===1&&(this.chainSubRuleSetCount=e.uint16,this.chainSubRuleSetOffsets=[...new Array(this.chainSubRuleSetCount)].map(t=>e.Offset16)),this.substFormat===2&&(this.backtrackClassDefOffset=e.Offset16,this.inputClassDefOffset=e.Offset16,this.lookaheadClassDefOffset=e.Offset16,this.chainSubClassSetCount=e.uint16,this.chainSubClassSetOffsets=[...new Array(this.chainSubClassSetCount)].map(t=>e.Offset16)),this.substFormat===3&&(Ty(this),this.backtrackGlyphCount=e.uint16,this.backtrackCoverageOffsets=[...new Array(this.backtrackGlyphCount)].map(t=>e.Offset16),this.inputGlyphCount=e.uint16,this.inputCoverageOffsets=[...new Array(this.inputGlyphCount)].map(t=>e.Offset16),this.lookaheadGlyphCount=e.uint16,this.lookaheadCoverageOffsets=[...new Array(this.lookaheadGlyphCount)].map(t=>e.Offset16),this.seqLookupCount=e.uint16,this.seqLookupRecords=[...new Array(this.substitutionCount)].map(t=>new Oy(e)))}getChainSubRuleSet(e){if(this.substFormat!==1)throw new Error(`lookup type 6.${this.substFormat} has no chainsubrule sets.`);let t=this.parser;return t.currentPosition=this.start+this.chainSubRuleSetOffsets[e],new wC(t)}getChainSubClassSet(e){if(this.substFormat!==2)throw new Error(`lookup type 6.${this.substFormat} has no chainsubclass sets.`);let t=this.parser;return t.currentPosition=this.start+this.chainSubClassSetOffsets[e],new SC(t)}getCoverageFromOffset(e){if(this.substFormat!==3)throw new Error(`lookup type 6.${this.substFormat} does not use contextual coverage offsets.`);let t=this.parser;return t.currentPosition=this.start+e,new _i(t)}},wC=class extends lt{constructor(e){super(e),this.chainSubRuleCount=e.uint16,this.chainSubRuleOffsets=[...new Array(this.chainSubRuleCount)].map(t=>e.Offset16)}getSubRule(e){let t=this.parser;return t.currentPosition=this.start+this.chainSubRuleOffsets[e],new xC(t)}},xC=class{constructor(e){this.backtrackGlyphCount=e.uint16,this.backtrackSequence=[...new Array(this.backtrackGlyphCount)].map(t=>e.uint16),this.inputGlyphCount=e.uint16,this.inputSequence=[...new Array(this.inputGlyphCount-1)].map(t=>e.uint16),this.lookaheadGlyphCount=e.uint16,this.lookAheadSequence=[...new Array(this.lookAheadGlyphCount)].map(t=>e.uint16),this.substitutionCount=e.uint16,this.substLookupRecords=[...new Array(this.SubstCount)].map(t=>new ru(e))}},SC=class extends lt{constructor(e){super(e),this.chainSubClassRuleCount=e.uint16,this.chainSubClassRuleOffsets=[...new Array(this.chainSubClassRuleCount)].map(t=>e.Offset16)}getSubClass(e){let t=this.parser;return t.currentPosition=this.start+this.chainSubRuleOffsets[e],new _C(t)}},_C=class{constructor(e){this.backtrackGlyphCount=e.uint16,this.backtrackSequence=[...new Array(this.backtrackGlyphCount)].map(t=>e.uint16),this.inputGlyphCount=e.uint16,this.inputSequence=[...new Array(this.inputGlyphCount-1)].map(t=>e.uint16),this.lookaheadGlyphCount=e.uint16,this.lookAheadSequence=[...new Array(this.lookAheadGlyphCount)].map(t=>e.uint16),this.substitutionCount=e.uint16,this.substLookupRecords=[...new Array(this.substitutionCount)].map(t=>new Oy(e))}},Oy=class extends lt{constructor(e){super(e),this.sequenceIndex=e.uint16,this.lookupListIndex=e.uint16}},CC=class extends lt{constructor(e){super(e),this.substFormat=e.uint16,this.extensionLookupType=e.uint16,this.extensionOffset=e.Offset32}},RC=class extends Qo{constructor(e){super(e),this.backtrackGlyphCount=e.uint16,this.backtrackCoverageOffsets=[...new Array(this.backtrackGlyphCount)].map(t=>e.Offset16),this.lookaheadGlyphCount=e.uint16,this.lookaheadCoverageOffsets=[new Array(this.lookaheadGlyphCount)].map(t=>e.Offset16),this.glyphCount=e.uint16,this.substituteGlyphIDs=[...new Array(this.glyphCount)].map(t=>e.uint16)}},EC={buildSubtable:function(e,t){let r=new[void 0,aC,lC,uC,dC,hC,bC,CC,RC][e](t);return r.type=e,r}},no=class extends lt{constructor(e){super(e)}},TC=class extends no{constructor(e){super(e),console.log("lookup type 1")}},PC=class extends no{constructor(e){super(e),console.log("lookup type 2")}},OC=class extends no{constructor(e){super(e),console.log("lookup type 3")}},kC=class extends no{constructor(e){super(e),console.log("lookup type 4")}},FC=class extends no{constructor(e){super(e),console.log("lookup type 5")}},AC=class extends no{constructor(e){super(e),console.log("lookup type 6")}},IC=class extends no{constructor(e){super(e),console.log("lookup type 7")}},LC=class extends no{constructor(e){super(e),console.log("lookup type 8")}},NC=class extends no{constructor(e){super(e),console.log("lookup type 9")}},MC={buildSubtable:function(e,t){let r=new[void 0,TC,PC,OC,kC,FC,AC,IC,LC,NC][e](t);return r.type=e,r}},_y=class extends lt{static EMPTY={lookupCount:0,lookups:[]};constructor(e){super(e),this.lookupCount=e.uint16,this.lookups=[...new Array(this.lookupCount)].map(t=>e.Offset16)}},VC=class extends lt{constructor(e,t){super(e),this.ctType=t,this.lookupType=e.uint16,this.lookupFlag=e.uint16,this.subTableCount=e.uint16,this.subtableOffsets=[...new Array(this.subTableCount)].map(r=>e.Offset16),this.markFilteringSet=e.uint16}get rightToLeft(){return this.lookupFlag&!0}get ignoreBaseGlyphs(){return this.lookupFlag&!0}get ignoreLigatures(){return this.lookupFlag&!0}get ignoreMarks(){return this.lookupFlag&!0}get useMarkFilteringSet(){return this.lookupFlag&!0}get markAttachmentType(){return this.lookupFlag&!0}getSubTable(e){let t=this.ctType==="GSUB"?EC:MC;return this.parser.currentPosition=this.start+this.subtableOffsets[e],t.buildSubtable(this.lookupType,this.parser)}},ky=class extends ke{constructor(e,t,r){let{p:o,tableStart:n}=super(e,t,r);this.majorVersion=o.uint16,this.minorVersion=o.uint16,this.scriptListOffset=o.Offset16,this.featureListOffset=o.Offset16,this.lookupListOffset=o.Offset16,this.majorVersion===1&&this.minorVersion===1&&(this.featureVariationsOffset=o.Offset32);let i=!(this.scriptListOffset||this.featureListOffset||this.lookupListOffset);ae(this,"scriptList",()=>i?wy.EMPTY:(o.currentPosition=n+this.scriptListOffset,new wy(o))),ae(this,"featureList",()=>i?Sy.EMPTY:(o.currentPosition=n+this.featureListOffset,new Sy(o))),ae(this,"lookupList",()=>i?_y.EMPTY:(o.currentPosition=n+this.lookupListOffset,new _y(o))),this.featureVariationsOffset&&ae(this,"featureVariations",()=>i?FeatureVariations.EMPTY:(o.currentPosition=n+this.featureVariationsOffset,new FeatureVariations(o)))}getSupportedScripts(){return this.scriptList.scriptRecords.map(e=>e.scriptTag)}getScriptTable(e){let t=this.scriptList.scriptRecords.find(o=>o.scriptTag===e);this.parser.currentPosition=this.scriptList.start+t.scriptOffset;let r=new eC(this.parser);return r.scriptTag=e,r}ensureScriptTable(e){return typeof e=="string"?this.getScriptTable(e):e}getSupportedLangSys(e){e=this.ensureScriptTable(e);let t=e.defaultLangSys!==0,r=e.langSysRecords.map(o=>o.langSysTag);return t&&r.unshift("dflt"),r}getDefaultLangSysTable(e){e=this.ensureScriptTable(e);let t=e.defaultLangSys;if(t!==0){this.parser.currentPosition=e.start+t;let r=new xy(this.parser);return r.langSysTag="",r.defaultForScript=e.scriptTag,r}}getLangSysTable(e,t="dflt"){if(t==="dflt")return this.getDefaultLangSysTable(e);e=this.ensureScriptTable(e);let r=e.langSysRecords.find(n=>n.langSysTag===t);this.parser.currentPosition=e.start+r.langSysOffset;let o=new xy(this.parser);return o.langSysTag=t,o}getFeatures(e){return e.featureIndices.map(t=>this.getFeature(t))}getFeature(e){let t;if(parseInt(e)==e?t=this.featureList.featureRecords[e]:t=this.featureList.featureRecords.find(o=>o.featureTag===e),!t)return;this.parser.currentPosition=this.featureList.start+t.featureOffset;let r=new oC(this.parser);return r.featureTag=t.featureTag,r}getLookups(e){return e.lookupListIndices.map(t=>this.getLookup(t))}getLookup(e,t){let r=this.lookupList.lookups[e];return this.parser.currentPosition=this.lookupList.start+r,new VC(this.parser,t)}},DC=class extends ky{constructor(e,t){super(e,t,"GSUB")}getLookup(e){return super.getLookup(e,"GSUB")}},BC=Object.freeze({__proto__:null,GSUB:DC}),jC=class extends ky{constructor(e,t){super(e,t,"GPOS")}getLookup(e){return super.getLookup(e,"GPOS")}},zC=Object.freeze({__proto__:null,GPOS:jC}),HC=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.offsetToSVGDocumentList=r.Offset32,r.currentPosition=this.tableStart+this.offsetToSVGDocumentList,this.documentList=new UC(r)}},UC=class extends lt{constructor(e){super(e),this.numEntries=e.uint16,this.documentRecords=[...new Array(this.numEntries)].map(t=>new WC(e))}getDocument(e){let t=this.documentRecords[e];if(!t)return"";let r=this.start+t.svgDocOffset;return this.parser.currentPosition=r,this.parser.readBytes(t.svgDocLength)}getDocumentForGlyph(e){let t=this.documentRecords.findIndex(r=>r.startGlyphID<=e&&e<=r.endGlyphID);return t===-1?"":this.getDocument(t)}},WC=class{constructor(e){this.startGlyphID=e.uint16,this.endGlyphID=e.uint16,this.svgDocOffset=e.Offset32,this.svgDocLength=e.uint32}},GC=Object.freeze({__proto__:null,SVG:HC}),YC=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.majorVersion=r.uint16,this.minorVersion=r.uint16,this.axesArrayOffset=r.Offset16,r.uint16,this.axisCount=r.uint16,this.axisSize=r.uint16,this.instanceCount=r.uint16,this.instanceSize=r.uint16;let o=this.tableStart+this.axesArrayOffset;ae(this,"axes",()=>(r.currentPosition=o,[...new Array(this.axisCount)].map(i=>new qC(r))));let n=o+this.axisCount*this.axisSize;ae(this,"instances",()=>{let i=[];for(let s=0;se.tag)}getAxis(e){return this.axes.find(t=>t.tag===e)}},qC=class{constructor(e){this.tag=e.tag,this.minValue=e.fixed,this.defaultValue=e.fixed,this.maxValue=e.fixed,this.flags=e.flags(16),this.axisNameID=e.uint16}},ZC=class{constructor(e,t,r){let o=e.currentPosition;this.subfamilyNameID=e.uint16,e.uint16,this.coordinates=[...new Array(t)].map(n=>e.fixed),e.currentPosition-o[...new Array(o)].map(n=>r.fword))}},JC=Object.freeze({__proto__:null,cvt:KC}),QC=class extends ke{constructor(e,t){let{p:r}=super(e,t);ae(this,"instructions",()=>[...new Array(e.length)].map(o=>r.uint8))}},$C=Object.freeze({__proto__:null,fpgm:QC}),eR=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.numRanges=r.uint16,ae(this,"gaspRanges",()=>[...new Array(this.numRanges)].map(n=>new tR(r)))}},tR=class{constructor(e){this.rangeMaxPPEM=e.uint16,this.rangeGaspBehavior=e.uint16}},rR=Object.freeze({__proto__:null,gasp:eR}),oR=class extends ke{constructor(e,t){super(e,t)}getGlyphData(e,t){return this.parser.currentPosition=this.tableStart+e,this.parser.readBytes(t)}},nR=Object.freeze({__proto__:null,glyf:oR}),iR=class extends ke{constructor(e,t,r){let{p:o}=super(e,t),n=r.maxp.numGlyphs+1;r.head.indexToLocFormat===0?(this.x2=!0,ae(this,"offsets",()=>[...new Array(n)].map(i=>o.Offset16))):ae(this,"offsets",()=>[...new Array(n)].map(i=>o.Offset32))}getGlyphDataOffsetAndLength(e){let t=this.offsets[e]*this.x2?2:1,r=this.offsets[e+1]*this.x2?2:1;return{offset:t,length:r-t}}},sR=Object.freeze({__proto__:null,loca:iR}),aR=class extends ke{constructor(e,t){let{p:r}=super(e,t);ae(this,"instructions",()=>[...new Array(e.length)].map(o=>r.uint8))}},lR=Object.freeze({__proto__:null,prep:aR}),cR=class extends ke{constructor(e,t){let{p:r}=super(e,t);ae(this,"data",()=>r.readBytes())}},uR=Object.freeze({__proto__:null,CFF:cR}),fR=class extends ke{constructor(e,t){let{p:r}=super(e,t);ae(this,"data",()=>r.readBytes())}},dR=Object.freeze({__proto__:null,CFF2:fR}),pR=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.majorVersion=r.uint16,this.minorVersion=r.uint16,this.defaultVertOriginY=r.int16,this.numVertOriginYMetrics=r.uint16,ae(this,"vertORiginYMetrics",()=>[...new Array(this.numVertOriginYMetrics)].map(o=>new mR(r)))}},mR=class{constructor(e){this.glyphIndex=e.uint16,this.vertOriginY=e.int16}},hR=Object.freeze({__proto__:null,VORG:pR}),gR=class{constructor(e){this.indexSubTableArrayOffset=e.Offset32,this.indexTablesSize=e.uint32,this.numberofIndexSubTables=e.uint32,this.colorRef=e.uint32,this.hori=new fa(e),this.vert=new fa(e),this.startGlyphIndex=e.uint16,this.endGlyphIndex=e.uint16,this.ppemX=e.uint8,this.ppemY=e.uint8,this.bitDepth=e.uint8,this.flags=e.int8}},yR=class{constructor(e){this.hori=new fa(e),this.vert=new fa(e),this.ppemX=e.uint8,this.ppemY=e.uint8,this.substitutePpemX=e.uint8,this.substitutePpemY=e.uint8}},fa=class{constructor(e){this.ascender=e.int8,this.descender=e.int8,this.widthMax=e.uint8,this.caretSlopeNumerator=e.int8,this.caretSlopeDenominator=e.int8,this.caretOffset=e.int8,this.minOriginSB=e.int8,this.minAdvanceSB=e.int8,this.maxBeforeBL=e.int8,this.minAfterBL=e.int8,this.pad1=e.int8,this.pad2=e.int8}},Fy=class extends ke{constructor(e,t,r){let{p:o}=super(e,t,r);this.majorVersion=o.uint16,this.minorVersion=o.uint16,this.numSizes=o.uint32,ae(this,"bitMapSizes",()=>[...new Array(this.numSizes)].map(n=>new gR(o)))}},vR=Object.freeze({__proto__:null,EBLC:Fy}),Ay=class extends ke{constructor(e,t,r){let{p:o}=super(e,t,r);this.majorVersion=o.uint16,this.minorVersion=o.uint16}},bR=Object.freeze({__proto__:null,EBDT:Ay}),wR=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.majorVersion=r.uint16,this.minorVersion=r.uint16,this.numSizes=r.uint32,ae(this,"bitmapScales",()=>[...new Array(this.numSizes)].map(o=>new yR(r)))}},xR=Object.freeze({__proto__:null,EBSC:wR}),SR=class extends Fy{constructor(e,t){super(e,t,"CBLC")}},_R=Object.freeze({__proto__:null,CBLC:SR}),CR=class extends Ay{constructor(e,t){super(e,t,"CBDT")}},RR=Object.freeze({__proto__:null,CBDT:CR}),ER=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.flags=r.flags(16),this.numStrikes=r.uint32,ae(this,"strikeOffsets",()=>[...new Array(this.numStrikes)].map(o=>r.Offset32))}},TR=Object.freeze({__proto__:null,sbix:ER}),PR=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.numBaseGlyphRecords=r.uint16,this.baseGlyphRecordsOffset=r.Offset32,this.layerRecordsOffset=r.Offset32,this.numLayerRecords=r.uint16}getBaseGlyphRecord(e){let t=this.tableStart+this.baseGlyphRecordsOffset;this.parser.currentPosition=t;let r=new tu(this.parser),o=r.gID,n=this.tableStart+this.layerRecordsOffset-6;this.parser.currentPosition=n;let i=new tu(this.parser),s=i.gID;if(o===e)return r;if(s===e)return i;for(;t!==n;){let a=t+(n-t)/12;this.parser.currentPosition=a;let u=new tu(this.parser),l=u.gID;if(l===e)return u;l>e?n=a:lnew OR(p))}},tu=class{constructor(e){this.gID=e.uint16,this.firstLayerIndex=e.uint16,this.numLayers=e.uint16}},OR=class{constructor(e){this.gID=e.uint16,this.paletteIndex=e.uint16}},kR=Object.freeze({__proto__:null,COLR:PR}),FR=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.numPaletteEntries=r.uint16;let o=this.numPalettes=r.uint16;this.numColorRecords=r.uint16,this.offsetFirstColorRecord=r.Offset32,this.colorRecordIndices=[...new Array(this.numPalettes)].map(n=>r.uint16),ae(this,"colorRecords",()=>(r.currentPosition=this.tableStart+this.offsetFirstColorRecord,[...new Array(this.numColorRecords)].map(n=>new AR(r)))),this.version===1&&(this.offsetPaletteTypeArray=r.Offset32,this.offsetPaletteLabelArray=r.Offset32,this.offsetPaletteEntryLabelArray=r.Offset32,ae(this,"paletteTypeArray",()=>(r.currentPosition=this.tableStart+this.offsetPaletteTypeArray,new IR(r,o))),ae(this,"paletteLabelArray",()=>(r.currentPosition=this.tableStart+this.offsetPaletteLabelArray,new LR(r,o))),ae(this,"paletteEntryLabelArray",()=>(r.currentPosition=this.tableStart+this.offsetPaletteEntryLabelArray,new NR(r,o))))}},AR=class{constructor(e){this.blue=e.uint8,this.green=e.uint8,this.red=e.uint8,this.alpha=e.uint8}},IR=class{constructor(e,t){this.paletteTypes=[...new Array(t)].map(r=>e.uint32)}},LR=class{constructor(e,t){this.paletteLabels=[...new Array(t)].map(r=>e.uint16)}},NR=class{constructor(e,t){this.paletteEntryLabels=[...new Array(t)].map(r=>e.uint16)}},MR=Object.freeze({__proto__:null,CPAL:FR}),VR=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint32,this.numSignatures=r.uint16,this.flags=r.uint16,this.signatureRecords=[...new Array(this.numSignatures)].map(o=>new DR(r))}getData(e){let t=this.signatureRecords[e];return this.parser.currentPosition=this.tableStart+t.offset,new BR(this.parser)}},DR=class{constructor(e){this.format=e.uint32,this.length=e.uint32,this.offset=e.Offset32}},BR=class{constructor(e){e.uint16,e.uint16,this.signatureLength=e.uint32,this.signature=e.readBytes(this.signatureLength)}},jR=Object.freeze({__proto__:null,DSIG:VR}),zR=class extends ke{constructor(e,t,r){let{p:o}=super(e,t),n=r.hmtx.numGlyphs;this.version=o.uint16,this.numRecords=o.int16,this.sizeDeviceRecord=o.int32,this.records=[...new Array(numRecords)].map(i=>new HR(o,n))}},HR=class{constructor(e,t){this.pixelSize=e.uint8,this.maxWidth=e.uint8,this.widths=e.readBytes(t)}},UR=Object.freeze({__proto__:null,hdmx:zR}),WR=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.nTables=r.uint16,ae(this,"tables",()=>{let o=this.tableStart+4,n=[];for(let i=0;i[...new Array(this.nPairs)].map(t=>new YR(e)))),this.format===2&&console.warn("Kern subtable format 2 is not supported: this parser currently only parses universal table data.")}get horizontal(){return this.coverage[0]}get minimum(){return this.coverage[1]}get crossstream(){return this.coverage[2]}get override(){return this.coverage[3]}},YR=class{constructor(e){this.left=e.uint16,this.right=e.uint16,this.value=e.fword}},qR=Object.freeze({__proto__:null,kern:WR}),ZR=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.numGlyphs=r.uint16,this.yPels=r.readBytes(this.numGlyphs)}},XR=Object.freeze({__proto__:null,LTSH:ZR}),KR=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.mergeClassCount=r.uint16,this.mergeDataOffset=r.Offset16,this.classDefCount=r.uint16,this.offsetToClassDefOffsets=r.Offset16,ae(this,"mergeEntryMatrix",()=>[...new Array(this.mergeClassCount)].map(o=>r.readBytes(this.mergeClassCount))),console.warn("Full MERG parsing is currently not supported."),console.warn("If you need this table parsed, please file an issue, or better yet, a PR.")}},JR=Object.freeze({__proto__:null,MERG:KR}),QR=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint32,this.flags=r.uint32,r.uint32,this.dataMapsCount=r.uint32,this.dataMaps=[...new Array(this.dataMapsCount)].map(o=>new $R(this.tableStart,r))}},$R=class{constructor(e,t){this.tableStart=e,this.parser=t,this.tag=t.tag,this.dataOffset=t.Offset32,this.dataLength=t.uint32}getData(){return this.parser.currentField=this.tableStart+this.dataOffset,this.parser.readBytes(this.dataLength)}},e2=Object.freeze({__proto__:null,meta:QR}),t2=class extends ke{constructor(e,t){super(e,t),console.warn("This font uses a PCLT table, which is currently not supported by this parser."),console.warn("If you need this table parsed, please file an issue, or better yet, a PR.")}},r2=Object.freeze({__proto__:null,PCLT:t2}),o2=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.uint16,this.numRecs=r.uint16,this.numRatios=r.uint16,this.ratRanges=[...new Array(this.numRatios)].map(o=>new n2(r)),this.offsets=[...new Array(this.numRatios)].map(o=>r.Offset16),this.VDMXGroups=[...new Array(this.numRecs)].map(o=>new i2(r))}},n2=class{constructor(e){this.bCharSet=e.uint8,this.xRatio=e.uint8,this.yStartRatio=e.uint8,this.yEndRatio=e.uint8}},i2=class{constructor(e){this.recs=e.uint16,this.startsz=e.uint8,this.endsz=e.uint8,this.records=[...new Array(this.recs)].map(t=>new s2(e))}},s2=class{constructor(e){this.yPelHeight=e.uint16,this.yMax=e.int16,this.yMin=e.int16}},a2=Object.freeze({__proto__:null,VDMX:o2}),l2=class extends ke{constructor(e,t){let{p:r}=super(e,t);this.version=r.fixed,this.ascent=this.vertTypoAscender=r.int16,this.descent=this.vertTypoDescender=r.int16,this.lineGap=this.vertTypoLineGap=r.int16,this.advanceHeightMax=r.int16,this.minTopSideBearing=r.int16,this.minBottomSideBearing=r.int16,this.yMaxExtent=r.int16,this.caretSlopeRise=r.int16,this.caretSlopeRun=r.int16,this.caretOffset=r.int16,this.reserved=r.int16,this.reserved=r.int16,this.reserved=r.int16,this.reserved=r.int16,this.metricDataFormat=r.int16,this.numOfLongVerMetrics=r.uint16,r.verifyLength()}},c2=Object.freeze({__proto__:null,vhea:l2}),u2=class extends ke{constructor(e,t,r){super(e,t);let o=r.vhea.numOfLongVerMetrics,n=r.maxp.numGlyphs,i=p.currentPosition;if(lazy(this,"vMetrics",()=>(p.currentPosition=i,[...new Array(o)].map(s=>new f2(p.uint16,p.int16)))),o(p.currentPosition=s,[...new Array(n-o)].map(a=>p.int16)))}}},f2=class{constructor(e,t){this.advanceHeight=e,this.topSideBearing=t}},d2=Object.freeze({__proto__:null,vmtx:u2});function Iy(e){let t=e.reduce((r,o)=>(r[o.fontFamily]||(r[o.fontFamily]={name:o.fontFamily,fontFamily:o.fontFamily,slug:Ks(o.fontFamily.toLowerCase()),fontFace:[]}),r[o.fontFamily].fontFace.push(o),r),{});return Object.values(t)}var Qt=f(Z(),1);function p2(){let{installFonts:e}=(0,Ci.useContext)(jt),[t,r]=(0,Ci.useState)(!1),[o,n]=(0,Ci.useState)(null),i=h=>{a(h)},s=h=>{a(h.target.files)},a=async h=>{if(!h)return;n(null),r(!0);let g=new Set,b=[...h],w=!1,_=b.map(async v=>{if(!await l(v))return w=!0,null;if(g.has(v.name))return null;let k=(((v.name??"").split(".")??[]).pop()??"").toLowerCase();return Kc.includes(k)?(g.add(v.name),v):null}),x=(await Promise.all(_)).filter(v=>v!==null);if(x.length>0)u(x);else{let v=w?(0,Vn.__)("Sorry, you are not allowed to upload this file type."):(0,Vn.__)("No fonts found to install.");n({type:"error",message:v}),r(!1)}},u=async h=>{let g=await Promise.all(h.map(async b=>{let w=await m(b);return await Po(w,w.file,"all"),w}));d(g)};async function l(h){let g=new da("Uploaded Font");try{let b=await c(h);return await g.fromDataBuffer(b,"font"),!0}catch{return!1}}async function c(h){return new Promise((g,b)=>{let w=new window.FileReader;w.readAsArrayBuffer(h),w.onload=()=>g(w.result),w.onerror=b})}let m=async h=>{let g=await c(h),b=new da("Uploaded Font");b.fromDataBuffer(g,h.name);let _=(await new Promise(I=>b.onload=I)).detail.font,{name:x}=_.opentype.tables,v=x.get(16)||x.get(1),C=x.get(2).toLowerCase().includes("italic"),k=_.opentype.tables["OS/2"].usWeightClass||"normal",T=!!_.opentype.tables.fvar&&_.opentype.tables.fvar.axes.find(({tag:I})=>I==="wght"),O=T?`${T.minValue} ${T.maxValue}`:null;return{file:h,fontFamily:v,fontStyle:C?"italic":"normal",fontWeight:O||k}},d=async h=>{let g=Iy(h);try{await e(g),n({type:"success",message:(0,Vn.__)("Fonts were installed successfully.")})}catch(b){let w=b;n({type:"error",message:w.message,errors:w?.installationErrors})}r(!1)};return(0,Qt.jsxs)("div",{className:"font-library__tabpanel-layout",children:[(0,Qt.jsx)(Ot.DropZone,{onFilesDrop:i}),(0,Qt.jsxs)(Ot.__experimentalVStack,{className:"font-library__local-fonts",justify:"start",children:[o&&(0,Qt.jsxs)(Ot.Notice,{status:o.type,__unstableHTML:!0,onRemove:()=>n(null),children:[o.message,o.errors&&(0,Qt.jsx)("ul",{children:o.errors.map((h,g)=>(0,Qt.jsx)("li",{children:h},g))})]}),t&&(0,Qt.jsx)(Ot.FlexItem,{children:(0,Qt.jsx)("div",{className:"font-library__upload-area",children:(0,Qt.jsx)(Ot.ProgressBar,{})})}),!t&&(0,Qt.jsx)(Ot.FormFileUpload,{accept:Kc.map(h=>`.${h}`).join(","),multiple:!0,onChange:s,render:({openFileDialog:h})=>(0,Qt.jsx)(Ot.Button,{__next40pxDefaultSize:!0,className:"font-library__upload-area",onClick:h,children:(0,Vn.__)("Upload font")})}),(0,Qt.jsx)(Ot.__experimentalText,{className:"font-library__upload-area__text",children:(0,Vn.__)("Uploaded fonts appear in your library and can be used in your theme. Supported formats: .ttf, .otf, .woff, and .woff2.")})]})]})}var pa=p2;var Ny=f(Z(),1),{Tabs:VB}=De(ou.privateApis),DB={id:"installed-fonts",title:(0,ma._x)("Library","Font library")},BB={id:"upload-fonts",title:(0,ma._x)("Upload","noun")};var My=f(ge(),1),nu=f(ue(),1),h2=f(Te(),1);var Vy=f(Z(),1);var iu=f(Z(),1);var Dy=f(ge(),1),ha=f(ue(),1);var By=f(Z(),1);var au=f(Z(),1);var wt=f(ge(),1),lu=f(ue(),1),_2=f(Te(),1);var jy=f(Dt(),1);var x2=f(Z(),1),{useSettingsForBlockElement:hj,TypographyPanel:gj}=De(jy.privateApis);var S2=f(Z(),1);var cu=f(Z(),1),Rj={text:{description:(0,wt.__)("Manage the fonts used on the site."),title:(0,wt.__)("Text")},link:{description:(0,wt.__)("Manage the fonts and typography used on the links."),title:(0,wt.__)("Links")},heading:{description:(0,wt.__)("Manage the fonts and typography used on headings."),title:(0,wt.__)("Headings")},caption:{description:(0,wt.__)("Manage the fonts and typography used on captions."),title:(0,wt.__)("Captions")},cite:{description:(0,wt.__)("Manage the fonts and typography used on citations."),title:(0,wt.__)("Citations")},button:{description:(0,wt.__)("Manage the fonts and typography used on buttons."),title:(0,wt.__)("Buttons")},textInput:{description:(0,wt.__)("Manage the fonts and typography used on inputs."),title:(0,wt.__)("Inputs")},select:{description:(0,wt.__)("Manage the fonts and typography used on selects."),title:(0,wt.__)("Selects")}};var ga=f(ge(),1),T2=f(ue(),1),Hy=f(Dt(),1);var Dn=f(ue(),1),zy=f(ge(),1);var E2=f(Te(),1);var C2=f(ue(),1),R2=f(Z(),1);var uu=f(Z(),1);var fu=f(Z(),1),{useSettingsForBlockElement:zj,ColorPanel:Hj}=De(Hy.privateApis),Uj=[{name:"cite",label:(0,ga.__)("Citations")},{name:"textInput",label:(0,ga.__)("Inputs")},{name:"select",label:(0,ga.__)("Selects")}];var D2=f(ge(),1);var k2=f(yo(),1),qy=f(ue(),1),F2=f(ge(),1);var va=f(ue(),1);var ya=f(ue(),1);var Uy=f(Z(),1);function Wy(){let{paletteColors:e}=Pn();return e.slice(0,4).map(({slug:t,color:r},o)=>(0,Uy.jsx)("div",{style:{flexGrow:1,height:"100%",background:r}},`${t}-${o}`))}var Ei=f(Z(),1),P2={start:{scale:1,opacity:1},hover:{scale:0,opacity:0}},O2=({label:e,isFocused:t,withHoverView:r})=>(0,Ei.jsx)(Fn,{label:e,isFocused:t,withHoverView:r,children:({key:o})=>(0,Ei.jsx)(ya.__unstableMotion.div,{variants:P2,style:{height:"100%",overflow:"hidden"},children:(0,Ei.jsx)(ya.__experimentalHStack,{spacing:0,justify:"center",style:{height:"100%",overflow:"hidden"},children:(0,Ei.jsx)(Wy,{})})},o)}),Gy=O2;var $o=f(Z(),1),Yy=["color"];function ba({title:e,gap:t=2}){let r=Hs(Yy);return r?.length<=1?null:(0,$o.jsxs)(va.__experimentalVStack,{spacing:3,children:[e&&(0,$o.jsx)(Er,{level:3,children:e}),(0,$o.jsx)(va.__experimentalGrid,{gap:t,children:r.map((o,n)=>(0,$o.jsx)(An,{variation:o,isPill:!0,properties:Yy,showTooltip:!0,children:()=>(0,$o.jsx)(Gy,{})},n))})]})}var Zy=f(Z(),1);var A2=f(yo(),1),Xy=f(ue(),1),I2=f(ge(),1);var Ky=f(Z(),1);var L2=f(yo(),1),N2=f(Te(),1),M2=f(ue(),1);var V2=f(ge(),1);var Jy=f(Z(),1);var du=f(Z(),1);var j2=f(ge(),1),$y=f(Dt(),1),z2=f(ue(),1);var Qy=f(Dt(),1);var B2=f(Z(),1);var{BackgroundPanel:v7}=De(Qy.privateApis);var pu=f(Z(),1),{useHasBackgroundPanel:R7}=De($y.privateApis);var tv=f(ge(),1);var Ti=f(ue(),1),G2=f(ge(),1);var Y2=f(Te(),1);var H2=f(ue(),1),U2=f(ge(),1),W2=f(Z(),1);var ev=f(Z(),1),{Menu:I7}=De(Ti.privateApis);var hu=f(Z(),1);var gr=f(ue(),1),nv=f(ge(),1);var wa=f(Te(),1);var Pi=f(ue(),1);var rv=f(Z(),1),{Menu:q7}=De(Pi.privateApis);var X2=f(ue(),1),K2=f(ge(),1),J2=f(Z(),1);var gu=f(ue(),1),Q2=f(ge(),1),$2=f(Te(),1);var ov=f(Z(),1);var yu=f(Z(),1);var oE=f(Z(),1);var sE=f(ge(),1),sv=f(Dt(),1);var iv=f(Dt(),1),nE=f(Te(),1);var iE=f(Z(),1),{useSettingsForBlockElement:v9,DimensionsPanel:b9}=De(iv.privateApis);var vu=f(Z(),1),{useHasDimensionsPanel:E9,useSettingsForBlockElement:T9}=De(sv.privateApis);var dv=f(ue(),1),uE=f(ge(),1);var lE=f(ge(),1),cE=f(ue(),1);var av=f(sr(),1),lv=f(Kt(),1),Sa=f(Te(),1),cv=f(ue(),1),uv=f(ge(),1);var xa=f(Z(),1);function aE({gap:e=2}){let{user:t}=(0,Sa.useContext)(gt),r=t?.styles,n=(0,lv.useSelect)(s=>{let a=s(av.store).__experimentalGetCurrentThemeGlobalStylesVariations();return Array.isArray(a)?a:void 0},[])?.filter(s=>!yi(s,["color"])&&!yi(s,["typography","spacing"])),i=(0,Sa.useMemo)(()=>[...[{title:(0,uv.__)("Default"),settings:{},styles:{}},...n??[]].map(a=>{let u=a?.styles?.blocks?{...a.styles.blocks}:{};r?.blocks&&Object.keys(r.blocks).forEach(d=>{if(r.blocks?.[d]?.css){let h=u[d]||{},g={css:`${u[d]?.css||""} ${r.blocks?.[d]?.css?.trim()||""}`};u[d]={...h,...g}}});let l=r?.css||a.styles?.css?{css:`${a.styles?.css||""} ${r?.css||""}`}:{},c=Object.keys(u).length>0?{blocks:u}:{},m={...a.styles,...l,...c};return{...a,settings:a.settings??{},styles:m}})],[n,r?.blocks,r?.css]);return!n||n.length<1?null:(0,xa.jsx)(cv.__experimentalGrid,{columns:2,className:"global-styles-ui-style-variations-container",gap:e,children:i.map((s,a)=>(0,xa.jsx)(An,{variation:s,children:u=>(0,xa.jsx)(jc,{label:s?.title,withHoverView:!0,isFocused:u,variation:s})},a))})}var bu=aE;var fv=f(Z(),1);var wu=f(Z(),1);var fE=f(ge(),1),dE=f(ue(),1),pv=f(Dt(),1);var xu=f(Z(),1),{AdvancedPanel:G9}=De(pv.privateApis);var Sv=f(ge(),1),_u=f(ue(),1),Cu=f(Te(),1);var pE=f(Kt(),1),mE=f(sr(),1),mv=f(Te(),1);var yv=f(ge(),1),vv=f(ue(),1),_a=f(gv(),1),hE=f(sr(),1),gE=f(Kt(),1);var bv=f(Zc(),1);var wv=f(Z(),1),K9=3600*1e3*24;var Su=f(ue(),1),Oi=f(ge(),1);var xv=f(Z(),1);var Ru=f(Z(),1);var _v=f(ge(),1),Cv=f(ue(),1);var Rv=f(Z(),1);var Tv=f(ge(),1),ki=f(ue(),1),Pv=f(Te(),1);var vE=f(Dt(),1),bE=f(ge(),1);var wE=f(Z(),1);var io=f(ue(),1),Ev=f(Z(),1);var Eu=f(Z(),1);var Pu=f(Z(),1);var Ou=f(Z(),1);function Bn(e){return function({value:r,baseValue:o,onChange:n,...i}){return(0,Ou.jsx)(gi,{value:r,baseValue:o,onChange:n,children:(0,Ou.jsx)(e,{...i})})}}var CE=Bn(bu);var RE=Bn(ba);var EE=Bn(Xs);var jn=f(Z(),1);function ku({value:e,baseValue:t,onChange:r,activeTab:o="installed-fonts"}){let n;switch(o){case"upload-fonts":n=(0,jn.jsx)(pa,{});break;case"installed-fonts":n=(0,jn.jsx)(na,{});break;default:n=(0,jn.jsx)(sa,{slug:o})}return(0,jn.jsx)(gi,{value:e,baseValue:t,onChange:r,children:(0,jn.jsx)($s,{children:n})})}var Fv=f(ai()),{unlock:Fu}=(0,Fv.__dangerousOptInToUnstableAPIsOnlyForCoreModules)("I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.","@wordpress/font-list-route");if(typeof document<"u"&&!document.head.querySelector("style[data-wp-hash='cb0e994672']")){let e=document.createElement("style");e.setAttribute("data-wp-hash","cb0e994672"),e.appendChild(document.createTextNode('@media (min-width:782px){.font-library-modal.font-library-modal{width:65vw}}.font-library-modal .components-modal__header{border-bottom:none}.font-library-modal .components-modal__content{margin-bottom:90px;padding:0}.font-library-modal .font-library__subtitle{font-size:11px;font-weight:var(--wpds-typography-font-weight-emphasis,600);text-transform:uppercase}.font-library-modal__tab-panel{height:calc(100% - 50px)}.font-library__tabpanel-layout{display:flex;flex-direction:column;height:100%}.font-library__tabpanel-layout>div{flex-grow:1}.font-library__tabpanel-layout .font-library__loading{align-items:center;box-sizing:border-box;display:flex;height:100%;justify-content:center;left:0;padding-top:124px;position:absolute;top:0;width:100%}.font-library__footer,.font-library__tabpanel-layout .components-navigator-screen{padding:24px;width:100%}.font-library__footer{background-color:#fff;border-top:1px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);bottom:0;box-sizing:border-box;flex-grow:0!important;flex-shrink:0;height:90px;position:absolute}.font-library__page-selection{font-size:11px;font-weight:var(--wpds-typography-font-weight-emphasis,600);text-transform:uppercase}@media (min-width:600px){.font-library__page-selection .components-select-control__input{font-size:11px!important;font-weight:var(--wpds-typography-font-weight-emphasis,600)}}.font-library__search{width:240px}.font-library__fonts-title{font-size:11px;font-weight:var(--wpds-typography-font-weight-emphasis,600);margin-bottom:0;margin-top:0;text-transform:uppercase}.font-library__fonts-list{list-style:none;margin-bottom:0;margin-top:0;padding:0}.font-library__fonts-list-item{margin-bottom:0}.font-library__font-demo{position:relative}.font-library__font-card{border:1px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);box-sizing:border-box;height:auto!important;margin-top:-1px;padding:16px;width:100%}.font-library__font-card:hover{background-color:#f0f0f0}.font-library__font-card:focus{position:relative}.font-library__font-card .font-library__font-card__name{font-weight:700}.font-library__font-card .font-library__font-card__count{color:#757575}.font-library__font-card .font-library__font-variant_demo-image{display:block;height:24px;width:auto}@media not (prefers-reduced-motion){.font-library__font-card .font-library__font-variant_demo-image{transition:opacity var(--wpds-motion-duration-lg,.3s) var(--wpds-motion-easing-subtle,cubic-bezier(.15,0,.15,1))}}.font-library__font-card .font-library__font-variant_demo-image.is-loading{left:0;opacity:0;position:absolute;top:0}.font-library__font-card .font-library__font-variant-demo-skeleton{border-radius:var(--wpds-border-radius-sm,2px);height:24px}.font-library__font-card .font-library__font-variant_demo-text{flex-shrink:0;white-space:nowrap}@media not (prefers-reduced-motion){.font-library__font-card .font-library__font-variant_demo-text{transition:opacity .3s ease-in-out}}.font-library-modal__tablist-container{background:#fff;border-bottom:1px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);position:sticky;top:0;z-index:1}.font-library__upload-area{align-items:center;display:flex;height:256px!important;justify-content:center;width:100%}button.font-library__upload-area{background-color:#f0f0f0}.font-library__local-fonts{margin:24px auto;width:80%}.font-library__local-fonts .font-library__upload-area__text{color:#757575}.font-library__google-fonts-confirm{align-items:center;display:flex;justify-content:center;margin-top:64px}.font-library__google-fonts-confirm p{line-height:1.4}.font-library__google-fonts-confirm h2{font-size:1.2rem;font-weight:400}.font-library__google-fonts-confirm .components-card{padding:16px;width:400px}.font-library__google-fonts-confirm .components-button{justify-content:center;width:100%}.font-library__select-all{padding:16px 16px 16px 17px}.font-library__select-all .components-checkbox-control__label{padding-left:16px}.global-styles-ui-pagination .components-button.is-tertiary{height:32px;justify-content:center;width:32px}.global-styles-ui-screen-revisions__revisions-list{flex-grow:1;list-style:none;margin:0 16px 16px}.global-styles-ui-screen-revisions__revisions-list li{margin-bottom:0}.global-styles-ui-screen-revisions__revision-item{cursor:var(--wpds-cursor-control,pointer);display:flex;flex-direction:column;position:relative}.global-styles-ui-screen-revisions__revision-item[role=option]:active,.global-styles-ui-screen-revisions__revision-item[role=option]:focus{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid transparent}.global-styles-ui-screen-revisions__revision-item:hover{background:rgba(var(--wp-admin-theme-color--rgb),.04)}.global-styles-ui-screen-revisions__revision-item:hover .global-styles-ui-screen-revisions__date{color:var(--wp-admin-theme-color)}.global-styles-ui-screen-revisions__revision-item:after,.global-styles-ui-screen-revisions__revision-item:before{content:"\\a";display:block;position:absolute}.global-styles-ui-screen-revisions__revision-item:before{background:#ddd;border:4px solid transparent;border-radius:50%;height:8px;left:17px;top:18px;transform:translate(-50%,-50%);width:8px;z-index:1}.global-styles-ui-screen-revisions__revision-item[aria-selected=true]{background:rgba(var(--wp-admin-theme-color--rgb),.04);border-radius:2px;color:var(--wp-admin-theme-color);outline:3px solid transparent;outline-offset:-2px}.global-styles-ui-screen-revisions__revision-item[aria-selected=true] .global-styles-ui-screen-revisions__date{color:var(--wp-admin-theme-color)}.global-styles-ui-screen-revisions__revision-item[aria-selected=true]:before{background:var(--wp-admin-theme-color)}.global-styles-ui-screen-revisions__revision-item[aria-selected=true] .global-styles-ui-screen-revisions__changes>li,.global-styles-ui-screen-revisions__revision-item[aria-selected=true] .global-styles-ui-screen-revisions__meta{color:#1e1e1e}.global-styles-ui-screen-revisions__revision-item:after{border:.5px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);height:100%;left:16px;top:0;width:0}.global-styles-ui-screen-revisions__revision-item:first-child:after{top:18px}.global-styles-ui-screen-revisions__revision-item:last-child:after{height:18px}.global-styles-ui-screen-revisions__revision-item-wrapper{display:block;padding:12px 12px 4px 40px}.global-styles-ui-screen-revisions__active-badge,.global-styles-ui-screen-revisions__apply-button.is-primary{align-self:flex-start;margin:0 12px 12px 40px}.global-styles-ui-screen-revisions__changes,.global-styles-ui-screen-revisions__meta{color:#757575;font-size:12px}.global-styles-ui-screen-revisions__description{align-items:flex-start;display:flex;flex-direction:column;gap:8px}.global-styles-ui-screen-revisions__description .global-styles-ui-screen-revisions__date{font-size:12px;font-weight:var(--wpds-typography-font-weight-emphasis,600);text-transform:uppercase}.global-styles-ui-screen-revisions__meta{align-items:flex-start;display:flex;justify-content:start;margin-bottom:4px;text-align:left;width:100%}.global-styles-ui-screen-revisions__meta img{border-radius:100%;height:16px;margin-right:8px;width:16px}.global-styles-ui-screen-revisions__loading{margin:24px auto!important}.global-styles-ui-screen-revisions__changes{line-height:1.4;list-style:disc;margin-left:12px;text-align:left}.global-styles-ui-screen-revisions__changes li{margin-bottom:4px}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination{gap:2px;justify-content:space-between}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .edit-site-pagination__total{height:1px;left:-1000px;margin:-1px;overflow:hidden;position:absolute}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-text{font-size:12px;will-change:opacity}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-button.is-tertiary{color:#1e1e1e}.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-button.is-tertiary:disabled,.global-styles-ui-screen-revisions__pagination.global-styles-ui-screen-revisions__pagination .components-button.is-tertiary[aria-disabled=true]{color:#949494}.global-styles-ui-screen-revisions__footer{background:#fff;border-top:1px solid var(--wpds-color-stroke-surface-neutral,#dbdbdb);bottom:0;box-sizing:border-box;height:56px;min-width:100%;padding:12px;position:sticky;z-index:1}.global-styles-ui-variations_item{box-sizing:border-box;cursor:var(--wpds-cursor-control,pointer)}.global-styles-ui-variations_item .global-styles-ui-variations_item-preview{border-radius:2px;outline:1px solid rgba(0,0,0,.1);outline-offset:-1px;overflow:hidden;position:relative}@media not (prefers-reduced-motion){.global-styles-ui-variations_item .global-styles-ui-variations_item-preview{transition:outline .1s linear}}.global-styles-ui-variations_item .global-styles-ui-variations_item-preview.is-pill{height:32px}.global-styles-ui-variations_item .global-styles-ui-variations_item-preview.is-pill .block-editor-iframe__scale-container{overflow:hidden}.global-styles-ui-variations_item:not(.is-active):hover .global-styles-ui-variations_item-preview{outline-color:rgba(0,0,0,.3)}.global-styles-ui-variations_item.is-active .global-styles-ui-variations_item-preview,.global-styles-ui-variations_item:focus-visible .global-styles-ui-variations_item-preview{outline-color:#1e1e1e;outline-offset:1px;outline-width:var(--wp-admin-border-width-focus)}.global-styles-ui-variations_item:focus-visible .global-styles-ui-variations_item-preview{outline-color:var(--wp-admin-theme-color)}.global-styles-ui-preview__wrapper{display:block;max-width:100%;width:100%}.global-styles-ui-preview__wrapper.is-hoverable{cursor:var(--wpds-cursor-control,pointer)}.global-styles-ui-typography-preview{align-items:center;background:#f0f0f0;border-radius:2px;display:flex;justify-content:center;margin-bottom:20px;min-height:100px;overflow:hidden}.global-styles-ui-font-size__item{line-break:anywhere;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.global-styles-ui-font-size__item-value{color:#757575}.global-styles-ui-screen-typography__indicator{align-items:center;border-radius:2px;display:flex!important;font-size:14px;height:24px;justify-content:center;width:24px}.global-styles-ui-block-types-filter{margin-bottom:12px;padding:0 16px}.global-styles-ui-block-types-search{flex-grow:1}.global-styles-ui-block-types-item-list .global-styles-ui-block-types-item__icon{min-width:24px}.global-styles-ui-block-types-item-list__no-results{padding-top:16px}.global-styles-ui-block-types-item__indicator{background:var(--wp-admin-theme-color);border-radius:50%;flex:none;height:6px;margin-left:auto;width:6px}.global-styles-ui-screen-typography__font-variants-count{color:#757575}.global-styles-ui-font-families__manage-fonts{justify-content:center}.global-styles-ui-screen .color-block-support-panel{border-top:none;padding-left:0;padding-right:0;padding-top:0;row-gap:12px}.global-styles-ui-header{line-height:1.9!important;margin-bottom:0!important}.global-styles-ui-subtitle{font-size:11px!important;font-weight:var(--wpds-typography-font-weight-emphasis,600)!important;margin-bottom:0!important;text-transform:uppercase}.global-styles-ui-section-title{color:#2f2f2f;font-weight:var(--wpds-typography-font-weight-emphasis,600);line-height:1.2;margin:0;padding:16px 16px 0}.global-styles-ui-icon-with-current-color{fill:currentColor}.global-styles-ui__color-indicator-wrapper{flex-shrink:0;height:24px}.global-styles-ui__shadows-panel__options-container,.global-styles-ui__typography-panel__options-container{height:24px}.global-styles-ui__block-preview-panel{border:1px solid #ddd;border-radius:2px;overflow:hidden;position:relative;width:100%}.global-styles-ui__shadow-preview-panel{background-image:repeating-linear-gradient(45deg,#e0e0e0 25%,transparent 0,transparent 75%,#e0e0e0 0,#e0e0e0),repeating-linear-gradient(45deg,#e0e0e0 25%,transparent 0,transparent 75%,#e0e0e0 0,#e0e0e0);background-position:0 0,8px 8px;background-size:16px 16px;border:1px solid #ddd;border-radius:2px;height:144px;overflow:auto}.global-styles-ui__shadow-preview-panel .global-styles-ui__shadow-preview-block{background-color:#fff;border:1px solid #ddd;border-radius:2px;height:60px;width:60%}.global-styles-ui__shadow-editor__dropdown-content{width:280px}.global-styles-ui__shadow-editor-panel{margin-bottom:4px}.global-styles-ui__shadow-editor__dropdown{position:relative;width:100%}.global-styles-ui__shadow-editor__dropdown-toggle{border-radius:inherit;height:auto;padding-bottom:8px;padding-top:8px;text-align:left;width:100%}.global-styles-ui__shadow-editor__dropdown-toggle.is-open{background:#f0f0f0;color:var(--wp-admin-theme-color)}.global-styles-ui__shadow-editor__remove-button{opacity:0;position:absolute;right:8px;top:8px}.global-styles-ui__shadow-editor__dropdown-toggle:hover+.global-styles-ui__shadow-editor__remove-button,.global-styles-ui__shadow-editor__remove-button:focus,.global-styles-ui__shadow-editor__remove-button:hover{opacity:1}@media (hover:none){.global-styles-ui__shadow-editor__remove-button{opacity:1}}.global-styles-ui-screen-css{display:flex;flex:1 1 auto;flex-direction:column;margin:16px}.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel{flex:1 1 auto}.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel__custom-css-input,.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel__custom-css-input .components-base-control__field{display:flex;flex:1 1 auto;flex-direction:column}.global-styles-ui-screen-css .block-editor-global-styles-advanced-panel__custom-css-input textarea{flex:1 1 auto}.global-styles-ui-screen-css-help-link{display:inline-block;margin-top:8px}.global-styles-ui-screen-variations{border-top:1px solid #ddd;margin-top:16px}.global-styles-ui-screen-variations>*{margin:24px 16px}.global-styles-ui-sidebar__navigator-provider{height:100%}.global-styles-ui-sidebar__navigator-screen{display:flex;flex-direction:column;height:100%}.global-styles-ui-color-palette__tablist-container{border-bottom:1px solid #ddd}.global-styles-ui-color-palette__tablist{margin-bottom:-1px}.global-styles-ui-sidebar__navigator-screen .single-column{grid-column:span 1}.global-styles-ui-screen-root.global-styles-ui-screen-root,.global-styles-ui-screen-style-variations.global-styles-ui-screen-style-variations{background:unset;color:inherit}.global-styles-ui-sidebar__panel .block-editor-block-icon svg{fill:currentColor}.global-styles-ui-screen-root__active-style-tile.global-styles-ui-screen-root__active-style-tile,.global-styles-ui-screen-root__active-style-tile.global-styles-ui-screen-root__active-style-tile .global-styles-ui-screen-root__active-style-tile-preview{border-radius:2px}.global-styles-ui-screen-root__active-style-tile-preview{clip-path:border-box}.global-styles-ui-color-palette-panel,.global-styles-ui-duotone-palette-panel,.global-styles-ui-gradient-palette-panel{padding:16px}.font-library-page__content{background-color:var(--wpds-color-background-surface-neutral-strong,#fff);display:flex;flex-direction:column;flex-grow:1;min-height:0}.font-library-page:has(.font-library__footer) .font-library-page__content{padding-bottom:90px}.font-library-page__tablist{border-bottom:1px solid #f0f0f0;flex-shrink:0;padding:0 24px}.font-library-page__tab-panel{flex-grow:1;min-height:0;overflow:auto}')),document.head.appendChild(e)}var Pr=f(Z()),{Tabs:Ca}=Fu(Av.privateApis),{useGlobalStyles:TE}=Fu(Iv.privateApis);function PE(){let{records:e=[]}=(0,Ra.useEntityRecords)("root","fontCollection",{_fields:"slug,name,description"}),[t,r]=(0,Nv.useState)("installed-fonts"),{base:o,user:n,setUser:i,isReady:s}=TE(),a=(0,Lv.useSelect)(l=>l(Ra.store).canUser("create",{kind:"postType",name:"wp_font_family"}),[]);if(!s)return null;let u=[{id:"installed-fonts",title:(0,zn._x)("Library","Font library")}];return a&&(u.push({id:"upload-fonts",title:(0,zn._x)("Upload","noun")}),u.push(...(e||[]).map(({slug:l,name:c})=>({id:l,title:e&&e.length===1&&l==="google-fonts"?(0,zn.__)("Install Fonts"):c})))),(0,Pr.jsx)(hc,{title:(0,zn.__)("Fonts"),className:"font-library-page",children:(0,Pr.jsx)("div",{className:"font-library-page__content",children:(0,Pr.jsxs)(Ca,{selectedTabId:t,onSelect:l=>r(l),children:[(0,Pr.jsx)("div",{className:"font-library-page__tablist",children:(0,Pr.jsx)(Ca.TabList,{children:u.map(({id:l,title:c})=>(0,Pr.jsx)(Ca.Tab,{tabId:l,children:c},l))})}),u.map(({id:l})=>(0,Pr.jsx)(Ca.TabPanel,{tabId:l,focusable:!1,className:"font-library-page__tab-panel",children:(0,Pr.jsx)(ku,{value:n,baseValue:o,onChange:i,activeTab:l})},l))]})})})}function OE(){return(0,Pr.jsx)(PE,{})}var kE=OE;export{kE as stage}; /*! Bundled license information: use-sync-external-store/cjs/use-sync-external-store-shim.production.js: diff --git a/src/wp-includes/images/icon-library/arrow-down-left.svg b/src/wp-includes/images/icon-library/arrow-down-left.svg index af4f173f3988b..81581dceafb99 100644 --- a/src/wp-includes/images/icon-library/arrow-down-left.svg +++ b/src/wp-includes/images/icon-library/arrow-down-left.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/arrow-down-right.svg b/src/wp-includes/images/icon-library/arrow-down-right.svg index d8a31b6ed447a..e7435f7e8c979 100644 --- a/src/wp-includes/images/icon-library/arrow-down-right.svg +++ b/src/wp-includes/images/icon-library/arrow-down-right.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/arrow-down.svg b/src/wp-includes/images/icon-library/arrow-down.svg index ef8fdd02e3c9e..c32a6d28f6e4c 100644 --- a/src/wp-includes/images/icon-library/arrow-down.svg +++ b/src/wp-includes/images/icon-library/arrow-down.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/arrow-left.svg b/src/wp-includes/images/icon-library/arrow-left.svg index e2a3e95d405d1..5890d0d13ccda 100644 --- a/src/wp-includes/images/icon-library/arrow-left.svg +++ b/src/wp-includes/images/icon-library/arrow-left.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/arrow-right.svg b/src/wp-includes/images/icon-library/arrow-right.svg index 225418a59e24f..ab99d246cc925 100644 --- a/src/wp-includes/images/icon-library/arrow-right.svg +++ b/src/wp-includes/images/icon-library/arrow-right.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/arrow-up-left.svg b/src/wp-includes/images/icon-library/arrow-up-left.svg index 054ebcfe3755d..0f61d3d4f59ee 100644 --- a/src/wp-includes/images/icon-library/arrow-up-left.svg +++ b/src/wp-includes/images/icon-library/arrow-up-left.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/arrow-up-right.svg b/src/wp-includes/images/icon-library/arrow-up-right.svg index 6a8f3a4445980..d828f0fe648a0 100644 --- a/src/wp-includes/images/icon-library/arrow-up-right.svg +++ b/src/wp-includes/images/icon-library/arrow-up-right.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/arrow-up.svg b/src/wp-includes/images/icon-library/arrow-up.svg index 8e4e1dcbb5ca4..581102424165c 100644 --- a/src/wp-includes/images/icon-library/arrow-up.svg +++ b/src/wp-includes/images/icon-library/arrow-up.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/block-meta.svg b/src/wp-includes/images/icon-library/block-meta.svg index 88095ac76494c..3fad51d72e8f8 100644 --- a/src/wp-includes/images/icon-library/block-meta.svg +++ b/src/wp-includes/images/icon-library/block-meta.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/category.svg b/src/wp-includes/images/icon-library/category.svg index bb70f4a56a6a5..5dfaa1b2f9f5b 100644 --- a/src/wp-includes/images/icon-library/category.svg +++ b/src/wp-includes/images/icon-library/category.svg @@ -1,3 +1,6 @@ - - + + + + + diff --git a/src/wp-includes/images/icon-library/caution.svg b/src/wp-includes/images/icon-library/caution.svg index 11ab2d31d15f3..11ec7b1df426f 100644 --- a/src/wp-includes/images/icon-library/caution.svg +++ b/src/wp-includes/images/icon-library/caution.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/chart-bar.svg b/src/wp-includes/images/icon-library/chart-bar.svg index 5469b91d71508..813fcb5045d61 100644 --- a/src/wp-includes/images/icon-library/chart-bar.svg +++ b/src/wp-includes/images/icon-library/chart-bar.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/check.svg b/src/wp-includes/images/icon-library/check.svg index 9eaf43d2f4122..0a6f0a20d2f1b 100644 --- a/src/wp-includes/images/icon-library/check.svg +++ b/src/wp-includes/images/icon-library/check.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/chevron-down-small.svg b/src/wp-includes/images/icon-library/chevron-down-small.svg index 411c1c2bb266f..d7a727bd702c0 100644 --- a/src/wp-includes/images/icon-library/chevron-down-small.svg +++ b/src/wp-includes/images/icon-library/chevron-down-small.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/chevron-down.svg b/src/wp-includes/images/icon-library/chevron-down.svg index 2c4553d3cac28..d7c5227261d4d 100644 --- a/src/wp-includes/images/icon-library/chevron-down.svg +++ b/src/wp-includes/images/icon-library/chevron-down.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/chevron-left-small.svg b/src/wp-includes/images/icon-library/chevron-left-small.svg index d00996331ecb4..4fc8981f250eb 100644 --- a/src/wp-includes/images/icon-library/chevron-left-small.svg +++ b/src/wp-includes/images/icon-library/chevron-left-small.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/chevron-left.svg b/src/wp-includes/images/icon-library/chevron-left.svg index f1eeafd04a233..d7a40c2c1c7eb 100644 --- a/src/wp-includes/images/icon-library/chevron-left.svg +++ b/src/wp-includes/images/icon-library/chevron-left.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/chevron-right-small.svg b/src/wp-includes/images/icon-library/chevron-right-small.svg index e98c0fd7decc8..872d7494a6659 100644 --- a/src/wp-includes/images/icon-library/chevron-right-small.svg +++ b/src/wp-includes/images/icon-library/chevron-right-small.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/chevron-right.svg b/src/wp-includes/images/icon-library/chevron-right.svg index 6f521fc34f116..44c37174dd001 100644 --- a/src/wp-includes/images/icon-library/chevron-right.svg +++ b/src/wp-includes/images/icon-library/chevron-right.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/chevron-up-down.svg b/src/wp-includes/images/icon-library/chevron-up-down.svg index 28e96c3369d80..7253e57b8a8b7 100644 --- a/src/wp-includes/images/icon-library/chevron-up-down.svg +++ b/src/wp-includes/images/icon-library/chevron-up-down.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/chevron-up-small.svg b/src/wp-includes/images/icon-library/chevron-up-small.svg index 897cea7292c16..bee27a88a28f8 100644 --- a/src/wp-includes/images/icon-library/chevron-up-small.svg +++ b/src/wp-includes/images/icon-library/chevron-up-small.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/chevron-up.svg b/src/wp-includes/images/icon-library/chevron-up.svg index d19e61474c583..8afc261bc0592 100644 --- a/src/wp-includes/images/icon-library/chevron-up.svg +++ b/src/wp-includes/images/icon-library/chevron-up.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/cover.svg b/src/wp-includes/images/icon-library/cover.svg index 20587c08a45e2..0a45590c3a76b 100644 --- a/src/wp-includes/images/icon-library/cover.svg +++ b/src/wp-includes/images/icon-library/cover.svg @@ -1,3 +1,4 @@ - - + + + diff --git a/src/wp-includes/images/icon-library/create.svg b/src/wp-includes/images/icon-library/create.svg index 5b1e766f81993..18b49120fbb90 100644 --- a/src/wp-includes/images/icon-library/create.svg +++ b/src/wp-includes/images/icon-library/create.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/download.svg b/src/wp-includes/images/icon-library/download.svg index 783c301be5b24..d222df20da821 100644 --- a/src/wp-includes/images/icon-library/download.svg +++ b/src/wp-includes/images/icon-library/download.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/help.svg b/src/wp-includes/images/icon-library/help.svg index e4174a83fa7ac..85d465377f0d0 100644 --- a/src/wp-includes/images/icon-library/help.svg +++ b/src/wp-includes/images/icon-library/help.svg @@ -1,3 +1,4 @@ - - + + + diff --git a/src/wp-includes/images/icon-library/image.svg b/src/wp-includes/images/icon-library/image.svg index e3516dccbeef5..36aa667cdb6e1 100644 --- a/src/wp-includes/images/icon-library/image.svg +++ b/src/wp-includes/images/icon-library/image.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/info.svg b/src/wp-includes/images/icon-library/info.svg index c33d9dc59689b..ebd757078da72 100644 --- a/src/wp-includes/images/icon-library/info.svg +++ b/src/wp-includes/images/icon-library/info.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/menu.svg b/src/wp-includes/images/icon-library/menu.svg index c911e7b176242..2564551e038fd 100644 --- a/src/wp-includes/images/icon-library/menu.svg +++ b/src/wp-includes/images/icon-library/menu.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/next.svg b/src/wp-includes/images/icon-library/next.svg index c7f3c872176b3..9c436f08d79dc 100644 --- a/src/wp-includes/images/icon-library/next.svg +++ b/src/wp-includes/images/icon-library/next.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/paragraph.svg b/src/wp-includes/images/icon-library/paragraph.svg index 2a6681576be80..b76197865e9d7 100644 --- a/src/wp-includes/images/icon-library/paragraph.svg +++ b/src/wp-includes/images/icon-library/paragraph.svg @@ -1,3 +1,4 @@ - - + + + diff --git a/src/wp-includes/images/icon-library/plus-circle.svg b/src/wp-includes/images/icon-library/plus-circle.svg index b6c6ecbd74ef1..c03320908c329 100644 --- a/src/wp-includes/images/icon-library/plus-circle.svg +++ b/src/wp-includes/images/icon-library/plus-circle.svg @@ -1,3 +1,4 @@ - - + + + diff --git a/src/wp-includes/images/icon-library/plus.svg b/src/wp-includes/images/icon-library/plus.svg index 555d8c2e0125e..13ab663720dc1 100644 --- a/src/wp-includes/images/icon-library/plus.svg +++ b/src/wp-includes/images/icon-library/plus.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/previous.svg b/src/wp-includes/images/icon-library/previous.svg index e986f1d5064c8..6213f948de87e 100644 --- a/src/wp-includes/images/icon-library/previous.svg +++ b/src/wp-includes/images/icon-library/previous.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/published.svg b/src/wp-includes/images/icon-library/published.svg index 6f5ad1027d8d1..534c6282f33a9 100644 --- a/src/wp-includes/images/icon-library/published.svg +++ b/src/wp-includes/images/icon-library/published.svg @@ -1,3 +1,4 @@ - - + + + diff --git a/src/wp-includes/images/icon-library/rss.svg b/src/wp-includes/images/icon-library/rss.svg index 4906420f5edbe..a6dcd21385bd5 100644 --- a/src/wp-includes/images/icon-library/rss.svg +++ b/src/wp-includes/images/icon-library/rss.svg @@ -1,3 +1,4 @@ - - + + + diff --git a/src/wp-includes/images/icon-library/scheduled.svg b/src/wp-includes/images/icon-library/scheduled.svg index a0d26f8adb8b0..d2b32b43f7de8 100644 --- a/src/wp-includes/images/icon-library/scheduled.svg +++ b/src/wp-includes/images/icon-library/scheduled.svg @@ -1,3 +1,4 @@ - - + + + diff --git a/src/wp-includes/images/icon-library/search.svg b/src/wp-includes/images/icon-library/search.svg index 5cae09d19eebf..e1c49101f6433 100644 --- a/src/wp-includes/images/icon-library/search.svg +++ b/src/wp-includes/images/icon-library/search.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/star-empty.svg b/src/wp-includes/images/icon-library/star-empty.svg index 9f18b42ce0830..8137f625c22f9 100644 --- a/src/wp-includes/images/icon-library/star-empty.svg +++ b/src/wp-includes/images/icon-library/star-empty.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/star-filled.svg b/src/wp-includes/images/icon-library/star-filled.svg index 9343997cdb066..4c407ff2cc1ea 100644 --- a/src/wp-includes/images/icon-library/star-filled.svg +++ b/src/wp-includes/images/icon-library/star-filled.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/star-half.svg b/src/wp-includes/images/icon-library/star-half.svg index 813d3e1c7276d..391acb64a7492 100644 --- a/src/wp-includes/images/icon-library/star-half.svg +++ b/src/wp-includes/images/icon-library/star-half.svg @@ -1,3 +1,4 @@ - - + + + diff --git a/src/wp-includes/images/icon-library/styles.svg b/src/wp-includes/images/icon-library/styles.svg index d9dddbd2e41b8..e3d2906a27248 100644 --- a/src/wp-includes/images/icon-library/styles.svg +++ b/src/wp-includes/images/icon-library/styles.svg @@ -1,3 +1,4 @@ - - + + + diff --git a/src/wp-includes/images/icon-library/tip.svg b/src/wp-includes/images/icon-library/tip.svg index 79fdb4c1f25d5..c698691bbeaa4 100644 --- a/src/wp-includes/images/icon-library/tip.svg +++ b/src/wp-includes/images/icon-library/tip.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/wp-includes/images/icon-library/upload.svg b/src/wp-includes/images/icon-library/upload.svg index 0af97ce70f172..0b797bcf3e5fa 100644 --- a/src/wp-includes/images/icon-library/upload.svg +++ b/src/wp-includes/images/icon-library/upload.svg @@ -1,3 +1,3 @@ - - + + From 62439bbb0ae8dc2e73f32bd42372a356e8ea55c1 Mon Sep 17 00:00:00 2001 From: Jonathan Desrosiers Date: Tue, 8 Sep 2026 16:55:39 +0000 Subject: [PATCH 437/634] Build/Test Tools: Upgrade Node.js to 24.x. This updates the minimum required version of Node.js in Core to `24.18.0`. Gutenberg has already been bumped, and the `gutenberg.sha` value is being updated to point to the corresponding merge commit. The Twenty Nineteen and Twenty Twenty themes are remaining on 20.x and 16.x for the time being until a compatibility issue in each dependency tree can be resolved. Props desrosj, manzoorwanijk, ciampo, SirLouen, jsnajdr, aduth, barry, mukesh27, jonsurrell. git-svn-id: https://develop.svn.wordpress.org/trunk@63539 602fd350-edb4-49c9-b593-d223f7449a82 --- .nvmrc | 2 +- package-lock.json | 4 ++-- package.json | 6 +++--- src/wp-content/themes/twentytwentyfive/.nvmrc | 2 +- .../themes/twentytwentyfive/package-lock.json | 7 ++----- src/wp-content/themes/twentytwentyfive/package.json | 12 ++++++------ src/wp-content/themes/twentytwentyone/.nvmrc | 2 +- .../themes/twentytwentyone/package-lock.json | 4 ++-- src/wp-content/themes/twentytwentyone/package.json | 4 ++-- src/wp-content/themes/twentytwentytwo/.nvmrc | 2 +- .../themes/twentytwentytwo/package-lock.json | 7 ++----- src/wp-content/themes/twentytwentytwo/package.json | 4 ++-- 12 files changed, 25 insertions(+), 31 deletions(-) diff --git a/.nvmrc b/.nvmrc index 209e3ef4b6247..82d5d714347ef 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -20 +24.18 diff --git a/package-lock.json b/package-lock.json index f1d7ebd89b2c4..fd069ad47879c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -95,8 +95,8 @@ "webpack": "5.108.4" }, "engines": { - "node": ">=20.10.0", - "npm": ">=10.2.3" + "node": ">=24.18.0", + "npm": ">=11.16.0" } }, "node_modules/@asamuzakjp/css-color": { diff --git a/package.json b/package.json index 7c9e99a625534..ca760568737a3 100644 --- a/package.json +++ b/package.json @@ -7,12 +7,12 @@ "url": "https://develop.svn.wordpress.org/trunk" }, "gutenberg": { - "sha": "5a4cc502d43016f1efa66f8f6d9bd3bb4bb24d85", + "sha": "5715a61334c4d29f21b67cf34b46061dc1b62502", "ghcrRepo": "WordPress/gutenberg/gutenberg-wp-develop-build" }, "engines": { - "node": ">=20.10.0", - "npm": ">=10.2.3" + "node": ">=24.18.0", + "npm": ">=11.16.0" }, "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/src/wp-content/themes/twentytwentyfive/.nvmrc b/src/wp-content/themes/twentytwentyfive/.nvmrc index 209e3ef4b6247..82d5d714347ef 100644 --- a/src/wp-content/themes/twentytwentyfive/.nvmrc +++ b/src/wp-content/themes/twentytwentyfive/.nvmrc @@ -1 +1 @@ -20 +24.18 diff --git a/src/wp-content/themes/twentytwentyfive/package-lock.json b/src/wp-content/themes/twentytwentyfive/package-lock.json index 3e364a3c43d01..26fc86bf03862 100644 --- a/src/wp-content/themes/twentytwentyfive/package-lock.json +++ b/src/wp-content/themes/twentytwentyfive/package-lock.json @@ -15,8 +15,8 @@ "postcss-cli": "^11.0.1" }, "engines": { - "node": ">=20.10.0", - "npm": ">=10.2.3" + "node": ">=24.18.0", + "npm": ">=11.16.0" } }, "node_modules/@wordpress/browserslist-config": { @@ -133,7 +133,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", @@ -825,7 +824,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -1582,7 +1580,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, diff --git a/src/wp-content/themes/twentytwentyfive/package.json b/src/wp-content/themes/twentytwentyfive/package.json index 9da89b58c35e0..04dab98c23949 100644 --- a/src/wp-content/themes/twentytwentyfive/package.json +++ b/src/wp-content/themes/twentytwentyfive/package.json @@ -13,8 +13,8 @@ }, "homepage": "https://wordpress.org/themes/twentytwentyfive/", "engines": { - "node": ">=20.10.0", - "npm": ">=10.2.3" + "node": ">=24.18.0", + "npm": ">=11.16.0" }, "devDependencies": { "@wordpress/browserslist-config": "^6.34.0", @@ -25,8 +25,8 @@ "browserslist": [ "extends @wordpress/browserslist-config" ], - "scripts": { - "build": "postcss style.css --use cssnano -o style.min.css --no-map", - "watch": "postcss style.css --use cssnano -o style.min.css --no-map --watch" - } + "scripts": { + "build": "postcss style.css --use cssnano -o style.min.css --no-map", + "watch": "postcss style.css --use cssnano -o style.min.css --no-map --watch" + } } diff --git a/src/wp-content/themes/twentytwentyone/.nvmrc b/src/wp-content/themes/twentytwentyone/.nvmrc index 209e3ef4b6247..82d5d714347ef 100644 --- a/src/wp-content/themes/twentytwentyone/.nvmrc +++ b/src/wp-content/themes/twentytwentyone/.nvmrc @@ -1 +1 @@ -20 +24.18 diff --git a/src/wp-content/themes/twentytwentyone/package-lock.json b/src/wp-content/themes/twentytwentyone/package-lock.json index c91af0fd29418..947acba18edcc 100644 --- a/src/wp-content/themes/twentytwentyone/package-lock.json +++ b/src/wp-content/themes/twentytwentyone/package-lock.json @@ -33,8 +33,8 @@ "stylelint-config-recommended-scss": "^16.0.2" }, "engines": { - "node": ">=20.10.0", - "npm": ">=10.2.3" + "node": ">=24.18.0", + "npm": ">=11.16.0" } }, "node_modules/@aashutoshrathi/word-wrap": { diff --git a/src/wp-content/themes/twentytwentyone/package.json b/src/wp-content/themes/twentytwentyone/package.json index 2e546c99eb612..7097e3f65f70f 100644 --- a/src/wp-content/themes/twentytwentyone/package.json +++ b/src/wp-content/themes/twentytwentyone/package.json @@ -13,8 +13,8 @@ }, "homepage": "https://wordpress.org/themes/twentytwentyone/", "engines": { - "node": ">=20.10.0", - "npm": ">=10.2.3" + "node": ">=24.18.0", + "npm": ">=11.16.0" }, "devDependencies": { "@wordpress/browserslist-config": "^6.34.0", diff --git a/src/wp-content/themes/twentytwentytwo/.nvmrc b/src/wp-content/themes/twentytwentytwo/.nvmrc index 209e3ef4b6247..82d5d714347ef 100644 --- a/src/wp-content/themes/twentytwentytwo/.nvmrc +++ b/src/wp-content/themes/twentytwentytwo/.nvmrc @@ -1 +1 @@ -20 +24.18 diff --git a/src/wp-content/themes/twentytwentytwo/package-lock.json b/src/wp-content/themes/twentytwentytwo/package-lock.json index 8d0f405241eb9..ffde012248aad 100644 --- a/src/wp-content/themes/twentytwentytwo/package-lock.json +++ b/src/wp-content/themes/twentytwentytwo/package-lock.json @@ -15,8 +15,8 @@ "postcss-cli": "^11.0.1" }, "engines": { - "node": ">=20.10.0", - "npm": ">=10.2.3" + "node": ">=24.18.0", + "npm": ">=11.16.0" } }, "node_modules/@wordpress/browserslist-config": { @@ -133,7 +133,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", @@ -825,7 +824,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -1582,7 +1580,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, diff --git a/src/wp-content/themes/twentytwentytwo/package.json b/src/wp-content/themes/twentytwentytwo/package.json index 842b94e80f1f1..b0b1a5e15f736 100644 --- a/src/wp-content/themes/twentytwentytwo/package.json +++ b/src/wp-content/themes/twentytwentytwo/package.json @@ -13,8 +13,8 @@ }, "homepage": "https://wordpress.org/themes/twentytwentytwo/", "engines": { - "node": ">=20.10.0", - "npm": ">=10.2.3" + "node": ">=24.18.0", + "npm": ">=11.16.0" }, "devDependencies": { "@wordpress/browserslist-config": "^6.34.0", From f03710d84744c509102c74e4a7e5149822bef26e Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 8 Sep 2026 18:35:49 +0000 Subject: [PATCH 438/634] Code Quality: Narrow the `esc_sql()` parameter and return types. Narrow the documented types of `esc_sql()` and `wpdb::_escape()` from `string|array` to `string|string[]`, since neither function is meant to operate on anything other than strings and flat arrays of strings. Add `@phpstan-` prefixed annotations with a key template and a conditional return type, so static analysis knows that a `string` yields a `string` and that an array yields an array of strings with its keys preserved. Developed in https://github.com/WordPress/wordpress-develop/pull/12975. Follow-up to r24986, r62672. Props johnbillion, westonruter, irozum. See #65817. git-svn-id: https://develop.svn.wordpress.org/trunk@63540 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/class-wpdb.php | 15 +++++++++++++-- src/wp-includes/formatting.php | 8 ++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/class-wpdb.php b/src/wp-includes/class-wpdb.php index 5cf9508f8fbdf..869111efd0797 100644 --- a/src/wp-includes/class-wpdb.php +++ b/src/wp-includes/class-wpdb.php @@ -1291,12 +1291,23 @@ public function _real_escape( $data ) { /** * Escapes data. Works on arrays. * + * The `$data is string` case must come first in the conditional return type below. PHPStan + * does not treat the documented types as certain, so it still analyzes the nested + * `is_array()` check even though `$v` is a `string`, narrowing `$v` to `never` there. A + * `never` argument satisfies whichever case is tested first, so testing for `string` first + * makes the recursive call resolve to `string`. Testing for the array case first would + * instead resolve it to an array, widening `$data` and contradicting the return type. + * * @since 2.8.0 * * @uses wpdb::_real_escape() * - * @param string|array $data Data to escape. - * @return string|array Escaped data, in the same type as supplied. + * @param string|string[] $data Data to escape. + * @return string|string[] Escaped data, in the same type as supplied. + * + * @phpstan-template TKey of array-key + * @phpstan-param string|array $data + * @phpstan-return ( $data is string ? string : array ) */ public function _escape( $data ) { if ( is_array( $data ) ) { diff --git a/src/wp-includes/formatting.php b/src/wp-includes/formatting.php index b9d551d59d51b..abbf18c3b74d2 100644 --- a/src/wp-includes/formatting.php +++ b/src/wp-includes/formatting.php @@ -4521,8 +4521,12 @@ function _deep_replace( $search, $subject ) { * * @global wpdb $wpdb WordPress database abstraction object. * - * @param string|array $data Unescaped data. - * @return string|array Escaped data, in the same type as supplied. + * @param string|string[] $data Unescaped data. + * @return string|string[] Escaped data, in the same type as supplied. + * + * @phpstan-template TKey of array-key + * @phpstan-param string|array $data + * @phpstan-return ( $data is string ? string : array ) */ function esc_sql( $data ) { global $wpdb; From 40a1782bb916a2797b5e1397a6ada9a7794ca6f2 Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Tue, 8 Sep 2026 19:35:37 +0000 Subject: [PATCH 439/634] Code Modernization: Use the null coalescing assignment operator for registration argument defaults. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the “assign a default only if not already set” guard blocks in `WP_Post_Type::set_props()` and `WP_Taxonomy::set_props()` with the null coalescing assignment operator (`??=`). Both classes normalize their registration arguments with the same idiom, so the two methods now read identically. **Scope** This covers `WP_Post_Type::set_props()` and `WP_Taxonomy::set_props()` completely: every guard in those two methods that `??=` can express is converted, so the two methods are internally consistent rather than half-modernized. The same pattern exists elsewhere in core; that is left for separate follow-ups on the same ticket so each one stays reviewable. Developed in https://github.com/WordPress/wordpress-develop/pull/13418. Follow-up to r63443, r63501, r63509. Props Soean, westonruter. See #65823. git-svn-id: https://develop.svn.wordpress.org/trunk@63541 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/class-wp-post-type.php | 44 ++++++++------------------ src/wp-includes/class-wp-taxonomy.php | 20 +++--------- 2 files changed, 19 insertions(+), 45 deletions(-) diff --git a/src/wp-includes/class-wp-post-type.php b/src/wp-includes/class-wp-post-type.php index 88fecd08c868c..f1919062686d0 100644 --- a/src/wp-includes/class-wp-post-type.php +++ b/src/wp-includes/class-wp-post-type.php @@ -570,19 +570,13 @@ public function set_props( $args ) { $args['name'] = $this->name; // If not set, default to the setting for 'public'. - if ( null === $args['publicly_queryable'] ) { - $args['publicly_queryable'] = $args['public']; - } + $args['publicly_queryable'] ??= $args['public']; // If not set, default to the setting for 'public'. - if ( null === $args['show_ui'] ) { - $args['show_ui'] = $args['public']; - } + $args['show_ui'] ??= $args['public']; // If not set, default to the setting for 'public'. - if ( null === $args['embeddable'] ) { - $args['embeddable'] = $args['public']; - } + $args['embeddable'] ??= $args['public']; // If not set, default rest_namespace to wp/v2 if show_in_rest is true. if ( false === $args['rest_namespace'] && ! empty( $args['show_in_rest'] ) ) { @@ -595,19 +589,13 @@ public function set_props( $args ) { } // If not set, default to the setting for 'show_in_menu'. - if ( null === $args['show_in_admin_bar'] ) { - $args['show_in_admin_bar'] = (bool) $args['show_in_menu']; - } + $args['show_in_admin_bar'] ??= (bool) $args['show_in_menu']; // If not set, default to the setting for 'public'. - if ( null === $args['show_in_nav_menus'] ) { - $args['show_in_nav_menus'] = $args['public']; - } + $args['show_in_nav_menus'] ??= $args['public']; // If not set, default to true if not public, false if public. - if ( null === $args['exclude_from_search'] ) { - $args['exclude_from_search'] = ! $args['public']; - } + $args['exclude_from_search'] ??= ! $args['public']; // Back compat with quirky handling in version 3.0. #14122. if ( empty( $args['capabilities'] ) @@ -617,9 +605,7 @@ public function set_props( $args ) { } // If not set, default to false. - if ( null === $args['map_meta_cap'] ) { - $args['map_meta_cap'] = false; - } + $args['map_meta_cap'] ??= false; // If there's no specified edit link and no UI, remove the edit link. if ( ! $args['show_ui'] && ! $has_edit_link ) { @@ -645,21 +631,19 @@ public function set_props( $args ) { if ( ! is_array( $args['rewrite'] ) ) { $args['rewrite'] = array(); } + if ( empty( $args['rewrite']['slug'] ) ) { $args['rewrite']['slug'] = $this->name; } - if ( ! isset( $args['rewrite']['with_front'] ) ) { - $args['rewrite']['with_front'] = true; - } - if ( ! isset( $args['rewrite']['pages'] ) ) { - $args['rewrite']['pages'] = true; - } + + $args['rewrite']['with_front'] ??= true; + $args['rewrite']['pages'] ??= true; + if ( ! isset( $args['rewrite']['feeds'] ) || ! $args['has_archive'] ) { $args['rewrite']['feeds'] = (bool) $args['has_archive']; } - if ( ! isset( $args['rewrite']['ep_mask'] ) ) { - $args['rewrite']['ep_mask'] = $args['permalink_epmask'] ?? EP_PERMALINK; - } + + $args['rewrite']['ep_mask'] ??= $args['permalink_epmask'] ?? EP_PERMALINK; } foreach ( $args as $property_name => $property_value ) { diff --git a/src/wp-includes/class-wp-taxonomy.php b/src/wp-includes/class-wp-taxonomy.php index 0c7ffa8c7d6dd..f44ce34a11def 100644 --- a/src/wp-includes/class-wp-taxonomy.php +++ b/src/wp-includes/class-wp-taxonomy.php @@ -376,9 +376,7 @@ public function set_props( $object_type, $args ) { $args = array_merge( $defaults, $args ); // If not set, default to the setting for 'public'. - if ( null === $args['publicly_queryable'] ) { - $args['publicly_queryable'] = $args['public']; - } + $args['publicly_queryable'] ??= $args['public']; if ( false !== $args['query_var'] && ( is_admin() || false !== $args['publicly_queryable'] ) ) { if ( true === $args['query_var'] ) { @@ -407,9 +405,7 @@ public function set_props( $object_type, $args ) { } // If not set, default to the setting for 'public'. - if ( null === $args['show_ui'] ) { - $args['show_ui'] = $args['public']; - } + $args['show_ui'] ??= $args['public']; // If not set, default to the setting for 'show_ui'. if ( null === $args['show_in_menu'] || ! $args['show_ui'] ) { @@ -417,19 +413,13 @@ public function set_props( $object_type, $args ) { } // If not set, default to the setting for 'public'. - if ( null === $args['show_in_nav_menus'] ) { - $args['show_in_nav_menus'] = $args['public']; - } + $args['show_in_nav_menus'] ??= $args['public']; // If not set, default to the setting for 'show_ui'. - if ( null === $args['show_tagcloud'] ) { - $args['show_tagcloud'] = $args['show_ui']; - } + $args['show_tagcloud'] ??= $args['show_ui']; // If not set, default to the setting for 'show_ui'. - if ( null === $args['show_in_quick_edit'] ) { - $args['show_in_quick_edit'] = $args['show_ui']; - } + $args['show_in_quick_edit'] ??= $args['show_ui']; // If not set, default rest_namespace to wp/v2 if show_in_rest is true. if ( false === $args['rest_namespace'] && ! empty( $args['show_in_rest'] ) ) { From ea146ac5205800a0ca9c87a2743856f5056ba092 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 8 Sep 2026 20:05:22 +0000 Subject: [PATCH 440/634] Code Quality: Remove redundant boolean sub-expressions. Each of three conditions re-tests something the surrounding expression has already established, so PHPStan reports the redundant operand as always true: 1. In `wp_render_typography_support()`, `! empty()` already requires the `fitText` attribute to be truthy, so a following truthiness check on the same value can never fail. 2. In `_get_block_templates_files()`, the right operand of an `||` is only evaluated when `! $post_type` was false, so a leading `$post_type &&` there is always true. 3. In `Walker::display_element()`, `$newlevel` is a local variable that is only ever assigned the literal `true`, so the truthiness test adds nothing to the `isset()`. All three are simplifications with no change in behavior. This resolves two `booleanAnd.rightAlwaysTrue` occurrences and one `booleanAnd.leftAlwaysTrue` occurrence, and the corresponding PHPStan baselines are regenerated. Developed in https://github.com/WordPress/wordpress-develop/pull/13086. Follow-up to r55687, r61246, r63023. Props tstokes8040. See #65817. git-svn-id: https://develop.svn.wordpress.org/trunk@63542 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/block-supports/typography.php | 2 +- src/wp-includes/block-template-utils.php | 2 +- src/wp-includes/class-wp-walker.php | 2 +- tests/phpstan/baselines/booleanAnd.leftAlwaysTrue.neon | 5 ----- .../phpstan/baselines/booleanAnd.rightAlwaysTrue.neon | 10 ---------- 5 files changed, 3 insertions(+), 18 deletions(-) diff --git a/src/wp-includes/block-supports/typography.php b/src/wp-includes/block-supports/typography.php index e99d0254fb43d..3e920f6b3daa8 100644 --- a/src/wp-includes/block-supports/typography.php +++ b/src/wp-includes/block-supports/typography.php @@ -304,7 +304,7 @@ function wp_typography_get_preset_inline_style_value( $style_value, $css_propert * @return string Filtered block content. */ function wp_render_typography_support( $block_content, $block ) { - if ( ! empty( $block['attrs']['fitText'] ) && $block['attrs']['fitText'] && ! is_admin() ) { + if ( ! empty( $block['attrs']['fitText'] ) && ! is_admin() ) { wp_enqueue_script_module( '@wordpress/block-editor/utils/fit-text-frontend' ); // Add Interactivity API directives for fit text to work with client-side navigation. diff --git a/src/wp-includes/block-template-utils.php b/src/wp-includes/block-template-utils.php index 4dcba75c6d8af..fa7a30edaeae3 100644 --- a/src/wp-includes/block-template-utils.php +++ b/src/wp-includes/block-template-utils.php @@ -459,7 +459,7 @@ function _get_block_templates_files( $template_type, $query = array() ) { if ( ! $post_type || - ( $post_type && isset( $candidate['postTypes'] ) && in_array( $post_type, $candidate['postTypes'], true ) ) + ( isset( $candidate['postTypes'] ) && in_array( $post_type, $candidate['postTypes'], true ) ) ) { $template_files[ $template_slug ] = $candidate; } diff --git a/src/wp-includes/class-wp-walker.php b/src/wp-includes/class-wp-walker.php index 7361520cbdccc..3937d5b89dff4 100644 --- a/src/wp-includes/class-wp-walker.php +++ b/src/wp-includes/class-wp-walker.php @@ -164,7 +164,7 @@ public function display_element( $element, &$children_elements, $max_depth, $dep unset( $children_elements[ $id ] ); } - if ( isset( $newlevel ) && $newlevel ) { + if ( isset( $newlevel ) ) { // End the child delimiter. $this->end_lvl( $output, $depth, ...array_values( $args ) ); } diff --git a/tests/phpstan/baselines/booleanAnd.leftAlwaysTrue.neon b/tests/phpstan/baselines/booleanAnd.leftAlwaysTrue.neon index c64a48177e085..69e4b48b16039 100644 --- a/tests/phpstan/baselines/booleanAnd.leftAlwaysTrue.neon +++ b/tests/phpstan/baselines/booleanAnd.leftAlwaysTrue.neon @@ -28,11 +28,6 @@ parameters: identifier: booleanAnd.leftAlwaysTrue count: 1 path: ../../../src/wp-admin/themes.php - - - message: '#^Left side of && is always true\.$#' - identifier: booleanAnd.leftAlwaysTrue - count: 1 - path: ../../../src/wp-includes/block-template-utils.php - message: '#^Left side of && is always true\.$#' identifier: booleanAnd.leftAlwaysTrue diff --git a/tests/phpstan/baselines/booleanAnd.rightAlwaysTrue.neon b/tests/phpstan/baselines/booleanAnd.rightAlwaysTrue.neon index 6bd091f5adffc..99d44e7b84f43 100644 --- a/tests/phpstan/baselines/booleanAnd.rightAlwaysTrue.neon +++ b/tests/phpstan/baselines/booleanAnd.rightAlwaysTrue.neon @@ -28,16 +28,6 @@ parameters: identifier: booleanAnd.rightAlwaysTrue count: 1 path: ../../../src/wp-content/themes/twentynineteen/header.php - - - message: '#^Right side of && is always true\.$#' - identifier: booleanAnd.rightAlwaysTrue - count: 1 - path: ../../../src/wp-includes/block-supports/typography.php - - - message: '#^Right side of && is always true\.$#' - identifier: booleanAnd.rightAlwaysTrue - count: 1 - path: ../../../src/wp-includes/class-wp-walker.php - message: '#^Right side of && is always true\.$#' identifier: booleanAnd.rightAlwaysTrue From 3e181d38c95bd8bf47b010c9e859a9f8d0c8c368 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Tue, 8 Sep 2026 21:08:30 +0000 Subject: [PATCH 441/634] Administration: Prevent errors in wp-tooltip.js on browsers without popover support. Add a feature gate so that the tooltip JS hides popover panels on browsers without popover support, and doesn't execute calls that can trigger errors. There are no browsers within the WordPress support matrix without popover support, but gating this feature gives users of older browsers a better experience with minimal change. Props wolf45, wildworks, adamsilverstein, joedolson. Fixes #65943. git-svn-id: https://develop.svn.wordpress.org/trunk@63543 602fd350-edb4-49c9-b593-d223f7449a82 --- src/js/_enqueues/wp/wp-tooltip.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/js/_enqueues/wp/wp-tooltip.js b/src/js/_enqueues/wp/wp-tooltip.js index 70fe2bfe7c1b2..87e4401e37fd2 100644 --- a/src/js/_enqueues/wp/wp-tooltip.js +++ b/src/js/_enqueues/wp/wp-tooltip.js @@ -8,6 +8,12 @@ */ (() => { + const supportsPopover = /** @type {boolean} */ ( Object.prototype.hasOwnProperty.call( HTMLElement.prototype, 'popover' ) ); + let hidePopover = false; + if ( ! supportsPopover ) { + hidePopover = true; + } + const popovers = /** @type {NodeListOf} */ ( document.querySelectorAll( '.wp-is-tooltip' ) ); /** @type {ReturnType} */ @@ -16,7 +22,11 @@ popovers.forEach( function( popover ) { const trigger = /** @type {HTMLButtonElement|HTMLAnchorElement|null} */ ( popover.querySelector( '.wp-tooltip__toggle' ) ); const panel = /** @type {HTMLSpanElement|null} */ ( popover.querySelector( 'span.wp-tooltip__bubble' ) ); + if ( hidePopover && panel ) { + panel.classList.add( 'hidden' ); + return; + } if ( ! trigger || ! panel ) { return; } From 46ab13cdec61c271787e83ac4831a59d58c7dff1 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Tue, 8 Sep 2026 21:30:28 +0000 Subject: [PATCH 442/634] Multisite: Restore missing user reassignment dropdown when deleting user. Explicitly pass the `blog_id` attribute to `wp_dropdown_users` in `confirm_delete_users()` so that the dropdown renders the list of users appropriate to the current site, rather than attempting to fallback to the main site despite the limits set by the `include` parameter, which limited to members of the subsite. This resulted in an empty list in any case where there was no overlap between members of the current subset and members of the primary network site. Props mgyura, johnbillion, adamsilverstein, joedolson. Fixes #66012. git-svn-id: https://develop.svn.wordpress.org/trunk@63544 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/includes/ms.php | 1 + tests/phpunit/tests/user/wpDropdownUsers.php | 39 ++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/wp-admin/includes/ms.php b/src/wp-admin/includes/ms.php index 56e17113653d2..155170aaf4f41 100644 --- a/src/wp-admin/includes/ms.php +++ b/src/wp-admin/includes/ms.php @@ -1003,6 +1003,7 @@ function confirm_delete_users( $users ) { 'include' => $blog_users, 'show' => 'display_name_with_login', 'id' => "reassign_user_{$details->userblog_id}_{$delete_user->ID}", + 'blog_id' => $details->userblog_id, ) ); ?> diff --git a/tests/phpunit/tests/user/wpDropdownUsers.php b/tests/phpunit/tests/user/wpDropdownUsers.php index a0b6501eb96d4..052dec318f896 100644 --- a/tests/phpunit/tests/user/wpDropdownUsers.php +++ b/tests/phpunit/tests/user/wpDropdownUsers.php @@ -201,4 +201,43 @@ public function test_role__not_in() { $this->assertStringNotContainsString( $u1->user_login, $found ); $this->assertStringContainsString( $u2->user_login, $found ); } + + /** + * @ticket 66012 + * @group ms-required + */ + public function test_multisite_users_in_blog_id() { + $blog_id = self::factory()->blog->create(); + $users = self::factory()->user->create_many( 2 ); + + add_user_to_blog( $blog_id, $users[0], 'author' ); + add_user_to_blog( $blog_id, $users[1], 'author' ); + + // The main site has no authors, so the dropdown should be empty. + $found_main_site = wp_dropdown_users( + array( + 'echo' => false, + 'role' => 'author', + 'show' => 'user_login', + 'blog_id' => get_current_blog_id(), + ) + ); + + $this->assertSame( '', $found_main_site ); + + $found_sub_site = wp_dropdown_users( + array( + 'echo' => false, + 'role' => 'author', + 'show' => 'user_login', + 'blog_id' => $blog_id, + ) + ); + + $user1 = get_userdata( $users[0] ); + $user2 = get_userdata( $users[1] ); + + $this->assertStringContainsString( $user1->user_login, $found_sub_site ); + $this->assertStringContainsString( $user2->user_login, $found_sub_site ); + } } From 2419dda9f396bf8d8d6c655a3939d072b7f7e362 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 8 Sep 2026 21:33:53 +0000 Subject: [PATCH 443/634] Administration: Wrap more one-liner inline scripts. Continuing the migration begun in r63481, the raw one-liner `SCRIPT` tags in `wp-admin/admin-footer.php`, `wp-admin/install.php` and `wp-admin/async-upload.php` now print through `wp_print_inline_script_tag()`, so `wp_inline_script_attributes` can attach a per-request nonce to these as well. The upload error handler is reworked in the process: 1. Its data now crosses into JavaScript as a single `wp_json_encode()` object rather than being interpolated into the script text, which also removes the raw interpolation of the dismiss button's generated `id`. 2. The jQuery object arrives as an argument instead of being read from the global scope four times. 3. `setTimeout()` replaces the lone `_.delay()` call, which was all the snippet wanted from Underscore. The two blocks that take an argument carry a JSDoc block naming its type, following the convention already used for the jQuery wrapper in `wp-admin/js`. These particular blocks are not reached by `lint:jsdoc`, which reads JavaScript files rather than heredocs embedded in PHP, but IDEs do check them. Developed in https://github.com/WordPress/wordpress-develop/pull/13393. Follow-up to r60263, r60520, r60681, r63481. Props thanhtinpk, westonruter. See #59446, #66033. git-svn-id: https://develop.svn.wordpress.org/trunk@63545 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/admin-footer.php | 10 +++++++++- src/wp-admin/async-upload.php | 37 ++++++++++++++++++++++++++++++++++- src/wp-admin/install.php | 29 +++++++++++++++++++-------- 3 files changed, 66 insertions(+), 10 deletions(-) diff --git a/src/wp-admin/admin-footer.php b/src/wp-admin/admin-footer.php index fef0c06bbf725..32f24e536e599 100644 --- a/src/wp-admin/admin-footer.php +++ b/src/wp-admin/admin-footer.php @@ -114,6 +114,14 @@ ?>
- + diff --git a/src/wp-admin/async-upload.php b/src/wp-admin/async-upload.php index 5fbdd370c5c1a..0bd955e5d0428 100644 --- a/src/wp-admin/async-upload.php +++ b/src/wp-admin/async-upload.php @@ -145,7 +145,42 @@ $_FILES['async-upload']['name'] ); - echo '\n"; + $js_function = <<<'JS' + /** + * Announces the upload failure and wires up its dismiss button. + * + * @param {JQueryStatic} $ The jQuery object. + * @param {Object} args PHP exports. + * @param {string} args.speakMessage Message announced to assistive technology. + * @param {string} args.buttonSelector Selector for the notice's dismiss button. + * @return {void} + */ + ( $, { speakMessage, buttonSelector } ) => { + setTimeout( () => wp.a11y.speak( speakMessage ), 1500 ); + $( buttonSelector ).on( 'click', function () { + $( this ) + .parents( 'div.media-item' ) + .slideUp( 200, function () { + $( this ).remove(); + wp.a11y.speak( wp.i18n.__( 'Error dismissed.' ) ); + $( '#plupload-browse-button' ).trigger( 'focus' ); + } ); + } ); + } + JS; + wp_print_inline_script_tag( + sprintf( + '( %s )( jQuery, %s )', + $js_function, + wp_json_encode( + array( + 'speakMessage' => $speak_message, + 'buttonSelector' => 'button#' . $button_unique_id, + ), + JSON_HEX_TAG | JSON_UNESCAPED_SLASHES + ) + ) + ); exit; } diff --git a/src/wp-admin/install.php b/src/wp-admin/install.php index b6b7a08f2a5aa..977e231cccdf1 100644 --- a/src/wp-admin/install.php +++ b/src/wp-admin/install.php @@ -470,17 +470,30 @@ function display_setup_form( $error = null ) { } if ( ! wp_is_mobile() ) { - ?> - - - From e075d868ac2dc42ea835302f93562d36e8596b4b Mon Sep 17 00:00:00 2001 From: Lance Willett Date: Wed, 9 Sep 2026 00:01:37 +0000 Subject: [PATCH 444/634] Tests: Remove unrelated option setup in REST settings test. Remove the `posts_per_page` update from `test_update_item_with_invalid_enum()`, which only checks rejection of an invalid default_ping_status value. Developed in: https://github.com/WordPress/wordpress-develop/pull/13450 Props wongjn. See #65819. git-svn-id: https://develop.svn.wordpress.org/trunk@63546 602fd350-edb4-49c9-b593-d223f7449a82 --- tests/phpunit/tests/rest-api/rest-settings-controller.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/phpunit/tests/rest-api/rest-settings-controller.php b/tests/phpunit/tests/rest-api/rest-settings-controller.php index 5bee862ef5247..153a898947fe7 100644 --- a/tests/phpunit/tests/rest-api/rest-settings-controller.php +++ b/tests/phpunit/tests/rest-api/rest-settings-controller.php @@ -683,8 +683,6 @@ public function test_update_item_with_null() { } public function test_update_item_with_invalid_enum() { - update_option( 'posts_per_page', 9 ); - wp_set_current_user( self::$administrator ); $request = new WP_REST_Request( 'PUT', '/wp/v2/settings' ); $request->set_param( 'default_ping_status', 'open&closed' ); From 447d765c17ecbd06edf523ef434987bb29bed9e0 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Wed, 9 Sep 2026 01:53:06 +0000 Subject: [PATCH 445/634] Administration: Prevent race condition in wp-tooltip.js delay timer. Move the timer variable `openTimeout` from the outer scope of the wrapper function to the inner scope, preventing reuse of the same timer instance by different tooltips. Props fahimmurshed, westonruter, joedolson. Fixes #65674. git-svn-id: https://develop.svn.wordpress.org/trunk@63549 602fd350-edb4-49c9-b593-d223f7449a82 --- src/js/_enqueues/wp/wp-tooltip.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/js/_enqueues/wp/wp-tooltip.js b/src/js/_enqueues/wp/wp-tooltip.js index 87e4401e37fd2..d00a0d5f6ae07 100644 --- a/src/js/_enqueues/wp/wp-tooltip.js +++ b/src/js/_enqueues/wp/wp-tooltip.js @@ -16,9 +16,6 @@ const popovers = /** @type {NodeListOf} */ ( document.querySelectorAll( '.wp-is-tooltip' ) ); - /** @type {ReturnType} */ - let openTimeout; - popovers.forEach( function( popover ) { const trigger = /** @type {HTMLButtonElement|HTMLAnchorElement|null} */ ( popover.querySelector( '.wp-tooltip__toggle' ) ); const panel = /** @type {HTMLSpanElement|null} */ ( popover.querySelector( 'span.wp-tooltip__bubble' ) ); @@ -31,6 +28,9 @@ return; } + /** @type {ReturnType} */ + let openTimeout; + // Show Tooltip Function (with delay to prevent flickering). const showTooltip = () => { clearTimeout( openTimeout ); From 08b0ba94f0e5050d23515742b36115994fff134e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= Date: Wed, 9 Sep 2026 08:37:26 +0000 Subject: [PATCH 446/634] View config: remove stale fields from wp_template. Props oandregal, ntsekouras. Part of #65981. git-svn-id: https://develop.svn.wordpress.org/trunk@63551 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/view-config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/view-config.php b/src/wp-includes/view-config.php index dd77063aff3f5..d972515c12438 100644 --- a/src/wp-includes/view-config.php +++ b/src/wp-includes/view-config.php @@ -566,7 +566,7 @@ function _wp_get_entity_view_config_posttype_wp_template( $data ) { 'titleField' => 'title', 'descriptionField' => 'description', 'mediaField' => 'preview', - 'fields' => array( 'author', 'active', 'slug', 'theme' ), + 'fields' => array( 'author' ), 'filters' => array(), 'showMedia' => true, ); From ad4aa65c0be41833a16160fb769591540702492d Mon Sep 17 00:00:00 2001 From: Marin Atanasov Date: Wed, 9 Sep 2026 09:49:57 +0000 Subject: [PATCH 447/634] Toolbar: Remove the light background behind the Admin Bar site icon. The site icon in the admin bar was given a `#f0f0f1` background to match the my-account (user avatar) node. Unlike avatars, which are always opaque, site icons are frequently transparent PNGs with a non-square shape, and the light square showed through them against the dark admin bar, breaking the icon's intended silhouette. Removing the background lets transparent icons blend into the toolbar. Opaque icons are unaffected, and icons that lack contrast against the admin bar are considered the site owner's responsibility, consistent with how a favicon must already work against varying browser chrome. Developed in https://github.com/WordPress/wordpress-develop/pull/13229 Props w3bdsgn, afercia, jorbin, audrasjb, r1k0, wildworks, sabernhardt, darshitrajyaguru97, fushar, ugyensupport, nkpathan, joen, adrianduffell, adamsilverstein, tyxla. Fixes #65924. git-svn-id: https://develop.svn.wordpress.org/trunk@63552 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/css/admin-bar.css | 1 - 1 file changed, 1 deletion(-) diff --git a/src/wp-includes/css/admin-bar.css b/src/wp-includes/css/admin-bar.css index ad8d2c286b805..e3d6412ce746c 100644 --- a/src/wp-includes/css/admin-bar.css +++ b/src/wp-includes/css/admin-bar.css @@ -593,7 +593,6 @@ html:lang(he-il) .rtl #wpadminbar * { #wpadminbar #wp-admin-bar-site-name > .ab-item .site-icon { width: 20px; height: 20px; - background: #f0f0f1; /* matching my-account (user avatar) node's background */ border-radius: 2px; } From 3290a8d5d3ecbf4c6b2d79a464c90fdd6ebcc151 Mon Sep 17 00:00:00 2001 From: Marin Atanasov Date: Wed, 9 Sep 2026 10:33:28 +0000 Subject: [PATCH 448/634] Toolbar: Prevent the site title from showing behind the site icon on narrow screens. Below 783px the Admin Bar hides each node's text label with `text-indent`, which has no effect on the site name node because setting a site icon makes it a flex container. Depending on the browser engine, the title then renders unindented and clipped, with the absolutely positioned icon drawn on top of it. Reset the node to a block container within the `max-width: 782px` media query. Flex serves no purpose there, as the icon is taken out of flow anyway. Developed in: https://github.com/WordPress/wordpress-develop/pull/13434 Props hbhalodia, jdab, audrasjb, adamsilverstein, fushar, tyxla. Fixes #66064. git-svn-id: https://develop.svn.wordpress.org/trunk@63554 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/css/admin-bar.css | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/wp-includes/css/admin-bar.css b/src/wp-includes/css/admin-bar.css index e3d6412ce746c..61f240be3a6f5 100644 --- a/src/wp-includes/css/admin-bar.css +++ b/src/wp-includes/css/admin-bar.css @@ -934,6 +934,14 @@ html:lang(he-il) .rtl #wpadminbar * { -moz-osx-font-smoothing: grayscale; } + /* + * Flex prevents `text-indent` from hiding the site title, and is unused here + * since the icon is positioned absolutely below. + */ + #wpadminbar #wp-admin-bar-site-name.has-site-icon > .ab-item { + display: block; + } + #wpadminbar #wp-admin-bar-site-name > .ab-item .site-icon { position: absolute; top: 9px; From eddb8539f8ff03ed6c052b48a972059b3a780c72 Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Wed, 9 Sep 2026 12:02:40 +0000 Subject: [PATCH 449/634] General: Add missing JS docblocks. Also, enables the JSDoc rule `jsdoc/require-jsdoc`. Part of the effort to improve JS inline documentation for 7.2. Developed in https://github.com/WordPress/wordpress-develop/pull/13439 Props afercia, westonruter. See #66033. git-svn-id: https://develop.svn.wordpress.org/trunk@63556 602fd350-edb4-49c9-b593-d223f7449a82 --- .eslintrc-jsdoc.js | 1 + Gruntfile.js | 33 +++++++++- src/js/_enqueues/admin/password-toggle.js | 9 ++- src/js/_enqueues/admin/plugin-install.js | 31 ++++++--- src/js/_enqueues/admin/privacy-tools.js | 76 +++++++++++++++++++++- src/js/_enqueues/admin/site-health.js | 15 ++++- src/js/_enqueues/admin/tags-suggest.js | 20 +++++- src/js/_enqueues/admin/user-profile.js | 31 +++++++++ src/js/_enqueues/lib/embed-template.js | 10 ++- src/js/_enqueues/lib/link.js | 14 +++- src/js/_enqueues/lib/nav-menu.js | 23 +++++++ src/js/_enqueues/lib/quicktags.js | 11 ++++ src/js/_enqueues/wp/api-request.js | 27 ++++++++ src/js/_enqueues/wp/autosave.js | 6 ++ src/js/_enqueues/wp/custom-header.js | 5 ++ src/js/_enqueues/wp/customize/controls.js | 70 +++++++++++++++++++- src/js/_enqueues/wp/customize/widgets.js | 5 ++ src/js/_enqueues/wp/editor/base.js | 9 +++ src/js/_enqueues/wp/editor/dfw.js | 12 ++++ src/js/_enqueues/wp/embed.js | 3 + src/js/_enqueues/wp/mce-view.js | 27 +++++++- src/js/_enqueues/wp/theme-plugin-editor.js | 24 ++++++- 22 files changed, 434 insertions(+), 28 deletions(-) diff --git a/.eslintrc-jsdoc.js b/.eslintrc-jsdoc.js index 34e10ed4b581e..12d2bf9a0922d 100644 --- a/.eslintrc-jsdoc.js +++ b/.eslintrc-jsdoc.js @@ -56,6 +56,7 @@ module.exports = [ 'jsdoc/require-returns-type': 'error', 'jsdoc/check-syntax': 'error', 'jsdoc/require-description': 'error', + 'jsdoc/require-jsdoc': 'error', }, }, ]; diff --git a/Gruntfile.js b/Gruntfile.js index 139cb6fb5b286..08da38fb748e2 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -154,7 +154,11 @@ module.exports = function(grunt) { ] }; - // Load grunt-* tasks. + /** + * Loads the Grunt tasks for the given dependency. + * + * @param {string} dependency The name of the Grunt task to load. + */ function loadGruntTasks( dependency ) { var contrib = key === 'contrib' ? 'contrib-' : ''; grunt.loadNpmTasks( 'grunt-' + contrib + dependency ); @@ -1797,6 +1801,11 @@ module.exports = function(grunt) { path.dirname( __dirname ) + '/.svn' ] ); + /** + * Searches for the first version control directory in the given set. + * + * @param {string[]} set Array of directory paths to check. + */ function find( set ) { var dir; @@ -1809,6 +1818,9 @@ module.exports = function(grunt) { } } + /** + * Runs all tasks. + */ function runAllTasks() { grunt.log.writeln( 'Cannot determine which files are modified as SVN and GIT are not available.' ); grunt.log.writeln( 'Running all tasks and all tests.' ); @@ -1824,6 +1836,11 @@ module.exports = function(grunt) { done(); } + /** + * Determines which precommit tasks to run based on modified files detected by version control. + * + * @param {string} type The version control type: 'git' or 'svn'. + */ function run( type ) { var command = map[ type ].split( ' ' ); @@ -1833,13 +1850,23 @@ module.exports = function(grunt) { }, function( error, result, code ) { var taskList = []; - // Callback for finding modified paths. + /** + * Checks if the given path appears in the version control status output. + * + * @param {string} path The path to check. + * @return {boolean} True if the path is found, false otherwise. + */ function testPath( path ) { var regex = new RegExp( ' ' + path + '$', 'm' ); return regex.test( result.stdout ); } - // Callback for finding modified files by extension. + /** + * Checks if files with the given extension appear in the version control status output. + * + * @param {string} extension The file extension to check for. + * @return {boolean} True if the file with the given extension is found, false otherwise. + */ function testExtension( extension ) { var regex = new RegExp( '\.' + extension + '$', 'm' ); return regex.test( result.stdout ); diff --git a/src/js/_enqueues/admin/password-toggle.js b/src/js/_enqueues/admin/password-toggle.js index 5bfaa3b122c01..bdd98f8bb7359 100644 --- a/src/js/_enqueues/admin/password-toggle.js +++ b/src/js/_enqueues/admin/password-toggle.js @@ -1,10 +1,12 @@ +/** + * @output wp-admin/js/password-toggle.js + */ + /** * Adds functionality for password visibility buttons to toggle between text and password input types. * * @since 6.3.0 - * @output wp-admin/js/password-toggle.js */ - ( function () { var toggleElements, status, input, icon, label, __ = wp.i18n.__; @@ -15,6 +17,9 @@ toggle.addEventListener( 'click', togglePassword ); } ); + /** + * Toggles the password input field visibility. + */ function togglePassword() { status = this.getAttribute( 'data-toggle' ); input = this.parentElement.children.namedItem( 'pwd' ); diff --git a/src/js/_enqueues/admin/plugin-install.js b/src/js/_enqueues/admin/plugin-install.js index 1e994763e1fda..b79931a7e7791 100644 --- a/src/js/_enqueues/admin/plugin-install.js +++ b/src/js/_enqueues/admin/plugin-install.js @@ -6,6 +6,11 @@ /* global tb_click, tb_remove, tb_position */ +/** + * Initializes the plugin install screens. + * + * @param {JQueryStatic} $ The jQuery object. + */ jQuery( function( $ ) { var tbWindow, @@ -78,6 +83,9 @@ jQuery( function( $ ) { $focusedBefore.trigger( 'focus' ); }); + /** + * Initializes the plugin details modal dialog after the iframe has fully loaded. + */ function iframeLoaded() { var $iframe = tbWindow.find( '#TB_iframeContent' ); @@ -109,8 +117,9 @@ jQuery( function( $ ) { }); } - /* - * Get the tabbable elements and detach/attach the keydown event. + /** + * Gets the tabbable elements and detaches/attaches the keydown event. + * * Called after the iframe has fully loaded so we have all the elements we need. * Called again each time a Tab gets clicked. * @todo Consider to implement a WordPress general utility for this and don't use jQuery UI. @@ -133,7 +142,11 @@ jQuery( function( $ ) { }); } - // Constrain tabbing within the plugin modal dialog. + /** + * Constrains tabbing within the plugin modal dialog. + * + * @param {JQuery.Event} event The keydown event. + */ function constrainTabbing( event ) { if ( 9 !== event.which ) { return; @@ -148,11 +161,13 @@ jQuery( function( $ ) { } } - /* - * Open the Plugin details modal. The event is delegated to get also the links - * in the plugins search tab, after the Ajax search rebuilds the HTML. It's - * delegated on the closest ancestor and not on the body to avoid conflicts - * with other handlers, see Trac ticket #43082. + /** + * Opens the Plugin details modal. + * + * The event is delegated to get also the links in the plugins search tab, + * after the Ajax search rebuilds the HTML. It's delegated on the closest + * ancestor and not on the body to avoid conflicts with other handlers, see + * Trac ticket #43082. */ $( '.wrap' ).on( 'click', '.thickbox.open-plugin-details-modal', function( e ) { // The `data-title` attribute is used only in the Plugin screens. diff --git a/src/js/_enqueues/admin/privacy-tools.js b/src/js/_enqueues/admin/privacy-tools.js index 480766ad051d7..df24538ffaefc 100644 --- a/src/js/_enqueues/admin/privacy-tools.js +++ b/src/js/_enqueues/admin/privacy-tools.js @@ -1,19 +1,34 @@ /** - * Interactions used by the User Privacy tools in WordPress. - * * @output wp-admin/js/privacy-tools.js */ -// Privacy request action handling. +/** + * Sets the interactions used by the User Privacy tools in WordPress. + * + * @param {jQueryStatic} $ The jQuery object. + */ jQuery( function( $ ) { var __ = wp.i18n.__, copiedNoticeTimeout; + /** + * Sets the state of the action. + * + * @param {jQuery} $action The action to set the state for. + * @param {string} state The state to set the action to. + * @return {void} + */ function setActionState( $action, state ) { $action.children().addClass( 'hidden' ); $action.children( '.' + state ).removeClass( 'hidden' ); } + /** + * Clears any results row after the request row. + * + * @param {jQuery} $requestRow The request row to clear results for. + * @return {void} + */ function clearResultsAfterRow( $requestRow ) { $requestRow.removeClass( 'has-request-results' ); @@ -22,6 +37,15 @@ jQuery( function( $ ) { } } + /** + * Appends a results row after the request row. + * + * @param {jQuery} $requestRow The request row to append the results after. + * @param {string} classes The classes to add to the results row. + * @param {string} summaryMessage The summary message to display in the results row. + * @param {string[]} additionalMessages Additional messages to display in the results row. + * @return {void} + */ function appendResultsAfterRow( $requestRow, classes, summaryMessage, additionalMessages ) { var itemList = '', resultRowClasses = 'request-results'; @@ -76,6 +100,12 @@ jQuery( function( $ ) { clearResultsAfterRow( $requestRow ); setExportProgress( 0 ); + /** + * Handles a successful export. + * + * @param {string} zipUrl The URL of the generated ZIP file, if available. + * @return {void} + */ function onExportDoneSuccess( zipUrl ) { var summaryMessage = __( 'This user’s personal data export link was sent.' ); @@ -96,6 +126,12 @@ jQuery( function( $ ) { setTimeout( function() { $rowActions.removeClass( 'processing' ); }, 500 ); } + /** + * Handles an export failure. + * + * @param {string} errorMessage The error message to display. + * @return {void} + */ function onExportFailure( errorMessage ) { var summaryMessage = __( 'An error occurred while attempting to export personal data.' ); @@ -108,6 +144,12 @@ jQuery( function( $ ) { setTimeout( function() { $rowActions.removeClass( 'processing' ); }, 500 ); } + /** + * Updates the progress of the export process. + * + * @param {number} exporterIndex The index of the exporter to process. + * @return {void} + */ function setExportProgress( exporterIndex ) { var progress = ( exportersCount > 0 ? exporterIndex / exportersCount : 0 ), progressString = Math.round( progress * 100 ).toString() + '%'; @@ -115,6 +157,13 @@ jQuery( function( $ ) { $progress.html( progressString ); } + /** + * Performs the next export request. + * + * @param {number} exporterIndex The index of the exporter to process. + * @param {number} pageIndex The index of the page to process for the current exporter. + * @return {void} + */ function doNextExport( exporterIndex, pageIndex ) { $.ajax( { @@ -181,6 +230,11 @@ jQuery( function( $ ) { clearResultsAfterRow( $requestRow ); setErasureProgress( 0 ); + /** + * Handles a successful erasure. + * + * @return {void} + */ function onErasureDoneSuccess() { var summaryMessage = __( 'No personal data was found for this user.' ), classes = 'notice-success'; @@ -207,6 +261,9 @@ jQuery( function( $ ) { setTimeout( function() { $rowActions.removeClass( 'processing' ); }, 500 ); } + /** + * Handles an erasure failure. + */ function onErasureFailure() { var summaryMessage = __( 'An error occurred while attempting to find and erase personal data.' ); @@ -217,6 +274,12 @@ jQuery( function( $ ) { setTimeout( function() { $rowActions.removeClass( 'processing' ); }, 500 ); } + /** + * Updates the progress of the erasure process. + * + * @param {number} eraserIndex The index of the eraser to process. + * @return {void} + */ function setErasureProgress( eraserIndex ) { var progress = ( erasersCount > 0 ? eraserIndex / erasersCount : 0 ), progressString = Math.round( progress * 100 ).toString() + '%'; @@ -224,6 +287,13 @@ jQuery( function( $ ) { $progress.html( progressString ); } + /** + * Performs the next erasure request. + * + * @param {number} eraserIndex The index of the eraser to process. + * @param {number} pageIndex The index of the page to process for the current eraser. + * @return {void} + */ function doNextErasure( eraserIndex, pageIndex ) { $.ajax({ url: window.ajaxurl, diff --git a/src/js/_enqueues/admin/site-health.js b/src/js/_enqueues/admin/site-health.js index 98aaedc427c0e..dc9107a3ebc2f 100644 --- a/src/js/_enqueues/admin/site-health.js +++ b/src/js/_enqueues/admin/site-health.js @@ -1,11 +1,14 @@ /** - * Interactions used by the Site Health modules in WordPress. - * * @output wp-admin/js/site-health.js */ /* global ajaxurl, ClipboardJS, SiteHealth, wp */ +/** + * Handles the interactions used by the Site Health modules in WordPress. + * + * @param {JQueryStatic} $ The jQuery object. + */ jQuery( function( $ ) { var __ = wp.i18n.__, @@ -393,6 +396,9 @@ jQuery( function( $ ) { } } + /** + * Get the sizes of the directories in the Site Health Info section. + */ function getDirectorySizes() { var timestamp = ( new Date().getTime() ); @@ -434,6 +440,11 @@ jQuery( function( $ ) { } ); } + /** + * Updates the directory sizes in the Site Health Info section. + * + * @param {Object} data The directory sizes data. + */ function updateDirSizes( data ) { var copyButton = $( 'button.button.copy-button' ); var clipboardText = copyButton.attr( 'data-clipboard-text' ); diff --git a/src/js/_enqueues/admin/tags-suggest.js b/src/js/_enqueues/admin/tags-suggest.js index 08bea1464bbbe..e7469cfea2286 100644 --- a/src/js/_enqueues/admin/tags-suggest.js +++ b/src/js/_enqueues/admin/tags-suggest.js @@ -1,7 +1,9 @@ /** - * Default settings for jQuery UI Autocomplete for use with non-hierarchical taxonomies. - * * @output wp-admin/js/tags-suggest.js + */ + +/** + * Default settings for jQuery UI Autocomplete for use with non-hierarchical taxonomies. * * @param {JQueryStatic} $ The jQuery object. */ @@ -12,16 +14,28 @@ _n = wp.i18n._n, sprintf = wp.i18n.sprintf; + /** + * Splits a string into an array of terms based on the separator. + * + * @param {string} val The string to split. + * @return {string[]} An array of terms. + */ function split( val ) { return val.split( new RegExp( separator + '\\s*' ) ); } + /** + * Gets the last term from a string based on the separator. + * + * @param {string} term The string to get the last term from. + * @return {string} The last term. + */ function getLast( term ) { return split( term ).pop(); } /** - * Add UI Autocomplete to an input or textarea element with presets for use + * Adds UI Autocomplete to an input or textarea element with presets for use * with non-hierarchical taxonomies. * * Example: `$( element ).wpTagsSuggest( options )`. diff --git a/src/js/_enqueues/admin/user-profile.js b/src/js/_enqueues/admin/user-profile.js index e6b79f616fbc3..dc0b5e8ccd6e0 100644 --- a/src/js/_enqueues/admin/user-profile.js +++ b/src/js/_enqueues/admin/user-profile.js @@ -32,6 +32,17 @@ isSafari = window.safari !== 'undefined' && typeof window.safari === 'object', isFirefox = ua.indexOf( 'firefox' ) !== -1; + /** + * Generates a password and updates the password input field. + * + * If zxcvbn is not yet loaded, it will wait and try again. If the password + * input field is empty or the password wrapper is open, it will set the + * password to the generated value. If the user has already entered a + * password, it will check the strength of that password. It also binds + * the toggle button to show or hide the password and sets the initial state + * of the toggle button based on whether the password should be masked or + * not. Finally, it updates the label for confirming weak passwords. + */ function generatePassword() { if ( typeof zxcvbn !== 'function' ) { setTimeout( generatePassword, 50 ); @@ -67,6 +78,9 @@ $( '#pw-weak-text-label' ).text( __( 'Confirm use of weak password' ) ); } + /** + * Binds the password input field to update the current password and refresh the password strength area when the user types in the field. + */ function bindPass1() { currentPass = $pass1.val(); @@ -89,6 +103,11 @@ bindCapsLockWarning( $pass1 ); } + /** + * Resets the toggle button to show or hide the password. + * + * @param {boolean} show Whether to show the password or not. + */ function resetToggle( show ) { $toggleButton .attr({ @@ -102,6 +121,9 @@ .addClass( show ? 'dashicons-visibility' : 'dashicons-hidden' ); } + /** + * Binds the toggle button to show or hide the password. Also ensures that the password input type is set to password when the form is submitted. + */ function bindToggleButton() { if ( !! $toggleButton ) { // Do not rebind. @@ -193,6 +215,9 @@ $this.before( resultDiv ); } + /** + * Initializes the password form, including the password strength meter, weak password checkbox, and show/hide password toggle button. + */ function bindPasswordForm() { var $generateButton, $cancelButton; @@ -309,6 +334,9 @@ }); } + /** + * Sets CSS classes to the password strength results based on the password strength. + */ function check_pass_strength() { var pass1 = $('#pass1').val(), strength; @@ -414,6 +442,9 @@ return event.getModifierState( 'CapsLock' ); } + /** + * Toggles the visibility of the weak password checkbox. + */ function showOrHideWeakPasswordCheckbox() { var passStrengthResult = $('#pass-strength-result'); diff --git a/src/js/_enqueues/lib/embed-template.js b/src/js/_enqueues/lib/embed-template.js index b053be7cc88ee..e43ef97b8fe96 100644 --- a/src/js/_enqueues/lib/embed-template.js +++ b/src/js/_enqueues/lib/embed-template.js @@ -5,8 +5,8 @@ /** * IIFE setup function. * - * @param {Window} window Global window object. - * @param {Document} document Global document object. + * @param {Window} window The global window object. + * @param {Document} document The global document object. */ (function ( window, document ) { 'use strict'; @@ -17,6 +17,12 @@ secretTimeout, resizing; + /** + * Sends a message to the parent window. + * + * @param {string} message The message type (e.g., 'height', 'link'). + * @param {*} value The message value. Type depends on message (number for height, string for link). + */ function sendEmbedMessage( message, value ) { window.parent.postMessage( { message: message, diff --git a/src/js/_enqueues/lib/link.js b/src/js/_enqueues/lib/link.js index a2500a9069648..0d1a5a923e978 100644 --- a/src/js/_enqueues/lib/link.js +++ b/src/js/_enqueues/lib/link.js @@ -2,8 +2,15 @@ * @output wp-includes/js/wplink.js */ - /* global wpLink */ +/* global wpLink */ +/** + * The WordPress Link Modal dialog. + * + * @param {JQueryStatic} $ The jQuery object. + * @param {Object} wpLinkL10n The WordPress Link localization object. + * @param {Object} wp The WordPress global object. + */ ( function( $, wpLinkL10n, wp ) { var editor, searchTimer, River, Query, correctedURL, emailRegexp = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,63}$/i, @@ -12,6 +19,11 @@ rivers = {}, isTouch = ( 'ontouchend' in document ); + /** + * Gets the currently selected link in the editor. + * + * @return {JQuery} The currently selected link element. + */ function getLink() { if ( editor ) { return editor.$( 'a[data-wplink-edit="true"]' ); diff --git a/src/js/_enqueues/lib/nav-menu.js b/src/js/_enqueues/lib/nav-menu.js index f70ca7c99fe3a..5e94a2b34f3c9 100644 --- a/src/js/_enqueues/lib/nav-menu.js +++ b/src/js/_enqueues/lib/nav-menu.js @@ -1013,6 +1013,11 @@ } }); + /** + * Updates the shared variables used to determine the depth of the menu item being moved. + * + * @param {Object} ui The jQuery UI object for the menu item being moved. + */ function updateSharedVars(ui) { var depth; @@ -1033,17 +1038,35 @@ maxDepth = 0; } + /** + * Updates the current depth of the menu item being moved. + * + * @param {Object} ui The jQuery UI object for the menu item being moved. + * @param {number} depth The new depth of the menu item being moved. + * @return {void} + */ function updateCurrentDepth(ui, depth) { ui.placeholder.updateDepthClass( depth, currentDepth ); currentDepth = depth; } + /** + * Determines the initial menu max depth class on the body element. + * + * @return {number} The initial menu max depth. + */ function initialMenuMaxDepth() { if( ! body[0].className ) return 0; var match = body[0].className.match(/menu-max-depth-(\d+)/); return match && match[1] ? parseInt( match[1], 10 ) : 0; } + /** + * Updates the menu max depth class on the body element. + * + * @param {number} depthChange The change in depth of the menu item being moved. + * @return {void} + */ function updateMenuMaxDepth( depthChange ) { var depth, newDepth = menuMaxDepth; if ( depthChange === 0 ) { diff --git a/src/js/_enqueues/lib/quicktags.js b/src/js/_enqueues/lib/quicktags.js index 621fab1058315..bdb978750e549 100644 --- a/src/js/_enqueues/lib/quicktags.js +++ b/src/js/_enqueues/lib/quicktags.js @@ -233,6 +233,12 @@ window.edToolbar = function(){}; t.init(); }; + /** + * Escapes HTML special characters in a string. + * + * @param {string} text The string to escape. + * @return {string} The escaped string. + */ function _escape( text ) { text = text || ''; text = text.replace( /&([^#])(?![a-z1-4]{1,8};)/gi, '&$1' ); @@ -248,6 +254,11 @@ window.edToolbar = function(){}; qt._buttonsInit = function( id ) { var t = this; + /** + * Initializes the Quicktags buttons for a specific instance. + * + * @param {string} instanceId The ID of the Quicktags instance to initialize buttons for. + */ function _init( instanceId ) { var canvas, name, settings, theButtons, html, ed, id, i, use, defaults = ',strong,em,link,block,del,ins,img,ul,ol,li,code,more,close,'; diff --git a/src/js/_enqueues/wp/api-request.js b/src/js/_enqueues/wp/api-request.js index a72fd08b376de..4762a37f658e2 100644 --- a/src/js/_enqueues/wp/api-request.js +++ b/src/js/_enqueues/wp/api-request.js @@ -21,11 +21,38 @@ ( function( $ ) { var wpApiSettings = window.wpApiSettings; + /** + * Makes an API request. + * + * @param {Object} options The options for the API request. + * @param {string} [options.url] The full URL for the request. + * @param {string} [options.path] The API path (e.g., 'wp/v2/posts'). Used if url is not provided. + * @param {string} [options.namespace] The API namespace (e.g., 'wp/v2'). Used with endpoint to build path. + * @param {string} [options.endpoint] The API endpoint (e.g., 'posts'). Used with namespace to build path. + * @param {string} [options.method] The HTTP method (GET, POST, PUT, DELETE, etc.). + * @param {Object} [options.data] The request data to send. + * @param {string} [options.data._wpnonce] Nonce for security. + * @param {Object} [options.headers] Custom headers to include in the request. + * @return {JQueryXHR} The jQuery XHR object. + */ function apiRequest( options ) { options = apiRequest.buildAjaxOptions( options ); return apiRequest.transport( options ); } + /** + * Builds the options for the jQuery.ajax request. + * + * @param {Object} options The options for the API request. + * @param {string} [options.url] The full URL for the request. + * @param {string} [options.path] The API path (e.g., 'wp/v2/posts'). Used if url is not provided. + * @param {string} [options.namespace] The API namespace (e.g., 'wp/v2'). Used with endpoint to build path. + * @param {string} [options.endpoint] The API endpoint (e.g., 'posts'). Used with namespace to build path. + * @param {string} [options.method] The HTTP method (GET, POST, PUT, DELETE, etc.). + * @param {Object} [options.data] The request data to send. + * @param {Object} [options.headers] Custom headers to include in the request. + * @return {Object} The options for the jQuery.ajax request. + */ apiRequest.buildAjaxOptions = function( options ) { var url = options.url; var path = options.path; diff --git a/src/js/_enqueues/wp/autosave.js b/src/js/_enqueues/wp/autosave.js index 35d7a055ed98e..4ad4e7fe56133 100644 --- a/src/js/_enqueues/wp/autosave.js +++ b/src/js/_enqueues/wp/autosave.js @@ -449,6 +449,12 @@ window.autosave = function() { * @return {boolean} True if the strings are the same. */ function compare( str1, str2 ) { + /** + * Removes all whitespace characters from a string. + * + * @param {string} string The string to remove whitespace from. + * @return {string} The string without whitespace characters. + */ function removeSpaces( string ) { return string.toString().replace(/[\x20\t\r\n\f]+/g, ''); } diff --git a/src/js/_enqueues/wp/custom-header.js b/src/js/_enqueues/wp/custom-header.js index 1771ce7505544..7d4fa98d7cc53 100644 --- a/src/js/_enqueues/wp/custom-header.js +++ b/src/js/_enqueues/wp/custom-header.js @@ -244,6 +244,11 @@ BaseHandler.extend = function( protoProps ) { var prop; + /** + * Creates a custom handler instance. + * + * @return {CustomHandler} A custom handler instance, when called with new. + */ function CustomHandler() { var result = BaseHandler.apply( this, arguments ); return result; diff --git a/src/js/_enqueues/wp/customize/controls.js b/src/js/_enqueues/wp/customize/controls.js index 2a1818b8bba42..94693163c0240 100644 --- a/src/js/_enqueues/wp/customize/controls.js +++ b/src/js/_enqueues/wp/customize/controls.js @@ -843,6 +843,9 @@ options ); + /** + * Cancels the reminder, preventing the button from being highlighted. + */ function cancelReminder() { canceled = true; } @@ -1981,6 +1984,9 @@ api.section( 'wporg_themes' ).focus(); }); + /** + * Updates the section header to reflect the expanded state. + */ function updateSelectedState() { var el = section.headerContainer.find( '.customize-themes-section-title' ); el.toggleClass( 'selected', section.expanded() ); @@ -2025,6 +2031,9 @@ return; } + /** + * Expands the section. + */ function expand() { // Try to load controls if none are loaded yet. @@ -2625,11 +2634,21 @@ .fadeIn( 'fast' ) .focus(); + /** + * Disables the switch buttons if the theme cannot be switched to. + * + * @return {boolean} True if the switch buttons should be disabled, false otherwise. + */ function disableSwitchButtons() { return ! panel.canSwitchTheme( theme.id ); } // Temporary special function since supplying SFTP credentials does not work yet. See #42184. + /** + * Disables the install buttons if the theme cannot be installed or if filesystem credentials are needed. + * + * @return {boolean} True if the install buttons should be disabled, false otherwise. + */ function disableInstallButtons() { return disableSwitchButtons() || false === api.settings.theme._canInstall || true === api.settings.theme._filesystemCredentialsNeeded; } @@ -3137,6 +3156,9 @@ } ) ); } + /** + * Toggles the theme switch unavailable notification based on whether switching is possible. + */ function toggleDisabledNotifications() { if ( panel.canSwitchTheme() ) { panel.notifications.remove( 'theme_switch_unavailable' ); @@ -5215,14 +5237,28 @@ ready: function() { var control = this, panel = api.panel( 'themes' ); + /** + * Disables the preview buttons if the theme cannot be switched to. + * + * @return {boolean} True if the preview buttons should be disabled, false otherwise. + */ function disableSwitchButtons() { return ! panel.canSwitchTheme( control.params.theme.id ); } // Temporary special function since supplying SFTP credentials does not work yet. See #42184. + /** + * Disables the install buttons if the theme cannot be installed or if filesystem credentials are needed. + * + * @return {boolean} True if the install buttons should be disabled, false otherwise. + */ function disableInstallButtons() { return disableSwitchButtons() || false === api.settings.theme._canInstall || true === api.settings.theme._filesystemCredentialsNeeded; } + + /** + * Updates the state of the preview and install buttons based on whether the theme can be switched to or installed. + */ function updateButtons() { control.container.find( 'button.preview, button.preview-theme' ).toggleClass( 'disabled', disableSwitchButtons() ); control.container.find( 'button.theme-install' ).toggleClass( 'disabled', disableInstallButtons() ); @@ -7336,6 +7372,9 @@ updateButtonsState(); section.active.bind( updateButtonsState ); + /** + * Highlights the schedule button to remind the user to schedule the changes. + */ function highlightScheduleButton() { if ( ! cancelScheduleButtonReminder ) { cancelScheduleButtonReminder = api.utils.highlightButton( btnWrapper, { @@ -7350,6 +7389,10 @@ } ); } } + + /** + * Cancels the highlight reminder for the schedule button. + */ function cancelHighlightScheduleButton() { if ( cancelScheduleButtonReminder ) { cancelScheduleButtonReminder(); @@ -7591,6 +7634,11 @@ api.state( 'saving' ).set( true ); + /** + * Captures a setting as modified during the save process. + * + * @param {wp.customize.Setting} setting The setting that was modified. + */ function captureSettingModifiedDuringSave( setting ) { modifiedWhileSaving[ setting.id ] = true; } @@ -8933,6 +8981,11 @@ (function() { var isInsideIframe = false; + /** + * Determine whether the Customizer is in a clean state. + * + * @return {boolean} True if the Customizer is in a clean state, false otherwise. + */ function isCleanState() { var defaultChangesetStatus; @@ -8969,6 +9022,9 @@ isInsideIframe = true; }); + /** + * Starts prompting the user before unloading the Customizer if there are unsaved changes. + */ function startPromptingBeforeUnload() { api.unbind( 'change', startPromptingBeforeUnload ); api.state( 'selectedChangesetStatus' ).unbind( startPromptingBeforeUnload ); @@ -8988,6 +9044,11 @@ api.state( 'selectedChangesetStatus' ).bind( startPromptingBeforeUnload ); api.state( 'selectedChangesetDate' ).bind( startPromptingBeforeUnload ); + /** + * Requests to close the Customizer, prompting the user to save changes if necessary. + * + * @return {JQuery.Promise} A promise that resolves if the user is cleared to close the Customizer, or rejects if the user cancels the close. + */ function requestClose() { var clearedToClose = $.Deferred(), dismissAutoSave = false, dismissLock = false; @@ -9377,12 +9438,19 @@ api.previewer.send( 'edit-shortcut-visibility', visibility ); } ); - // Autosave changeset. + /** + * Starts autosaving changeset when a change is made. + */ function startAutosaving() { var timeoutId, updateChangesetWithReschedule, scheduleChangesetUpdate, updatePending = false; api.unbind( 'change', startAutosaving ); // Ensure startAutosaving only fires once. + /** + * Handles changes to the saved state of the changeset. + * + * @param {boolean} isSaved Whether the changeset is saved or not. + */ function onChangeSaved( isSaved ) { if ( ! isSaved && ! api.settings.changeset.autosaved ) { api.settings.changeset.autosaved = true; // Once a change is made then autosaving kicks in. diff --git a/src/js/_enqueues/wp/customize/widgets.js b/src/js/_enqueues/wp/customize/widgets.js index 5f8faf29709dd..5af1e8007de83 100644 --- a/src/js/_enqueues/wp/customize/widgets.js +++ b/src/js/_enqueues/wp/customize/widgets.js @@ -2358,6 +2358,11 @@ */ function focusConstructWithBreadcrumb( focusConstruct, returnConstruct ) { focusConstruct.focus(); + /** + * Determines whether to return focus to the returnConstruct after the focusConstruct is collapsed. + * + * @param {boolean} isExpanded Whether the focusConstruct is expanded. + */ function onceCollapsed( isExpanded ) { if ( ! isExpanded ) { focusConstruct.expanded.unbind( onceCollapsed ); diff --git a/src/js/_enqueues/wp/editor/base.js b/src/js/_enqueues/wp/editor/base.js index c2c264e3f8045..0c3485ca7d661 100644 --- a/src/js/_enqueues/wp/editor/base.js +++ b/src/js/_enqueues/wp/editor/base.js @@ -4,6 +4,12 @@ window.wp = window.wp || {}; +/** + * The editor functionality. + * + * @param {JQueryStatic} $ The jQuery object. + * @param {Object} wp The WordPress global object. + */ ( function( $, wp ) { wp.editor = wp.editor || {}; @@ -17,6 +23,9 @@ window.wp = window.wp || {}; var tinymce, $$, exports = {}; + /** + * Initializes the editor utility functions. + */ function init() { if ( ! tinymce && window.tinymce ) { tinymce = window.tinymce; diff --git a/src/js/_enqueues/wp/editor/dfw.js b/src/js/_enqueues/wp/editor/dfw.js index 3e5276ed3ef4f..d6a563e8f7872 100644 --- a/src/js/_enqueues/wp/editor/dfw.js +++ b/src/js/_enqueues/wp/editor/dfw.js @@ -1360,6 +1360,12 @@ setTimeout( function() { var position = document.activeElement.compareDocumentPosition( $editor.get( 0 ) ); + /** + * Determines whether the passed element has focus. + * + * @param {jQuery} $el The element to check for focus. + * @return {boolean} True if the element has focus, false otherwise. + */ function hasFocus( $el ) { return $.contains( $el.get( 0 ), document.activeElement ); } @@ -1524,10 +1530,16 @@ $document.on( 'tinymce-editor-init.focus', function( event, editor ) { var mceBind, mceUnbind; + /** + * Tracks when the TinyMCE editor receives focus. + */ function focus() { editorHasFocus = true; } + /** + * Tracks when the TinyMCE editor loses focus. + */ function blur() { editorHasFocus = false; } diff --git a/src/js/_enqueues/wp/embed.js b/src/js/_enqueues/wp/embed.js index 724daa3283e93..5522fb824a38c 100644 --- a/src/js/_enqueues/wp/embed.js +++ b/src/js/_enqueues/wp/embed.js @@ -87,6 +87,9 @@ } }; + /** + * Initializes the embed script on DOMContentLoaded. + */ function onLoad() { var iframes = document.querySelectorAll( 'iframe.wp-embedded-content' ), i, source, secret; diff --git a/src/js/_enqueues/wp/mce-view.js b/src/js/_enqueues/wp/mce-view.js index 01dbaedf1f122..4bbd71efc31f0 100644 --- a/src/js/_enqueues/wp/mce-view.js +++ b/src/js/_enqueues/wp/mce-view.js @@ -4,7 +4,7 @@ /* global tinymce */ -/* +/** * The TinyMCE view API. * * Note: this API is "experimental" meaning that it will probably change @@ -25,6 +25,11 @@ * | | |- ... * |- registered view * | |- ... + * + * @param {Window} window The global window object. + * @param {Object} wp The WordPress global object. + * @param {Object} shortcode The shortcode API. + * @param {JQueryStatic} $ The jQuery object. */ ( function( window, wp, shortcode, $ ) { 'use strict'; @@ -615,6 +620,9 @@ iframeDoc.close(); + /** + * Resizes the iframe to fit its content. + */ function resize() { var $iframe; @@ -643,6 +651,9 @@ }, 3000 ); } + /** + * Adds a MutationObserver to the iframe's body to watch for changes and resize accordingly. + */ function addObserver() { observer = new MutationObserver( _.debounce( resize, 100 ) ); @@ -763,15 +774,27 @@ } ); } )( window, window.wp, window.wp.shortcode, window.jQuery ); -/* +/** * The WordPress core TinyMCE views. + * * Views for the gallery, audio, video, playlist and embed shortcodes, * and a view for embeddable URLs. + * + * @param {Window} window The global window object. + * @param {Object} views The wp.mce.views object. + * @param {Object} media The wp.media object. + * @param {JQueryStatic} $ The jQuery object. */ ( function( window, views, media, $ ) { var base, gallery, av, embed, schema, parser, serializer; + /** + * Verifies that a given string is valid HTML. + * + * @param {string} string The string to verify. + * @return {string} The verified string. + */ function verifyHTML( string ) { var settings = {}; diff --git a/src/js/_enqueues/wp/theme-plugin-editor.js b/src/js/_enqueues/wp/theme-plugin-editor.js index 88c985be42012..74e0634f94e45 100644 --- a/src/js/_enqueues/wp/theme-plugin-editor.js +++ b/src/js/_enqueues/wp/theme-plugin-editor.js @@ -418,6 +418,9 @@ wp.themePluginEditor = (function( $ ) { editor = wp.codeEditor.initialize( $( '#newcontent' ), codeEditorSettings ); editor.codemirror.on( 'change', component.onChange ); + /** + * Handles the save shortcut (Ctrl+S / Cmd+S). + */ function onSaveShortcut() { component.form.trigger( 'submit' ); } @@ -601,10 +604,22 @@ wp.themePluginEditor = (function( $ ) { var flag = false, _char = event.key; + /** + * Determines whether a character is a printable character. + * + * @param {string} str The character to check. + * @return {boolean} True if the character is printable, false otherwise. + */ function isPrintableCharacter(str) { return str.length === 1 && str.match(/\S/); } + /** + * Handles printable character key press. + * + * @param {TreeitemLink} item The tree item link instance. + * @return {void} + */ function printableCharacter(item) { if (_char == '*') { item.tree.expandAllSiblingItems(item); @@ -808,7 +823,14 @@ wp.themePluginEditor = (function( $ ) { }; TreeLinks.prototype.init = function () { - + /** + * Finds all treeitems and groups and creates object instances. + * + * @param {Element} node The DOM node to search for treeitems. + * @param {TreeLinks} tree The TreeLinks instance. + * @param {TreeitemLink|boolean} group The parent TreeitemLink instance or false if there is no parent. + * @return {void} + */ function findTreeitems(node, tree, group) { var elem = node.firstElementChild; From 83ba0ce32b7ef7ae7e90a78da516f44702444661 Mon Sep 17 00:00:00 2001 From: Jonathan Desrosiers Date: Wed, 9 Sep 2026 12:35:58 +0000 Subject: [PATCH 450/634] Build/Test Tools: Increase PHPUnit workflow `timeout-minutes`. There has been a considerable number of PHPUnit test workflow runs recently that have been hitting the default configured `timeout-minutes` value of `20`. This increases the value to `30` to avoid runs being cancelled prematurely until the speed of the test suite can be improved. See #65845. git-svn-id: https://develop.svn.wordpress.org/trunk@63557 602fd350-edb4-49c9-b593-d223f7449a82 --- .github/workflows/reusable-phpunit-tests-v3.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reusable-phpunit-tests-v3.yml b/.github/workflows/reusable-phpunit-tests-v3.yml index 459ad5fda8823..6348d2a5cfbbf 100644 --- a/.github/workflows/reusable-phpunit-tests-v3.yml +++ b/.github/workflows/reusable-phpunit-tests-v3.yml @@ -154,7 +154,7 @@ jobs: phpunit-tests: name: ${{ ( inputs.phpunit-test-groups || inputs.coverage-report ) && format( 'PHP {0} with ', inputs.php ) || '' }} ${{ 'mariadb' == inputs.db-type && 'MariaDB' || 'MySQL' }} ${{ inputs.db-version }}${{ inputs.multisite && ' multisite' || '' }}${{ inputs.db-innovation && ' (innovation release)' || '' }}${{ inputs.memcached && ' with memcached' || '' }}${{ inputs.report && ' (test reporting enabled)' || '' }} ${{ 'example.org' != inputs.tests-domain && inputs.tests-domain || '' }} runs-on: ${{ vars.RUNNERS_NAME || inputs.os }} - timeout-minutes: ${{ inputs.coverage-report && 120 || inputs.php == '8.4' && 30 || 20 }} + timeout-minutes: ${{ inputs.coverage-report && 120 || 30 }} permissions: contents: read From 0f36f52ddf1733ff3acaaae76dee920491c3d0eb Mon Sep 17 00:00:00 2001 From: Jonathan Desrosiers Date: Wed, 9 Sep 2026 12:39:32 +0000 Subject: [PATCH 451/634] Build/Test Tools: Increase Gutenberg artifact retention. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It’s common for nuanced workflow run failures to be investigated over the course of several days following the initial run. In these cases, the entire workflow must be rerun even one only one or two jobs had failed because the artifact has expired. This increases the artifact retention of the built Gutenberg asset from `1` day to `7` to help with this workflow. See #65845. git-svn-id: https://develop.svn.wordpress.org/trunk@63558 602fd350-edb4-49c9-b593-d223f7449a82 --- .github/workflows/reusable-prepare-gutenberg.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reusable-prepare-gutenberg.yml b/.github/workflows/reusable-prepare-gutenberg.yml index 83c22cffb1b55..2d2c407ecdc7a 100644 --- a/.github/workflows/reusable-prepare-gutenberg.yml +++ b/.github/workflows/reusable-prepare-gutenberg.yml @@ -106,4 +106,4 @@ jobs: path: gutenberg/ if-no-files-found: error include-hidden-files: true - retention-days: 1 + retention-days: 7 From 8edab75a6f51433606e71d8e916f923462c13bc3 Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Wed, 9 Sep 2026 14:02:43 +0000 Subject: [PATCH 452/634] Administration: Remove usage of the #787c82 gray color. This light gray color is used for controls that contain only icons. For example, the next / previous / close buttons in the media and themes browsers. Same for some icon-only controls in the Customizer. These icons must meet a 4.5:1 minimum color contrast ratio. The remaining usages are so limited that don't justify the introduction of a dedicated color so it's reasonable to remove it entirely. Developed in https://github.com/WordPress/wordpress-develop/pull/13320 Fixes #65995. git-svn-id: https://develop.svn.wordpress.org/trunk@63559 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/css/common.css | 4 ++-- src/wp-admin/css/customize-nav-menus.css | 4 ++-- src/wp-admin/css/customize-widgets.css | 2 +- src/wp-admin/css/edit.css | 4 ++-- src/wp-admin/css/forms.css | 2 +- src/wp-admin/css/list-tables.css | 2 +- src/wp-admin/css/media.css | 2 +- src/wp-admin/css/themes.css | 4 ++-- src/wp-admin/css/widgets.css | 2 +- src/wp-includes/css/wp-auth-check.css | 2 +- src/wp-includes/css/wp-pointer.css | 2 +- 11 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/wp-admin/css/common.css b/src/wp-admin/css/common.css index 980702d31fb80..a3c5c05dcda81 100644 --- a/src/wp-admin/css/common.css +++ b/src/wp-admin/css/common.css @@ -2553,7 +2553,7 @@ h1.nav-tab-wrapper, /* Back-compat for pre-4.4 */ position: absolute; right: 10px; left: auto; - color: #787c82; + color: #50575e; border-radius: 50px; top: 50%; transform: translateY(-50%); @@ -3372,7 +3372,7 @@ img { .bulk-action-notice .toggle-indicator::before { line-height: 16px; vertical-align: top; - color: #787c82; + color: #50575e; } .postbox .handle-order-higher:focus, diff --git a/src/wp-admin/css/customize-nav-menus.css b/src/wp-admin/css/customize-nav-menus.css index 37008d6d8e29a..9c98728841bc3 100644 --- a/src/wp-admin/css/customize-nav-menus.css +++ b/src/wp-admin/css/customize-nav-menus.css @@ -329,7 +329,7 @@ display: block; padding: 1px 2px 1px 0; border-radius: 50%; - color: #787c82; + color: #50575e; font: normal 20px/1 dashicons; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; @@ -770,7 +770,7 @@ body.adding-menu-items #customize-preview iframe { cursor: default; opacity: .5; background: #fff; - color: #787c82; + color: #50575e; } .added-menu-item .menu-item-handle { diff --git a/src/wp-admin/css/customize-widgets.css b/src/wp-admin/css/customize-widgets.css index 6e1bda06b13dc..db86274af00f1 100644 --- a/src/wp-admin/css/customize-widgets.css +++ b/src/wp-admin/css/customize-widgets.css @@ -25,7 +25,7 @@ } .customize-control .widget-action { - color: #787c82; + color: #50575e; } .customize-control .widget-top:hover .widget-action, diff --git a/src/wp-admin/css/edit.css b/src/wp-admin/css/edit.css index c02a15aa3995a..e564d362a5a85 100644 --- a/src/wp-admin/css/edit.css +++ b/src/wp-admin/css/edit.css @@ -876,7 +876,7 @@ form#tags-filter { .privacy-settings-tab:focus, .health-check-tab:focus { color: #1d2327; - outline: 1px solid #787c82; + outline: 1px solid #50575e; box-shadow: none; } @@ -1087,7 +1087,7 @@ form#tags-filter { .privacy-settings-accordion-panel div > *:not(h1):not(h2):not(h3):not(h4):not(h5):not(h6):not(div):not(.privacy-policy-tutorial):not(.wp-policy-help):not(.privacy-text-copy):not(span.success):not(.notice p) { margin: 0; padding: 1em; - border-left: 2px solid #787c82; + border-left: 2px solid #50575e; } /* Media queries */ diff --git a/src/wp-admin/css/forms.css b/src/wp-admin/css/forms.css index 42a07d16fc9f2..fe45e848a3a91 100644 --- a/src/wp-admin/css/forms.css +++ b/src/wp-admin/css/forms.css @@ -1188,7 +1188,7 @@ table.form-table td .updated p { } .pressthis-bookmarklet span:before { - color: #787c82; + color: #50575e; font: normal 20px/1 dashicons; content: "\f157"; content: "\f157" / ''; diff --git a/src/wp-admin/css/list-tables.css b/src/wp-admin/css/list-tables.css index f6abda748bf1a..66078669f4107 100644 --- a/src/wp-admin/css/list-tables.css +++ b/src/wp-admin/css/list-tables.css @@ -793,7 +793,7 @@ th.sorted a span { .view-switch a:hover:before, .view-switch a:focus:before { - color: #787c82; + color: #1e1e1e; } .view-switch a.current:before { diff --git a/src/wp-admin/css/media.css b/src/wp-admin/css/media.css index 3d7b0c9455c83..09c69d83cbb41 100644 --- a/src/wp-admin/css/media.css +++ b/src/wp-admin/css/media.css @@ -675,7 +675,7 @@ border color while dragging a file over the uploader drop area */ .edit-attachment-frame .edit-media-header .left, .edit-attachment-frame .edit-media-header .right { cursor: pointer; - color: #787c82; + color: #50575e; background-color: transparent; height: 50px; width: 50px; diff --git a/src/wp-admin/css/themes.css b/src/wp-admin/css/themes.css index 24be8ac58c5be..5ffb62ca033cd 100644 --- a/src/wp-admin/css/themes.css +++ b/src/wp-admin/css/themes.css @@ -453,7 +453,7 @@ body.js .theme-browser.search-loading { .theme-overlay .theme-header .close:before { font: normal 22px/50px dashicons !important; - color: #787c82; + color: #50575e; display: inline-block; content: "\f335"; content: "\f335" / ''; @@ -464,7 +464,7 @@ body.js .theme-browser.search-loading { .theme-overlay .theme-header .right, .theme-overlay .theme-header .left { cursor: pointer; - color: #787c82; + color: #50575e; background-color: transparent; height: 48px; width: 54px; diff --git a/src/wp-admin/css/widgets.css b/src/wp-admin/css/widgets.css index 99039d3c7c66a..44a3eaf03f6a7 100644 --- a/src/wp-admin/css/widgets.css +++ b/src/wp-admin/css/widgets.css @@ -516,7 +516,7 @@ div#widgets-right .closed .widgets-sortables { /* Dragging a widget over a closed sidebar */ #widgets-right .widgets-holder-wrap.widget-hover { - border-color: #787c82; + border-color: #50575e; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); } diff --git a/src/wp-includes/css/wp-auth-check.css b/src/wp-includes/css/wp-auth-check.css index 904dbab4fe9c5..046e87b0b8be6 100644 --- a/src/wp-includes/css/wp-auth-check.css +++ b/src/wp-includes/css/wp-auth-check.css @@ -86,7 +86,7 @@ right: 5px; height: 22px; width: 22px; - color: #787c82; + color: #50575e; text-decoration: none; text-align: center; } diff --git a/src/wp-includes/css/wp-pointer.css b/src/wp-includes/css/wp-pointer.css index ccf7ddc560397..0d6238796d12c 100644 --- a/src/wp-includes/css/wp-pointer.css +++ b/src/wp-includes/css/wp-pointer.css @@ -64,7 +64,7 @@ .wp-pointer-buttons a.close::before { background: none; - color: #787c82; + color: #50575e; content: "\f153"; content: "\f153" / ""; display: block !important; From dafbbffcce918ed637fc69e21e6b543257ba1f52 Mon Sep 17 00:00:00 2001 From: Lance Willett Date: Wed, 9 Sep 2026 14:23:57 +0000 Subject: [PATCH 453/634] Build/Test Tools: Block ungrouped external HTTP requests. Fail core tests that make unmocked HTTP requests outside the external-http group, and block those requests before they reach the network. Preserve mocked responses and leave plugin and theme test suites unaffected. Add the missing external-http annotation to the oEmbed shortcode test. Developed in: https://github.com/WordPress/wordpress-develop/pull/13407 Props peterwilsoncc, adrianmoldovanwp, westonruter. See #63083. git-svn-id: https://develop.svn.wordpress.org/trunk@63560 602fd350-edb4-49c9-b593-d223f7449a82 --- tests/phpunit/includes/abstract-testcase.php | 49 ++++++++++++++++++++ tests/phpunit/tests/oembed/WpEmbed.php | 2 + 2 files changed, 51 insertions(+) diff --git a/tests/phpunit/includes/abstract-testcase.php b/tests/phpunit/includes/abstract-testcase.php index c87e5e7fd077c..25b207092c110 100644 --- a/tests/phpunit/includes/abstract-testcase.php +++ b/tests/phpunit/includes/abstract-testcase.php @@ -22,6 +22,13 @@ abstract class WP_UnitTestCase_Base extends PHPUnit_Adapter_TestCase { /** @var non-empty-string[] */ protected $caught_doing_it_wrong = array(); + /** + * URLs of blocked external HTTP requests made during the current test. + * + * @var list + */ + protected array $blocked_http_requests = array(); + protected static $hooks_saved = array(); protected static $ignore_files; @@ -143,6 +150,12 @@ public function set_up() { $this->expectDeprecated(); add_filter( 'wp_die_handler', array( $this, 'get_wp_die_handler' ) ); add_filter( 'wp_hash_password_options', array( $this, 'wp_hash_password_options' ), 1, 2 ); + + if ( defined( 'WP_RUN_CORE_TESTS' ) && WP_RUN_CORE_TESTS + && ! in_array( 'external-http', $this->getGroups(), true ) + ) { + add_filter( 'pre_http_request', array( $this, 'block_external_http_request' ), PHP_INT_MAX, 3 ); + } } /** @@ -685,6 +698,34 @@ public function expectedDeprecated() { } } + /** + * Blocks an external HTTP request that no other filter has answered. + * + * Added by set_up() for tests that are not in the `external-http` group, and + * runs last on the filter so any mock set up by the test itself gets the + * first say. Requests reaching this point are recorded and fail the test in + * assert_post_conditions(). + * + * @since 7.2.0 + * + * @param false|array|WP_Error $response A preemptive response, or false when none was given. + * @param array $args Request arguments. + * @param string $url The request URL. + * @return array|WP_Error The preemptive response, or an error for a blocked request. + */ + public function block_external_http_request( $response, array $args, string $url ) { + if ( false !== $response ) { + return $response; + } + + $this->blocked_http_requests[] = $url; + + return new WP_Error( + 'test_external_http_blocked', + 'External HTTP requests are blocked in tests that are not in the `external-http` group.' + ); + } + /** * Detects post-test failure conditions. * @@ -694,6 +735,14 @@ public function expectedDeprecated() { */ protected function assert_post_conditions() { $this->expectedDeprecated(); + + if ( $this->blocked_http_requests ) { + $this->fail( + "This test made an external HTTP request but is not in the `external-http` group.\n" + . "Add `@group external-http` to it, or mock the request with the `pre_http_request` filter.\n" + . '- ' . implode( "\n- ", array_unique( $this->blocked_http_requests ) ) + ); + } } /** diff --git a/tests/phpunit/tests/oembed/WpEmbed.php b/tests/phpunit/tests/oembed/WpEmbed.php index 42d9c9e0f4ed9..f95fbde7b92dd 100644 --- a/tests/phpunit/tests/oembed/WpEmbed.php +++ b/tests/phpunit/tests/oembed/WpEmbed.php @@ -405,6 +405,8 @@ public function test_shortcode_should_make_link_for_unknown_url() { } /** + * @group external-http + * * @covers ::run_shortcode */ public function test_run_shortcode_url_only() { From 4c988a30bdce85a3f6ba89d7ab0a06416db723f8 Mon Sep 17 00:00:00 2001 From: Lance Willett Date: Wed, 9 Sep 2026 14:29:00 +0000 Subject: [PATCH 454/634] Tests: Remove unused sitemap taxonomy test variables. Remove unused post variables and closure captures from the sitemap taxonomy tests. Use the post factory create() method to assign and count the test terms, and correct the fixture comment. Developed in: https://github.com/WordPress/wordpress-develop/pull/13455 Props soean. See #65819. git-svn-id: https://develop.svn.wordpress.org/trunk@63561 602fd350-edb4-49c9-b593-d223f7449a82 --- .../phpunit/tests/sitemaps/wpSitemapsTaxonomies.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/phpunit/tests/sitemaps/wpSitemapsTaxonomies.php b/tests/phpunit/tests/sitemaps/wpSitemapsTaxonomies.php index 456efe06e922f..f3d292dd26a34 100644 --- a/tests/phpunit/tests/sitemaps/wpSitemapsTaxonomies.php +++ b/tests/phpunit/tests/sitemaps/wpSitemapsTaxonomies.php @@ -45,8 +45,8 @@ public function test_get_url_list_taxonomies() { // Add the default category to the list of categories we're testing. $categories = array_merge( array( 1 ), self::$cats ); - // Create a test post to calculate update times. - $post = self::factory()->post->create_and_get( + // Create a test post so the test terms are assigned and counted. + self::factory()->post->create( array( 'tags_input' => self::$post_tags, 'post_category' => $categories, @@ -58,7 +58,7 @@ public function test_get_url_list_taxonomies() { $cat_list = $tax_provider->get_url_list( 1, 'category' ); $expected_cats = array_map( - static function ( $id ) use ( $post ) { + static function ( $id ) { return array( 'loc' => get_term_link( $id, 'category' ), ); @@ -71,7 +71,7 @@ static function ( $id ) use ( $post ) { $tag_list = $tax_provider->get_url_list( 1, 'post_tag' ); $expected_tags = array_map( - static function ( $id ) use ( $post ) { + static function ( $id ) { return array( 'loc' => get_term_link( $id, 'post_tag' ), ); @@ -97,10 +97,10 @@ public function test_get_url_list_custom_taxonomy() { $terms = self::factory()->term->create_many( 10, array( 'taxonomy' => $taxonomy ) ); // Create a test post applied to all test terms. - $post = self::factory()->post->create_and_get( array( 'tax_input' => array( $taxonomy => $terms ) ) ); + self::factory()->post->create( array( 'tax_input' => array( $taxonomy => $terms ) ) ); $expected = array_map( - static function ( $id ) use ( $taxonomy, $post ) { + static function ( $id ) use ( $taxonomy ) { return array( 'loc' => get_term_link( $id, $taxonomy ), ); From 6e3e6967de1ad584a852cd4d68077278800d000f Mon Sep 17 00:00:00 2001 From: Lance Willett Date: Wed, 9 Sep 2026 14:30:58 +0000 Subject: [PATCH 455/634] Tests: Simplify mocks in WP_Upgrader tests. Use `createMock()` for the upgrader skin and filesystem mocks. These test doubles need no custom builder configuration, original constructor, or cloning behavior. Developed in: https://github.com/WordPress/wordpress-develop/pull/13458 Props soean. See #65819. git-svn-id: https://develop.svn.wordpress.org/trunk@63562 602fd350-edb4-49c9-b593-d223f7449a82 --- tests/phpunit/tests/admin/wpUpgrader.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/tests/admin/wpUpgrader.php b/tests/phpunit/tests/admin/wpUpgrader.php index ffea594ae87bc..59930164a238a 100644 --- a/tests/phpunit/tests/admin/wpUpgrader.php +++ b/tests/phpunit/tests/admin/wpUpgrader.php @@ -49,11 +49,11 @@ public static function set_up_before_class() { public function set_up() { parent::set_up(); - self::$upgrader_skin_mock = $this->getMockBuilder( 'WP_Upgrader_Skin' )->getMock(); + self::$upgrader_skin_mock = $this->createMock( 'WP_Upgrader_Skin' ); self::$instance = new WP_Upgrader( self::$upgrader_skin_mock ); - self::$wp_filesystem_mock = $this->getMockBuilder( 'WP_Filesystem_Base' )->getMock(); + self::$wp_filesystem_mock = $this->createMock( 'WP_Filesystem_Base' ); if ( array_key_exists( 'wp_filesystem', $GLOBALS ) ) { self::$wp_filesystem_backup = $GLOBALS['wp_filesystem']; From d6b0c206946b091745bfef66b432ec46100c073e Mon Sep 17 00:00:00 2001 From: Lance Willett Date: Wed, 9 Sep 2026 14:50:06 +0000 Subject: [PATCH 456/634] Tests: Reduce repeated core block style registration. Register core block styles once per scenario, then check all block handles. Replace per-block data-provider cases with loops, retaining the assertions and adding block names to failure messages. Developed in: https://github.com/WordPress/wordpress-develop/pull/13457 Props sainathpoojary. See #66074. git-svn-id: https://develop.svn.wordpress.org/trunk@63563 602fd350-edb4-49c9-b593-d223f7449a82 --- .../blocks/registerCoreBlockStyleHandles.php | 129 +++++++++--------- 1 file changed, 63 insertions(+), 66 deletions(-) diff --git a/tests/phpunit/tests/blocks/registerCoreBlockStyleHandles.php b/tests/phpunit/tests/blocks/registerCoreBlockStyleHandles.php index 7d5249b3236c0..cb798b20ba527 100644 --- a/tests/phpunit/tests/blocks/registerCoreBlockStyleHandles.php +++ b/tests/phpunit/tests/blocks/registerCoreBlockStyleHandles.php @@ -54,26 +54,24 @@ public function tear_down() { /** * @ticket 58528 * - * @dataProvider data_block_data - * * @covers ::register_core_block_style_handles * @covers ::wp_should_load_separate_core_block_assets - * - * @param string $name The block name. - * @param array $schema The block's schema. */ - public function test_wp_should_load_separate_core_block_assets_false( $name, $schema ) { + public function test_wp_should_load_separate_core_block_assets_false() { add_filter( 'should_load_separate_core_block_assets', '__return_false' ); - $this->assertFalse( wp_should_load_separate_core_block_assets(), 'Core blocks are not expected to load separate assets' ); register_core_block_style_handles(); - foreach ( self::STYLE_FIELDS as $style_field => $filename ) { - $style_handle = $schema[ $style_field ]; - if ( is_array( $style_handle ) ) { - continue; - } + foreach ( $this->get_block_data() as $name => $schema ) { + $this->assertFalse( wp_should_load_separate_core_block_assets(), "Block {$name}: Core blocks are not expected to load separate assets" ); + + foreach ( self::STYLE_FIELDS as $style_field => $filename ) { + $style_handle = $schema[ $style_field ]; + if ( is_array( $style_handle ) ) { + continue; + } - $this->assertArrayNotHasKey( $style_handle, $GLOBALS['wp_styles']->registered, 'The key should not exist, as this style should not be registered' ); + $this->assertArrayNotHasKey( $style_handle, $GLOBALS['wp_styles']->registered, "Block {$name}: The key should not exist, as this style should not be registered" ); + } } } @@ -81,74 +79,66 @@ public function test_wp_should_load_separate_core_block_assets_false( $name, $sc /** * @ticket 58528 * - * @dataProvider data_block_data - * * @covers ::register_core_block_style_handles * @covers ::wp_should_load_separate_core_block_assets - * - * @param string $name The block name. - * @param array $schema The block's schema. */ - public function test_wp_should_load_separate_core_block_assets_true( $name, $schema ) { + public function test_wp_should_load_separate_core_block_assets_true() { add_filter( 'should_load_separate_core_block_assets', '__return_true' ); - $this->assertTrue( wp_should_load_separate_core_block_assets(), 'Core assets are expected to load separately' ); register_core_block_style_handles(); $wp_styles = $GLOBALS['wp_styles']; - foreach ( self::STYLE_FIELDS as $style_field => $filename ) { - $style_handle = $schema[ $style_field ]; - if ( is_array( $style_handle ) ) { - continue; - } - - $this->assertArrayHasKey( $style_handle, $wp_styles->registered, 'The key should exist, as this style should be registered' ); - if ( false === $wp_styles->registered[ $style_handle ]->src ) { - $this->assertEmpty( $wp_styles->registered[ $style_handle ]->extra, 'If source is false, style path should not be set' ); - } else { - $this->assertStringContainsString( $this->includes_url, $wp_styles->registered[ $style_handle ]->src, 'Source of style should contain the includes url' ); - $this->assertNotEmpty( $wp_styles->registered[ $style_handle ]->extra, 'The path of the style should exist' ); - $this->assertArrayHasKey( 'path', $wp_styles->registered[ $style_handle ]->extra, 'The path key of the style should exist in extra array' ); - $this->assertNotEmpty( $wp_styles->registered[ $style_handle ]->extra['path'], 'The path key of the style should not be empty' ); + foreach ( $this->get_block_data() as $name => $schema ) { + $this->assertTrue( wp_should_load_separate_core_block_assets(), "Block {$name}: Core assets are expected to load separately" ); + + foreach ( self::STYLE_FIELDS as $style_field => $filename ) { + $style_handle = $schema[ $style_field ]; + if ( is_array( $style_handle ) ) { + continue; + } + + $this->assertArrayHasKey( $style_handle, $wp_styles->registered, "Block {$name}: The key should exist, as this style should be registered" ); + if ( false === $wp_styles->registered[ $style_handle ]->src ) { + $this->assertEmpty( $wp_styles->registered[ $style_handle ]->extra, "Block {$name}: If source is false, style path should not be set" ); + } else { + $this->assertStringContainsString( $this->includes_url, $wp_styles->registered[ $style_handle ]->src, "Block {$name}: Source of style should contain the includes url" ); + $this->assertNotEmpty( $wp_styles->registered[ $style_handle ]->extra, "Block {$name}: The path of the style should exist" ); + $this->assertArrayHasKey( 'path', $wp_styles->registered[ $style_handle ]->extra, "Block {$name}: The path key of the style should exist in extra array" ); + $this->assertNotEmpty( $wp_styles->registered[ $style_handle ]->extra['path'], "Block {$name}: The path key of the style should not be empty" ); + } } } } /** * @ticket 58560 - * - * @dataProvider data_block_data - * - * @param string $name The block name. */ - public function test_wp_should_load_separate_core_block_assets_current_theme_supports( $name ) { + public function test_wp_should_load_separate_core_block_assets_current_theme_supports() { add_filter( 'should_load_separate_core_block_assets', '__return_true' ); add_theme_support( 'wp-block-styles' ); register_core_block_style_handles(); $wp_styles = $GLOBALS['wp_styles']; - $style_handle = "wp-block-{$name}-theme"; + foreach ( array_keys( $this->get_block_data() ) as $name ) { + $style_handle = "wp-block-{$name}-theme"; - $this->assertArrayHasKey( $style_handle, $wp_styles->registered, 'The key should exist, as this style should be registered' ); - if ( false === $wp_styles->registered[ $style_handle ]->src ) { - $this->assertEmpty( $wp_styles->registered[ $style_handle ]->extra, 'If source is false, style path should not be set' ); - } else { - $this->assertStringContainsString( $this->includes_url, $wp_styles->registered[ $style_handle ]->src, 'Source of style should contain the includes url' ); - $this->assertNotEmpty( $wp_styles->registered[ $style_handle ]->extra, 'The path of the style should exist' ); - $this->assertArrayHasKey( 'path', $wp_styles->registered[ $style_handle ]->extra, 'The path key of the style should exist in extra array' ); - $this->assertNotEmpty( $wp_styles->registered[ $style_handle ]->extra['path'], 'The path key of the style should not be empty' ); + $this->assertArrayHasKey( $style_handle, $wp_styles->registered, "Block {$name}: The key should exist, as this style should be registered" ); + if ( false === $wp_styles->registered[ $style_handle ]->src ) { + $this->assertEmpty( $wp_styles->registered[ $style_handle ]->extra, "Block {$name}: If source is false, style path should not be set" ); + } else { + $this->assertStringContainsString( $this->includes_url, $wp_styles->registered[ $style_handle ]->src, "Block {$name}: Source of style should contain the includes url" ); + $this->assertNotEmpty( $wp_styles->registered[ $style_handle ]->extra, "Block {$name}: The path of the style should exist" ); + $this->assertArrayHasKey( 'path', $wp_styles->registered[ $style_handle ]->extra, "Block {$name}: The path key of the style should exist in extra array" ); + $this->assertNotEmpty( $wp_styles->registered[ $style_handle ]->extra['path'], "Block {$name}: The path key of the style should not be empty" ); + } } } /** * @ticket 59715 - * - * @dataProvider data_block_data - * - * @param string $name The block name. */ - public function test_register_core_block_style_handles_should_load_rtl_stylesheets_for_rtl_text_direction( $name ) { + public function test_register_core_block_style_handles_should_load_rtl_stylesheets_for_rtl_text_direction() { global $wp_locale; $orig_text_dir = $wp_locale->text_direction; @@ -159,23 +149,30 @@ public function test_register_core_block_style_handles_should_load_rtl_styleshee $wp_styles = $GLOBALS['wp_styles']; - $style_handle = "wp-block-{$name}-theme"; - $wp_locale->text_direction = $orig_text_dir; - $this->assertArrayHasKey( $style_handle, $wp_styles->registered, 'The key should exist, as this style should be registered' ); - if ( false === $wp_styles->registered[ $style_handle ]->src ) { - $this->assertEmpty( $wp_styles->registered[ $style_handle ]->extra, 'If source is false, style path should not be set' ); - } else { - $this->assertStringContainsString( $this->includes_url, $wp_styles->registered[ $style_handle ]->src, 'Source of style should contain the includes url' ); - $this->assertNotEmpty( $wp_styles->registered[ $style_handle ]->extra, 'The path of the style should exist' ); - $this->assertArrayHasKey( 'path', $wp_styles->registered[ $style_handle ]->extra, 'The path key of the style should exist in extra array' ); - $this->assertNotEmpty( $wp_styles->registered[ $style_handle ]->extra['path'], 'The path key of the style should not be empty' ); - $this->assertArrayHasKey( 'rtl', $wp_styles->registered[ $style_handle ]->extra, 'The rtl key of the style should exist in extra array' ); + foreach ( array_keys( $this->get_block_data() ) as $name ) { + $style_handle = "wp-block-{$name}-theme"; + + $this->assertArrayHasKey( $style_handle, $wp_styles->registered, "Block {$name}: The key should exist, as this style should be registered" ); + if ( false === $wp_styles->registered[ $style_handle ]->src ) { + $this->assertEmpty( $wp_styles->registered[ $style_handle ]->extra, "Block {$name}: If source is false, style path should not be set" ); + } else { + $this->assertStringContainsString( $this->includes_url, $wp_styles->registered[ $style_handle ]->src, "Block {$name}: Source of style should contain the includes url" ); + $this->assertNotEmpty( $wp_styles->registered[ $style_handle ]->extra, "Block {$name}: The path of the style should exist" ); + $this->assertArrayHasKey( 'path', $wp_styles->registered[ $style_handle ]->extra, "Block {$name}: The path key of the style should exist in extra array" ); + $this->assertNotEmpty( $wp_styles->registered[ $style_handle ]->extra['path'], "Block {$name}: The path key of the style should not be empty" ); + $this->assertArrayHasKey( 'rtl', $wp_styles->registered[ $style_handle ]->extra, "Block {$name}: The rtl key of the style should exist in extra array" ); + } } } - public function data_block_data() { + /** + * Gets the blocks to check after registering styles once per scenario. + * + * @return array[] Block schemas keyed by block name. + */ + private function get_block_data() { $core_blocks_meta = require ABSPATH . WPINC . '/blocks/blocks-json.php'; // Remove this blocks for now, as they are registered elsewhere. @@ -191,7 +188,7 @@ public function data_block_data() { $schema['editorStyle'] = "wp-block-{$name}-editor"; } - $data[ $name ] = array( $name, $schema ); + $data[ $name ] = $schema; } return $data; From 37a5d59ef68354d92a7966d66044ac6381bb77d6 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Wed, 9 Sep 2026 16:18:49 +0000 Subject: [PATCH 457/634] Media: Prepare the attachment finalize response from the current post data. `finalize_item()` prepares its response from the `$post` fetched before the `wp_generate_attachment_metadata` filter runs, so anything a callback writes to the post row is missing from the response. The editor now stores that response as the attachment record instead of refetching, so re-read the post after the metadata is written and return the `WP_Error` if a callback deleted the attachment. See https://github.com/WordPress/gutenberg/issues/81844 and https://github.com/WordPress/gutenberg/pull/81947. Props gregbenz, andrewserong. Fixes #66056. git-svn-id: https://develop.svn.wordpress.org/trunk@63564 602fd350-edb4-49c9-b593-d223f7449a82 --- .../class-wp-rest-attachments-controller.php | 15 ++ .../rest-api/rest-attachments-controller.php | 198 ++++++++++++++++++ 2 files changed, 213 insertions(+) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php index b95b061b3399e..9807ac9cf15b5 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php @@ -3453,6 +3453,21 @@ public function finalize_item( WP_REST_Request $request ) { $response_request['_fields'] = $request['_fields']; } + /* + * Re-read the post. The 'wp_generate_attachment_metadata' filter above + * runs long after $post was fetched, and a callback that rewrites the + * post row - an optimizer changing post_mime_type once it has + * converted the file, say - would otherwise be missing from this + * response. The editor stores the response as its copy of the record + * rather than reading the attachment again, so a stale row here is + * what it keeps. A callback that deleted the attachment instead leaves + * nothing to respond with, so that is reported as the error it is. + */ + $post = $this->get_post( $attachment_id ); + if ( is_wp_error( $post ) ) { + return $post; + } + return $this->prepare_item_for_response( $post, $response_request ); } } diff --git a/tests/phpunit/tests/rest-api/rest-attachments-controller.php b/tests/phpunit/tests/rest-api/rest-attachments-controller.php index 4dd0b60172cb4..282c0f6b95e22 100644 --- a/tests/phpunit/tests/rest-api/rest-attachments-controller.php +++ b/tests/phpunit/tests/rest-api/rest-attachments-controller.php @@ -5128,6 +5128,204 @@ public function test_finalize_preserves_image_meta(): void { $this->assertSame( $original_image_meta['iso'], $metadata['image_meta']['iso'], 'ISO should be preserved.' ); } + /** + * Verifies that the finalize response carries the generated sub-sizes. + * + * The response is prepared after the sub-size metadata has been written, so + * it is the finished attachment record. The editor stores it as-is instead + * of fetching the attachment again to pick the sizes up. + * + * @ticket 66056 + * + * @covers WP_REST_Attachments_Controller::finalize_item + */ + public function test_finalize_response_contains_generated_sub_sizes(): void { + $this->enable_client_side_media_processing(); + + wp_set_current_user( self::$author_id ); + + $request = new WP_REST_Request( 'POST', '/wp/v2/media' ); + $request->set_header( 'Content-Type', 'image/jpeg' ); + $request->set_header( 'Content-Disposition', 'attachment; filename=finalize-response-test.jpg' ); + $request->set_param( 'generate_sub_sizes', false ); + $request->set_body( (string) file_get_contents( DIR_TESTDATA . '/images/canola.jpg' ) ); + + $response = rest_get_server()->dispatch( $request ); + $data = $response->get_data(); + $attachment_id = $data['id']; + + // Nothing has generated sub-sizes yet, which is the window in which the + // editor's first read of the attachment happens. + $this->assertEmpty( + (array) $data['media_details']['sizes'], + 'The create response should not carry sub-sizes yet.' + ); + + $request = new WP_REST_Request( 'POST', "/wp/v2/media/{$attachment_id}/sideload" ); + $request->set_header( 'Content-Type', 'image/jpeg' ); + $request->set_header( 'Content-Disposition', 'attachment; filename=finalize-response-test-150x150.jpg' ); + $request->set_param( 'image_size', 'thumbnail' ); + $request->set_body( (string) file_get_contents( DIR_TESTDATA . '/images/test-image.jpg' ) ); + + $response = rest_get_server()->dispatch( $request ); + $thumbnail_data = $response->get_data(); + $this->assertSame( 200, $response->get_status(), 'Sideloading the thumbnail should succeed.' ); + + $request = new WP_REST_Request( 'POST', "/wp/v2/media/{$attachment_id}/finalize" ); + $request->set_param( 'sub_sizes', array( $thumbnail_data ) ); + + $response = rest_get_server()->dispatch( $request ); + $this->assertSame( 200, $response->get_status() ); + + $data = $response->get_data(); + $this->assertArrayHasKey( 'media_details', $data ); + $this->assertArrayHasKey( + 'thumbnail', + $data['media_details']['sizes'], + 'The finalize response should list the sideloaded sub-size.' + ); + + // source_url is what the Image block's Resolution control offers. + $this->assertArrayHasKey( + 'source_url', + $data['media_details']['sizes']['thumbnail'], + 'Each sub-size in the finalize response should carry its URL.' + ); + $this->assertStringEndsWith( + 'finalize-response-test-150x150.jpg', + $data['media_details']['sizes']['thumbnail']['source_url'] + ); + + // The finalize response must match what a later read would return, as + // the editor stores it in place of that read. + $request = new WP_REST_Request( 'GET', "/wp/v2/media/{$attachment_id}" ); + $request->set_param( 'context', 'view' ); + $fetched = rest_get_server()->dispatch( $request )->get_data(); + + $this->assertSame( + array_keys( (array) $fetched['media_details']['sizes'] ), + array_keys( (array) $data['media_details']['sizes'] ), + 'The finalize response should carry the same sizes a refetch would.' + ); + } + + /** + * Verifies that the finalize response reflects the post row as it stands + * after the metadata has been generated. + * + * finalize_item() applies the 'wp_generate_attachment_metadata' filter + * before preparing its response, and a callback is free to rewrite the + * attachment's post row - an optimizer that converts the file updates + * post_mime_type, for instance. The editor stores this response as its + * copy of the record rather than reading the attachment again, so + * anything stale here is what the block keeps for the session. + * + * @ticket 66056 + * + * @covers WP_REST_Attachments_Controller::finalize_item + */ + public function test_finalize_response_reflects_post_row_changed_by_metadata_filter(): void { + $this->enable_client_side_media_processing(); + + wp_set_current_user( self::$author_id ); + + $request = new WP_REST_Request( 'POST', '/wp/v2/media' ); + $request->set_header( 'Content-Type', 'image/jpeg' ); + $request->set_header( 'Content-Disposition', 'attachment; filename=filtered-post-row.jpg' ); + $request->set_param( 'generate_sub_sizes', false ); + $request->set_param( 'title', 'Original title' ); + $request->set_body( (string) file_get_contents( DIR_TESTDATA . '/images/canola.jpg' ) ); + + $attachment_id = rest_get_server()->dispatch( $request )->get_data()['id']; + + $request = new WP_REST_Request( 'POST', "/wp/v2/media/{$attachment_id}/sideload" ); + $request->set_header( 'Content-Type', 'image/jpeg' ); + $request->set_header( 'Content-Disposition', 'attachment; filename=filtered-post-row-150x150.jpg' ); + $request->set_param( 'image_size', 'thumbnail' ); + $request->set_body( (string) file_get_contents( DIR_TESTDATA . '/images/test-image.jpg' ) ); + + $thumbnail_data = rest_get_server()->dispatch( $request )->get_data(); + + // Stands in for a plugin that rewrites the post row as the metadata is + // generated. Added after the upload so only finalize runs it. + add_filter( + 'wp_generate_attachment_metadata', + static function ( $metadata, $id ) { + wp_update_post( + array( + 'ID' => $id, + 'post_title' => 'Rewritten while generating metadata', + ) + ); + return $metadata; + }, + 10, + 2 + ); + + $request = new WP_REST_Request( 'POST', "/wp/v2/media/{$attachment_id}/finalize" ); + $request->set_param( 'sub_sizes', array( $thumbnail_data ) ); + + $response = rest_get_server()->dispatch( $request ); + $this->assertSame( 200, $response->get_status() ); + + $this->assertSame( + 'Rewritten while generating metadata', + get_post( $attachment_id )->post_title, + 'The filter should have rewritten the stored post row.' + ); + + $this->assertSame( + 'Rewritten while generating metadata', + $response->get_data()['title']['raw'], + 'The finalize response should carry the rewritten post row, not the row as it was before the metadata was generated.' + ); + } + + /** + * Verifies that finalize fails when the attachment no longer exists by the + * time its response is prepared. + * + * A 'wp_generate_attachment_metadata' callback that rejects the file and + * deletes the attachment must not be answered with a 200 built from the row + * as it was before the callback ran: the editor would store that stale + * record and report the upload as complete. + * + * @ticket 66056 + * + * @covers WP_REST_Attachments_Controller::finalize_item + */ + public function test_finalize_fails_when_metadata_filter_deletes_attachment(): void { + $this->enable_client_side_media_processing(); + + wp_set_current_user( self::$author_id ); + + $request = new WP_REST_Request( 'POST', '/wp/v2/media' ); + $request->set_header( 'Content-Type', 'image/jpeg' ); + $request->set_header( 'Content-Disposition', 'attachment; filename=deleted-while-finalizing.jpg' ); + $request->set_param( 'generate_sub_sizes', false ); + $request->set_body( (string) file_get_contents( DIR_TESTDATA . '/images/canola.jpg' ) ); + + $attachment_id = rest_get_server()->dispatch( $request )->get_data()['id']; + + add_filter( + 'wp_generate_attachment_metadata', + static function ( $metadata, $id ) { + wp_delete_attachment( $id, true ); + return $metadata; + }, + 10, + 2 + ); + + $request = new WP_REST_Request( 'POST', "/wp/v2/media/{$attachment_id}/finalize" ); + $request->set_param( 'sub_sizes', array() ); + + $response = rest_get_server()->dispatch( $request ); + + $this->assertErrorResponse( 'rest_post_invalid_id', $response, 404 ); + } + /** * Tests that the sideload route declares `convert_format` as a boolean arg. * From 126a9ea87e6dcef5cae9e4b405215fd5a2babd75 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Wed, 9 Sep 2026 19:38:38 +0000 Subject: [PATCH 458/634] Administration: Prevent fatal error in sprintf replacement in tooltips. If HTML passed directly the `button` argument of `wp_get_tooltip_helper()` contained a `%` character, this was interpreted as a placeholder for `sprintf()`, causing a PHP fatal due to a mismatch in argument count. Use the WP_HTML_Tag_Processor to fully construct the button HTML before running sprintf, so that supplied `%` characters are part of the value instead of the format string. Props ekamran, parthjoginyusoft, sc0ttkclark, jack960330, adamsilverstein, joedolson. Fixes #65914. git-svn-id: https://develop.svn.wordpress.org/trunk@63566 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/general-template.php | 96 ++++++++++------ tests/phpunit/tests/general/wpGetTooltip.php | 115 +++++++++++++++++++ 2 files changed, 177 insertions(+), 34 deletions(-) diff --git a/src/wp-includes/general-template.php b/src/wp-includes/general-template.php index 63a3aa67123b2..0e35894fd47c4 100644 --- a/src/wp-includes/general-template.php +++ b/src/wp-includes/general-template.php @@ -390,7 +390,7 @@ function get_search_form( $args = array() ) { * @type string $id Unique ID for the popover element. Default is a * generated unique ID. * @type string $button Existing `button` or `a` markup. Used instead of generated button. - * Default standard button HTML. + * Default empty string. * @type string $label Not used for tooltips. * @type string $close_label Not used for tooltips. * @type string $icon Dashicons icon class for the toggle button. @@ -420,7 +420,7 @@ function wp_get_tooltip( $content, $args = array() ) { * @type string $id Unique ID for the popover element. Default is a * generated unique ID. * @type string $button Existing `button` markup. Used instead of generated button. - * Default standard button HTML. + * Default empty string. * @type string $label Accessible label for the toggle button. * Default 'Help', matching the default icon. * Ignored for tooltips. @@ -455,7 +455,7 @@ function wp_get_toggletip( $content, $args = array() ) { * @type string $id Unique ID for the popover element. Default is a * generated unique ID. * @type string $button Existing `button` or `a` markup. Used instead of generated button. - * Default standard button HTML. + * Default empty string. * @type string $label Accessible label for the toggle button. * Default 'Help', matching the default icon. * Ignored for tooltips. @@ -479,7 +479,7 @@ function wp_get_tooltip_helper( $content, $args = array() ) { $defaults = array( 'id' => wp_unique_id( 'wp-tooltip-' ), - 'button' => '', + 'button' => '', 'label' => __( 'Help' ), 'close_label' => __( 'Close' ), 'icon' => 'dashicons-editor-help', @@ -494,39 +494,67 @@ function wp_get_tooltip_helper( $content, $args = array() ) { $classes .= ' ' . $args['class']; } - $icon = ( $args['icon'] ) ? trim( $args['icon'] ) : $defaults['icon']; - $id = ( $args['id'] ) ? $args['id'] : $defaults['id']; - $button = ( $args['button'] ) ? $args['button'] : $defaults['button']; - $processed = false; + $icon = ( $args['icon'] ) ? trim( $args['icon'] ) : $defaults['icon']; + $id = ( $args['id'] ) ? $args['id'] : $defaults['id']; + + // Tooltips use the content as the accessible name; toggletips use the label. + $label = ( 'tooltip' === $args['type'] ) ? wp_strip_all_tags( $content, true ) : $args['label']; + + /* + * The generated button is a plain skeleton. Every dynamic attribute is + * added through the tag processor below, so caller-supplied markup is + * never scanned or substituted and a percent sign in custom markup, + * such as a percent-encoded URL, is never treated as a conversion + * specification. + */ + $default_button = ''; + + $is_default = ! $args['button']; + $button = ( $args['button'] ) ? $args['button'] : $default_button; + + // The accepted root element is a `button`, or an `a` for tooltips. + $tag = false; $processor = new WP_HTML_Tag_Processor( $button ); if ( true === $processor->next_tag( 'button' ) ) { - $processor->add_class( 'wp-tooltip__toggle' ); - if ( 'tooltip' !== $args['type'] ) { - $processor->set_attribute( 'popovertarget', '%2$s' ); - $processor->set_attribute( 'aria-haspopup', 'dialog' ); - } - $button = $processor->get_updated_html(); - $processed = true; + $tag = 'button'; } else { - // Reset processor. $processor = new WP_HTML_Tag_Processor( $button ); - if ( true === $processor->next_tag( 'a' ) && 'tooltip' === $args['type'] ) { - $processor->add_class( 'wp-tooltip__toggle' ); - $button = $processor->get_updated_html(); - $processed = true; + if ( 'tooltip' === $args['type'] && true === $processor->next_tag( 'a' ) ) { + $tag = 'a'; } } - if ( ! $processed ) { - // Button HTML passed was not valid. - $processor = new WP_HTML_Tag_Processor( $defaults['button'] ); - $processor->add_class( 'wp-tooltip__toggle' ); - if ( 'tooltip' !== $args['type'] ) { - $processor->set_attribute( 'popovertarget', '%2$s' ); - $processor->set_attribute( 'aria-haspopup', 'dialog' ); - } - $button = $processor->get_updated_html(); + + if ( false === $tag ) { + // Button HTML passed was not valid. Reset to default. + $is_default = true; + $button = $default_button; + $processor = new WP_HTML_Tag_Processor( $button ); + $processor->next_tag( 'button' ); + $tag = 'button'; } + /* + * Attributes that apply to every accepted button are added in one pass. + * Attributes that name the control are only added when the caller's + * markup did not already provide them. + */ + if ( null === $processor->get_attribute( 'aria-label' ) ) { + $processor->set_attribute( 'aria-label', $label ); + } + $processor->add_class( 'wp-tooltip__toggle' ); + if ( 'button' === $tag && 'tooltip' !== $args['type'] ) { + $processor->set_attribute( 'popovertarget', $id ); + $processor->set_attribute( 'aria-haspopup', 'dialog' ); + } + + // The generated button also carries the dashicon on its inner span. + if ( $is_default && true === $processor->next_tag( 'span' ) ) { + $processor->set_attribute( 'class', 'dashicons ' . $icon ); + $processor->set_attribute( 'aria-hidden', 'true' ); + } + + $button = $processor->get_updated_html(); + /* * The markup only uses phrasing content so it is valid when nested * in a phrasing context. Sectioning content (e.g. `div`, `dialog`) will @@ -534,11 +562,9 @@ function wp_get_tooltip_helper( $content, $args = array() ) { * the layout. See #65660. */ if ( 'tooltip' === $args['type'] ) { - // Tooltips are only used to visually display labels. - $label = wp_strip_all_tags( $content, true ); $markup = sprintf( ' - ' . $button . ' + %6$s ' . '%5$s' . '' . @@ -548,6 +574,7 @@ function wp_get_tooltip_helper( $content, $args = array() ) { esc_attr( $label ), esc_attr( $icon ), esc_html( $content ), + $button, ); } else { /* @@ -557,7 +584,7 @@ function wp_get_tooltip_helper( $content, $args = array() ) { */ $markup = sprintf( ' - ' . $button . ' + %7$s ' . '%5$s' . '', + ) + ); + + $this->assertStringContainsString( 'aria-label="Helpful text."', $html, 'A custom button without an accessible name should gain one from the content.' ); + + $html2 = wp_get_tooltip( + 'Helpful text.', + array( + 'button' => '', + ) + ); + + $this->assertStringContainsString( 'aria-label="Custom name"', $html2, 'A caller-supplied aria-label should be preserved.' ); + $this->assertStringNotContainsString( 'aria-label="Helpful text."', $html2, 'The generated label should not overwrite the caller-supplied one.' ); + } + /** * Tests that the accessible labels are output and escaped in attributes. * @@ -206,6 +233,94 @@ public function test_wp_get_toggletip_bubble_uses_dialog_role_and_autofocus() { $this->assertStringContainsString( 'tabindex="-1" autofocus>', $html ); } + /** + * Tests that a percent sign in the button markup is not treated as a + * `sprintf()` conversion specification. + * + * @ticket 65914 + * + * @dataProvider data_button_markup_containing_percent_signs + * + * @param string $button Button markup containing a percent sign. + * @param string $expected Substring that must be preserved in the output. + */ + public function test_wp_get_tooltip_preserves_percent_signs_in_button_markup( $button, $expected ) { + $this->assertStringContainsString( + $expected, + wp_get_tooltip( 'Helpful text.', array( 'button' => $button ) ), + 'The tooltip did not preserve the percent sign.' + ); + $this->assertStringContainsString( + $expected, + wp_get_toggletip( 'Helpful text.', array( 'button' => $button ) ), + 'The toggletip did not preserve the percent sign.' + ); + } + + /** + * Tests that a percent-encoded URL in anchor markup is not rewritten. + * + * @ticket 65914 + * + * @dataProvider data_percent_encoded_hrefs + * + * @param string $href A percent-encoded URL. + */ + public function test_wp_get_tooltip_preserves_percent_encoding_in_anchor_href( $href ) { + $html = wp_get_tooltip( + 'Helpful text.', + array( 'button' => 'Search' ) + ); + + $this->assertStringContainsString( 'href="' . $href . '"', $html ); + } + + /** + * Data provider. + * + * @return array[] + */ + public function data_percent_encoded_hrefs() { + return array( + 'an encoded space' => array( '/wp-admin/edit.php?s=hello%20world' ), + 'an encoded slash' => array( '/x?p=a%2Fb' ), + ); + } + + /** + * Data provider. + * + * @return array[] + */ + public function data_button_markup_containing_percent_signs() { + return array( + 'a literal percent sign' => array( + '', + '100% done', + ), + 'a percent sign then a word' => array( + '', + 'Save 20%!', + ), + 'an unknown format specifier' => array( + '', + 'Buy %q now', + ), + 'a percent sign in an ID' => array( + '', + 'aria-describedby="box_100%_complete-title"', + ), + 'a percent-encoded ID' => array( + '', + 'aria-describedby="meta-%d0%b8%d0%b3%d1%80%d0%b0-title"', + ), + 'text resembling a argnum' => array( + '', + 'Use %2$s in your code', + ), + ); + } + /** * Data provider. * From 8f6799a4e5ed4071ead29572c020fa9c1df0a7f5 Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Wed, 9 Sep 2026 19:49:38 +0000 Subject: [PATCH 459/634] Code Modernization: Use `array_key_first()` to read the first key of an array. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reading the first key of an array through `array_keys()` allocates a full array of every key just to keep one entry and discard the rest. `array_key_first()` reads the first bucket directly. Follow-up to r63297 / #65773, which is scoped to the two nested `current( array_keys( $array ) )` call sites. This commit covers a second shape of the same idea, which that ticket does not include: the key array is assigned to a variable first, then read on the next line. {{{ $keys = array_keys( $wp_registered_sidebars ); $sidebar = reset( $keys ); }}} {{{ $sidebar = array_key_first( $wp_registered_sidebars ); }}} 13 occurrences across 11 files, in two shapes — `reset( $keys )` and `$keys[0]`. In every case the intermediate variable existed only to carry the key array to the next line and is never read again afterwards. **One change that goes further** In `spawn_cron()` and `_wp_cron()` the surrounding check is dropped too: {{{ $keys = array_keys( $crons ); if ( isset( $keys[0] ) && $keys[0] > $gmt_time ) { }}} {{{ if ( array_key_first( $crons ) > $gmt_time ) { }}} Both functions return early a few lines above when `$crons` is empty, so `isset( $keys[0] )` can never be false there. **Behavior notes** - On an empty array `reset()` returns `false` while `array_key_first()` returns `null`. None of the touched call sites compares the result with `===`, and most sit behind an `empty()` guard. - Where the old code used `$keys[0]`, the new code is strictly safer: `$keys[0]` emitted a notice on an empty array, `array_key_first()` returns `null` quietly. Developed in https://github.com/WordPress/wordpress-develop/pull/12790. Follow-up to r63297. Props Soean, mukesh27. See #65773. git-svn-id: https://develop.svn.wordpress.org/trunk@63567 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/import.php | 3 +-- src/wp-admin/includes/class-plugin-upgrader.php | 4 +--- src/wp-admin/includes/media.php | 7 +++---- src/wp-admin/includes/plugin-install.php | 3 +-- src/wp-admin/includes/revision.php | 3 +-- src/wp-admin/plugin-editor.php | 3 +-- src/wp-admin/widgets-form.php | 3 +-- src/wp-includes/class-wp-query.php | 5 ++--- src/wp-includes/cron.php | 6 ++---- .../endpoints/class-wp-rest-block-directory-controller.php | 4 +--- src/wp-includes/widgets/class-wp-widget-tag-cloud.php | 3 +-- 11 files changed, 15 insertions(+), 29 deletions(-) diff --git a/src/wp-admin/import.php b/src/wp-admin/import.php index ce17a70f20cf3..98ecd9bb3836a 100644 --- a/src/wp-admin/import.php +++ b/src/wp-admin/import.php @@ -118,8 +118,7 @@ // Looks like an importer is installed, but not active. $plugins = get_plugins( '/' . $plugin_slug ); if ( ! empty( $plugins ) ) { - $keys = array_keys( $plugins ); - $plugin_file = $plugin_slug . '/' . $keys[0]; + $plugin_file = $plugin_slug . '/' . array_key_first( $plugins ); $url = wp_nonce_url( add_query_arg( array( diff --git a/src/wp-admin/includes/class-plugin-upgrader.php b/src/wp-admin/includes/class-plugin-upgrader.php index f5290ff5258f6..5361c63821c14 100644 --- a/src/wp-admin/includes/class-plugin-upgrader.php +++ b/src/wp-admin/includes/class-plugin-upgrader.php @@ -542,9 +542,7 @@ public function plugin_info() { } // Assume the requested plugin is the first in the list. - $plugin_files = array_keys( $plugin ); - - return $this->result['destination_name'] . '/' . $plugin_files[0]; + return $this->result['destination_name'] . '/' . array_key_first( $plugin ); } /** diff --git a/src/wp-admin/includes/media.php b/src/wp-admin/includes/media.php index be10d2f7bf0b6..beaf88101e648 100644 --- a/src/wp-admin/includes/media.php +++ b/src/wp-admin/includes/media.php @@ -796,8 +796,7 @@ function media_upload_form_handler() { $errors = null; if ( isset( $_POST['send'] ) ) { - $keys = array_keys( $_POST['send'] ); - $send_id = (int) reset( $keys ); + $send_id = (int) array_key_first( $_POST['send'] ); } if ( ! empty( $_POST['attachments'] ) ) { @@ -1685,8 +1684,8 @@ function get_media_item( $attachment_id, $args = null ) { $title = esc_attr( $post->post_title ); $post_mime_types = get_post_mime_types(); - $keys = array_keys( wp_match_mime_types( array_keys( $post_mime_types ), $post->post_mime_type ) ); - $type = reset( $keys ); + $matched_types = wp_match_mime_types( array_keys( $post_mime_types ), $post->post_mime_type ); + $type = array_key_first( $matched_types ) ?? ''; $type_html = ""; $form_fields = get_attachment_fields_to_edit( $post, $parsed_args['errors'] ); diff --git a/src/wp-admin/includes/plugin-install.php b/src/wp-admin/includes/plugin-install.php index 62e93a36eef5d..b37b956d3455c 100644 --- a/src/wp-admin/includes/plugin-install.php +++ b/src/wp-admin/includes/plugin-install.php @@ -593,8 +593,7 @@ function install_plugin_information() { // Default to the Description tab, Do not translate, API returns English. $section = isset( $_REQUEST['section'] ) ? wp_unslash( $_REQUEST['section'] ) : 'description'; if ( empty( $section ) || ! isset( $api->sections[ $section ] ) ) { - $section_titles = array_keys( (array) $api->sections ); - $section = reset( $section_titles ); + $section = array_key_first( (array) $api->sections ); } iframe_header( __( 'Plugin Installation' ) ); diff --git a/src/wp-admin/includes/revision.php b/src/wp-admin/includes/revision.php index 2f15f1c9e2faf..ec58011f7a3a0 100644 --- a/src/wp-admin/includes/revision.php +++ b/src/wp-admin/includes/revision.php @@ -325,8 +325,7 @@ function wp_prepare_revisions_for_js( $post, $selected_revision_id, $from = null if ( ! $compare_two_mode ) { $found = array_search( $selected_revision_id, array_keys( $revisions ), true ); if ( $found ) { - $from = array_keys( array_slice( $revisions, $found - 1, 1, true ) ); - $from = reset( $from ); + $from = array_key_first( array_slice( $revisions, $found - 1, 1, true ) ); } else { $from = 0; } diff --git a/src/wp-admin/plugin-editor.php b/src/wp-admin/plugin-editor.php index 4beee7b8409da..b129a7652b28b 100644 --- a/src/wp-admin/plugin-editor.php +++ b/src/wp-admin/plugin-editor.php @@ -71,8 +71,7 @@ $plugin = $file; } } else { - $plugin = array_keys( $plugins ); - $plugin = $plugin[0]; + $plugin = array_key_first( $plugins ); } } diff --git a/src/wp-admin/widgets-form.php b/src/wp-admin/widgets-form.php index e47905c5d0099..25ee8215b9678 100644 --- a/src/wp-admin/widgets-form.php +++ b/src/wp-admin/widgets-form.php @@ -229,8 +229,7 @@ if ( isset( $_GET['addnew'] ) ) { // Default to the first sidebar. - $keys = array_keys( $wp_registered_sidebars ); - $sidebar = reset( $keys ); + $sidebar = array_key_first( $wp_registered_sidebars ); if ( isset( $_GET['base'] ) && isset( $_GET['num'] ) ) { // Multi-widget. // Copy minimal info from an existing instance of this widget to a new instance. diff --git a/src/wp-includes/class-wp-query.php b/src/wp-includes/class-wp-query.php index 9385ae832ff66..1d6b652c5a610 100644 --- a/src/wp-includes/class-wp-query.php +++ b/src/wp-includes/class-wp-query.php @@ -4028,9 +4028,8 @@ public function get_queried_object() { } else { // For other tax queries, grab the first term from the first clause. if ( ! empty( $this->tax_query->queried_terms ) ) { - $queried_taxonomies = array_keys( $this->tax_query->queried_terms ); - $matched_taxonomy = reset( $queried_taxonomies ); - $query = $this->tax_query->queried_terms[ $matched_taxonomy ]; + $matched_taxonomy = array_key_first( $this->tax_query->queried_terms ); + $query = $this->tax_query->queried_terms[ $matched_taxonomy ]; if ( ! empty( $query['terms'] ) ) { if ( 'term_id' === $query['field'] ) { diff --git a/src/wp-includes/cron.php b/src/wp-includes/cron.php index 82889d7cc7e2f..1070ae4680b91 100644 --- a/src/wp-includes/cron.php +++ b/src/wp-includes/cron.php @@ -929,8 +929,7 @@ function spawn_cron( $gmt_time = 0 ) { return false; } - $keys = array_keys( $crons ); - if ( isset( $keys[0] ) && $keys[0] > $gmt_time ) { + if ( array_key_first( $crons ) > $gmt_time ) { return false; } @@ -1059,8 +1058,7 @@ function _wp_cron() { } $gmt_time = microtime( true ); - $keys = array_keys( $crons ); - if ( isset( $keys[0] ) && $keys[0] > $gmt_time ) { + if ( array_key_first( $crons ) > $gmt_time ) { return 0; } diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-block-directory-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-block-directory-controller.php index c2c92efbbcd22..31267f9600671 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-block-directory-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-block-directory-controller.php @@ -200,9 +200,7 @@ protected function find_plugin_for_slug( $slug ) { return ''; } - $plugin_files = array_keys( $plugin_files ); - - return $slug . '/' . reset( $plugin_files ); + return $slug . '/' . array_key_first( $plugin_files ); } /** diff --git a/src/wp-includes/widgets/class-wp-widget-tag-cloud.php b/src/wp-includes/widgets/class-wp-widget-tag-cloud.php index c56a774b111a4..aeb3c09ce8e10 100644 --- a/src/wp-includes/widgets/class-wp-widget-tag-cloud.php +++ b/src/wp-includes/widgets/class-wp-widget-tag-cloud.php @@ -169,8 +169,7 @@ public function form( $instance ) { // Just a single tag cloud supporting taxonomy found, no need to display a select. case 1: - $keys = array_keys( $taxonomies ); - $taxonomy = reset( $keys ); + $taxonomy = array_key_first( $taxonomies ); ?> Date: Wed, 9 Sep 2026 21:11:48 +0000 Subject: [PATCH 460/634] Docs: Update outdated upstream Chrome documentation link in `WP_Site_Icon`. Props mayur8991, harishtewari, logicrays, sabernhardt. Fixes #65940. git-svn-id: https://develop.svn.wordpress.org/trunk@63568 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/includes/class-wp-site-icon.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/wp-admin/includes/class-wp-site-icon.php b/src/wp-admin/includes/class-wp-site-icon.php index ea0ab35007327..542bddbb4a1e7 100644 --- a/src/wp-admin/includes/class-wp-site-icon.php +++ b/src/wp-admin/includes/class-wp-site-icon.php @@ -48,8 +48,7 @@ class WP_Site_Icon { /* * App icon for Android/Chrome. * - * @link https://developers.google.com/web/updates/2014/11/Support-for-theme-color-in-Chrome-39-for-Android - * @link https://developer.chrome.com/multidevice/android/installtohomescreen + * @link https://developer.chrome.com/blog/support-for-theme-color-in-chrome-39-for-android */ 192, From 27cb8012ac0b45c47f339fc04bb53b0f69af2f50 Mon Sep 17 00:00:00 2001 From: Jb Audras Date: Wed, 9 Sep 2026 21:17:25 +0000 Subject: [PATCH 461/634] Docs: Replace `@see` with `@link` in `WP_Site_Icon` various docblocks. This changeset ensures these external links declaration is consistent with WordPress/PHP Documentation Standards. See #65860. git-svn-id: https://develop.svn.wordpress.org/trunk@63569 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/includes/class-wp-site-icon.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp-admin/includes/class-wp-site-icon.php b/src/wp-admin/includes/class-wp-site-icon.php index 542bddbb4a1e7..411302385cda9 100644 --- a/src/wp-admin/includes/class-wp-site-icon.php +++ b/src/wp-admin/includes/class-wp-site-icon.php @@ -41,7 +41,7 @@ class WP_Site_Icon { /* * Square, medium sized tiles for IE11+. * - * See https://msdn.microsoft.com/library/dn455106(v=vs.85).aspx + * @link https://msdn.microsoft.com/library/dn455106(v=vs.85).aspx */ 270, @@ -55,7 +55,7 @@ class WP_Site_Icon { /* * App icons up to iPhone 6 Plus. * - * See https://developer.apple.com/library/prerelease/ios/documentation/UserExperience/Conceptual/MobileHIG/IconMatrix.html + * @link https://developer.apple.com/library/prerelease/ios/documentation/UserExperience/Conceptual/MobileHIG/IconMatrix.html */ 180, From 285d4d10cdb2edf19c01d5592cabb32452014f16 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Wed, 9 Sep 2026 22:24:50 +0000 Subject: [PATCH 462/634] Sitemaps: Don't 404 valid sitemaps on sites with no posts. `WP::handle_404()` sets a 404 when the main query matches no posts and no exception applies. Sitemap requests were never among those exceptions; they were shielded only incidentally, by falling through to `is_home`, and in r62664 that fallthrough was removed. A site with no published posts therefore served a complete, valid sitemap under a 404 status, which search engines discard. Exempt sitemap and stylesheet routes there, alongside the existing admin, robots and favicon exceptions. Since `handle_404()` no longer decides the status for these requests, every sitemap 404 now has to be issued by `WP_Sitemaps::render_sitemaps()` instead: an unregistered provider, an unrecognized stylesheet type, and a route whose query vars do not survive `sanitize_text_field()` would each otherwise be served as a 200 on an arbitrary URL. These share a `send_404()` helper, which also sends the no-cache headers `handle_404()` was previously contributing, so an intermediary does not retain a 404 for a route that becomes valid once the site has more content. Sitemaps disabled via the `wp_sitemaps_enabled` filter, and providers with an empty URL list, keep the status they already had; whether the latter should render an empty sitemap instead is #61293. Developed in https://github.com/WordPress/wordpress-develop/pull/13247. Follow-up to r48072, r48523, r62664. Props iamchitti, westonruter, fernandot, wildworks, harishtewari, l1onofjudah, luksusspokoju, abrahamfariaz, andreasca, siliconforks, adamsilverstein, audrasjb, ocean90, mrkenobi. See #39157, #61293. Fixes #65945. git-svn-id: https://develop.svn.wordpress.org/trunk@63570 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/class-wp.php | 5 +- .../sitemaps/class-wp-sitemaps.php | 52 ++++++-- tests/phpunit/tests/sitemaps/sitemaps.php | 104 ++++++++++++++++ tests/phpunit/tests/wp/handle404.php | 117 ++++++++++++++++++ 4 files changed, 268 insertions(+), 10 deletions(-) create mode 100644 tests/phpunit/tests/wp/handle404.php diff --git a/src/wp-includes/class-wp.php b/src/wp-includes/class-wp.php index f1664747d4042..ad6ce74b1716e 100644 --- a/src/wp-includes/class-wp.php +++ b/src/wp-includes/class-wp.php @@ -746,8 +746,9 @@ public function handle_404() { $set_404 = true; - // Never 404 for the admin, robots, or favicon. - if ( is_admin() || is_robots() || is_favicon() ) { + // Never 404 here for the admin, robots, favicon, or sitemaps. + // Sitemap routes send their own status in WP_Sitemaps::render_sitemaps(). + if ( is_admin() || is_robots() || is_favicon() || is_sitemap() || get_query_var( 'sitemap-stylesheet' ) ) { $set_404 = false; // If posts were found, check for paged content. diff --git a/src/wp-includes/sitemaps/class-wp-sitemaps.php b/src/wp-includes/sitemaps/class-wp-sitemaps.php index d4bbe38c86b11..87b3765b3f2e3 100644 --- a/src/wp-includes/sitemaps/class-wp-sitemaps.php +++ b/src/wp-includes/sitemaps/class-wp-sitemaps.php @@ -157,30 +157,45 @@ public function register_rewrites() { * Renders sitemap templates based on rewrite rules. * * @since 5.5.0 - * - * @global WP_Query $wp_query WordPress Query object. */ public function render_sitemaps() { - global $wp_query; + /* + * Bail early if this isn't a sitemap or stylesheet route. + * + * This runs on every front-end request, so it comes before any + * sanitizing. The raw query vars are tested here, matching + * WP::handle_404(), which exempts sitemap requests from its own 404 on + * the same basis. Testing the sanitized values instead would let a + * request that handle_404() exempted fall through both, leaving it a 200. + */ + if ( ! get_query_var( 'sitemap' ) && ! get_query_var( 'sitemap-stylesheet' ) ) { + return; + } $sitemap = sanitize_text_field( get_query_var( 'sitemap' ) ); $object_subtype = sanitize_text_field( get_query_var( 'sitemap-subtype' ) ); $stylesheet_type = sanitize_text_field( get_query_var( 'sitemap-stylesheet' ) ); $paged = absint( get_query_var( 'paged' ) ); - // Bail early if this isn't a sitemap or stylesheet route. + // Force a 404 and bail early if the route did not survive sanitizing. if ( ! ( $sitemap || $stylesheet_type ) ) { + $this->send_404(); return; } if ( ! $this->sitemaps_enabled() ) { - $wp_query->set_404(); - status_header( 404 ); + $this->send_404(); return; } // Render stylesheet if this is stylesheet route. if ( $stylesheet_type ) { + // Force a 404 and bail early if the stylesheet type is not recognized. + if ( ! in_array( $stylesheet_type, array( 'sitemap', 'index' ), true ) ) { + $this->send_404(); + return; + } + $stylesheet = new WP_Sitemaps_Stylesheet(); $stylesheet->render_stylesheet( $stylesheet_type ); @@ -197,7 +212,9 @@ public function render_sitemaps() { $provider = $this->registry->get_provider( $sitemap ); + // Force a 404 and bail early if the requested provider is not registered. if ( ! $provider ) { + $this->send_404(); return; } @@ -209,8 +226,7 @@ public function render_sitemaps() { // Force a 404 and bail early if no URLs are present. if ( empty( $url_list ) ) { - $wp_query->set_404(); - status_header( 404 ); + $this->send_404(); return; } @@ -218,6 +234,26 @@ public function render_sitemaps() { exit; } + /** + * Sends a 404 for a sitemap route that cannot be served. + * + * WP::handle_404() exempts sitemap requests, so every sitemap 404 is issued + * here instead. That includes the no-cache headers handle_404() sends with + * its own 404, so an intermediary does not retain a 404 for a route that + * becomes valid once the site has more content. + * + * @since 7.1.1 + * + * @global WP_Query $wp_query WordPress Query object. + */ + private function send_404(): void { + global $wp_query; + + $wp_query->set_404(); + status_header( 404 ); + nocache_headers(); + } + /** * Redirects a URL to the wp-sitemap.xml * diff --git a/tests/phpunit/tests/sitemaps/sitemaps.php b/tests/phpunit/tests/sitemaps/sitemaps.php index 24243787d5068..3a0d3adc4e675 100644 --- a/tests/phpunit/tests/sitemaps/sitemaps.php +++ b/tests/phpunit/tests/sitemaps/sitemaps.php @@ -493,4 +493,108 @@ public function test_empty_url_list_should_return_404() { $this->assertTrue( is_404() ); } + + /** + * Ensures a paged subtype route with no URLs still 404s, now that + * WP::handle_404() no longer sets a 404 for sitemap requests. + * + * @ticket 65945 + */ + public function test_empty_url_list_for_subtype_should_return_404() { + wp_register_sitemap_provider( 'foo', new WP_Sitemaps_Empty_Test_Provider( 'foo' ) ); + + $this->go_to( home_url( '/?sitemap=foo&sitemap-subtype=bar&paged=2' ) ); + + wp_sitemaps_get_server()->render_sitemaps(); + + $this->assertTrue( is_404() ); + } + + /** + * Ensures a sitemap query var that does not survive sanitizing 404s. + * + * WP::handle_404() exempts these requests on the raw query var, while + * render_sitemaps() acts on the sanitized value. Without a matching bail + * they fall through both and an arbitrary URL is served as a 200. + * + * @ticket 65945 + * + * @dataProvider data_unusable_sitemap_query_vars + * + * @param non-falsy-string $query_string Query string to append to a nonexistent URL. + */ + public function test_unusable_sitemap_query_var_should_return_404( string $query_string ) { + $this->set_permalink_structure( '/%postname%/' ); + + // Instantiate the server before navigating: registering the sitemap + // rewrite tags is what adds the query vars to `$wp->public_query_vars`. + $sitemaps = wp_sitemaps_get_server(); + + $this->go_to( home_url( '/this-page-does-not-exist/' . $query_string ) ); + + $this->assertFalse( is_404(), 'WP::handle_404() should not have set a 404.' ); + + $sitemaps->render_sitemaps(); + + $this->assertTrue( is_404(), 'render_sitemaps() should have set a 404.' ); + } + + /** + * Data provider. + * + * @return array + */ + public function data_unusable_sitemap_query_vars(): array { + return array( + 'value stripped by sanitizing' => array( '?sitemap=<>' ), + 'array sitemap value' => array( '?sitemap[]=index' ), + 'array stylesheet value' => array( '?sitemap-stylesheet[]=sitemap' ), + ); + } + + /** + * Ensures an unrecognized stylesheet type 404s from render_sitemaps(). + * + * WP::handle_404() exempts any request carrying a `sitemap-stylesheet` + * query var, and WP_Sitemaps_Stylesheet::render_stylesheet() echoes nothing + * for a type other than 'sitemap' or 'index', so this route would otherwise + * be served as a 200 with an empty body. + * + * @ticket 65945 + */ + public function test_unrecognized_stylesheet_type_should_return_404() { + // Instantiate the server before navigating: registering the sitemap rewrite + // tags is what adds `sitemap-stylesheet` to `$wp->public_query_vars`. + $sitemaps = wp_sitemaps_get_server(); + + $this->go_to( home_url( '/?sitemap-stylesheet=this-is-not-a-stylesheet' ) ); + + $this->assertFalse( is_404(), 'WP::handle_404() should not have set a 404.' ); + + $sitemaps->render_sitemaps(); + + $this->assertTrue( is_404(), 'render_sitemaps() should have set a 404.' ); + } + + /** + * Ensures an unregistered provider 404s from render_sitemaps(). + * + * WP::handle_404() exempts every sitemap request, so this route would + * otherwise be served with a 200. + * + * @ticket 65945 + */ + public function test_unregistered_provider_should_return_404() { + // Instantiate the server before navigating: registering the sitemap + // rewrite tags is what adds `sitemap` to `$wp->public_query_vars`. + $sitemaps = wp_sitemaps_get_server(); + + $this->go_to( home_url( '/?sitemap=this-provider-does-not-exist' ) ); + + $this->assertFalse( is_404(), 'WP::handle_404() should not have set a 404.' ); + + $sitemaps->render_sitemaps(); + + $this->assertTrue( is_404(), 'render_sitemaps() should have set a 404.' ); + } } diff --git a/tests/phpunit/tests/wp/handle404.php b/tests/phpunit/tests/wp/handle404.php new file mode 100644 index 0000000000000..4b6b55064367e --- /dev/null +++ b/tests/phpunit/tests/wp/handle404.php @@ -0,0 +1,117 @@ +set_permalink_structure( '/%postname%/' ); + + /* + * Priming the server re-registers the sitemap query vars. tear_down() + * replaces the $wp global with a fresh WP instance, which carries only + * the built-in public query vars, and nulls $GLOBALS['wp_sitemaps'] so + * that this call re-runs WP_Sitemaps::init() and adds them back. + */ + wp_sitemaps_get_server(); + } + + /** + * A sitemap request must not be turned into a 404 by an empty main query. + * + * Whether the sitemap exists is decided later by WP_Sitemaps::render_sitemaps(), + * so some of these URLs still 404 in a full request, just not from here. + * + * @ticket 65945 + * + * @dataProvider data_sitemap_requests + * + * @param non-falsy-string $url Sitemap URL to request. + */ + public function test_sitemap_requests_should_not_be_404ed_by_an_empty_main_query( string $url ) { + $this->go_to( home_url( $url ) ); + + $this->assertTrue( is_sitemap(), 'The request should be recognized as a sitemap request.' ); + $this->assertFalse( is_404(), 'WP::handle_404() should not have set a 404.' ); + } + + /** + * Data provider. + * + * @return array + */ + public function data_sitemap_requests(): array { + return array( + 'index' => array( '/?sitemap=index' ), + 'posts provider' => array( '/?sitemap=posts&sitemap-subtype=post' ), + 'posts provider, paged' => array( '/?sitemap=posts&sitemap-subtype=post&paged=2' ), + 'pages provider, paged' => array( '/?sitemap=posts&sitemap-subtype=page&paged=2' ), + 'taxonomies provider' => array( '/?sitemap=taxonomies&sitemap-subtype=category' ), + 'taxonomies provider,paged' => array( '/?sitemap=taxonomies&sitemap-subtype=category&paged=3' ), + 'users provider, paged' => array( '/?sitemap=users&paged=2' ), + ); + } + + /** + * The sitemap stylesheet routes must not be 404ed either. + * + * Covered separately because is_sitemap() only reflects the `sitemap` query var. + * + * @ticket 65945 + * + * @dataProvider data_sitemap_stylesheet_requests + * + * @param non-falsy-string $url Stylesheet URL to request. + */ + public function test_sitemap_stylesheet_requests_should_not_be_404ed_by_an_empty_main_query( string $url ) { + $this->go_to( home_url( $url ) ); + + $this->assertFalse( is_404(), 'WP::handle_404() should not have set a 404.' ); + } + + /** + * Data provider. + * + * @return array + */ + public function data_sitemap_stylesheet_requests(): array { + return array( + 'sitemap stylesheet' => array( '/?sitemap-stylesheet=sitemap' ), + 'index stylesheet' => array( '/?sitemap-stylesheet=index' ), + // Not a real route, but the only stylesheet case is_home() doesn't already cover. + 'sitemap stylesheet, paged' => array( '/?sitemap-stylesheet=sitemap&paged=2' ), + ); + } + + /** + * A genuinely unknown URL must still 404. + * + * @ticket 65945 + */ + public function test_non_sitemap_request_should_still_404() { + $this->go_to( home_url( '/this-page-does-not-exist/' ) ); + + $this->assertFalse( is_sitemap(), 'The request should not be a sitemap request.' ); + $this->assertTrue( is_404(), 'An unknown URL should still be a 404.' ); + } + + /** + * An unregistered sitemap provider must not be turned into a 404 here. + * + * render_sitemaps() sends that status itself, covered in Tests_Sitemaps_Sitemaps. + * + * @ticket 65945 + */ + public function test_unregistered_sitemap_provider_should_not_404_in_handle_404() { + $this->go_to( home_url( '/?sitemap=this-provider-does-not-exist' ) ); + + $this->assertTrue( is_sitemap(), 'The request should be recognized as a sitemap request.' ); + $this->assertFalse( is_404(), 'WP::handle_404() should not have set a 404.' ); + } +} From 90dcece80797dab5aa9688bc712225fc0899c7d7 Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Thu, 10 Sep 2026 09:03:16 +0000 Subject: [PATCH 463/634] General: Enable the JSDoc rule require-param-name. Also, sorts the rules alphabetically in `.eslintrc-jsdoc.js`. Part of the effort to improve JS inline documentation for 7.2. Developed in https://github.com/WordPress/wordpress-develop/pull/13473 See #66033. git-svn-id: https://develop.svn.wordpress.org/trunk@63577 602fd350-edb4-49c9-b593-d223f7449a82 --- .eslintrc-jsdoc.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.eslintrc-jsdoc.js b/.eslintrc-jsdoc.js index 12d2bf9a0922d..e3c98d449f3c5 100644 --- a/.eslintrc-jsdoc.js +++ b/.eslintrc-jsdoc.js @@ -37,7 +37,7 @@ module.exports = [ }, rules: { 'jsdoc/check-param-names': 'error', - 'jsdoc/check-types': 'error', + 'jsdoc/check-syntax': 'error', 'jsdoc/check-tag-names': [ 'error', { definedTags: [ 'memberOf', @@ -46,17 +46,18 @@ module.exports = [ 'link', ], } ], + 'jsdoc/check-types': 'error', + 'jsdoc/require-description': 'error', + 'jsdoc/require-jsdoc': 'error', 'jsdoc/require-param': [ 'error', { enableFixer: false, } ], + 'jsdoc/require-param-name': 'error', 'jsdoc/require-param-type': 'error', + 'jsdoc/require-returns': 'error', 'jsdoc/require-returns-check': 'error', 'jsdoc/require-returns-description': 'error', - 'jsdoc/require-returns': 'error', 'jsdoc/require-returns-type': 'error', - 'jsdoc/check-syntax': 'error', - 'jsdoc/require-description': 'error', - 'jsdoc/require-jsdoc': 'error', }, }, ]; From 50d75551577d0c637d1955dc8ebbb360dd6bf9ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= Date: Thu, 10 Sep 2026 09:48:17 +0000 Subject: [PATCH 464/634] View Config: add form info for root/site entity. Props oandregal, ntsekouras. Part of #65981. git-svn-id: https://develop.svn.wordpress.org/trunk@63578 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/default-filters.php | 1 + src/wp-includes/view-config.php | 33 +++++++++++++++++++ .../rest-api/rest-view-config-controller.php | 29 ++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/src/wp-includes/default-filters.php b/src/wp-includes/default-filters.php index d16979c9c8fb5..a839ef92966b4 100644 --- a/src/wp-includes/default-filters.php +++ b/src/wp-includes/default-filters.php @@ -834,5 +834,6 @@ 5 ); } +add_filter( 'get_entity_view_config_root_site', '_wp_get_entity_view_config_root_site', 5 ); unset( $filter, $action, $post_type ); diff --git a/src/wp-includes/view-config.php b/src/wp-includes/view-config.php index d972515c12438..8765a5d095008 100644 --- a/src/wp-includes/view-config.php +++ b/src/wp-includes/view-config.php @@ -769,3 +769,36 @@ function _wp_get_entity_view_config_posttype_wp_template( $data ) { return $data; } + +/** + * Provides the view configuration for the `root`/`site` entity. + * + * The site settings are a singleton record edited through a form (the site + * editor's Identity screen) rather than listed in a view, so only the `form` + * is defined here. The generic `default_view`, `default_layouts`, and + * `view_list` built by wp_get_entity_view_config() are left untouched. + * + * @since 7.2.0 + * + * @param WP_View_Config_Data $data The view configuration container for the entity. + * @return WP_View_Config_Data The updated view configuration container. + */ +function _wp_get_entity_view_config_root_site( $data ) { + return $data->set( + array( + 'form' => array( + 'layout' => array( + 'type' => 'regular', + 'labelPosition' => 'top', + ), + 'fields' => array( + 'title', + 'description', + 'site_logo', + 'site_icon', + ), + ), + ), + 1 + ); +} diff --git a/tests/phpunit/tests/rest-api/rest-view-config-controller.php b/tests/phpunit/tests/rest-api/rest-view-config-controller.php index 34fcd55e2466d..c6a7ed86b816d 100644 --- a/tests/phpunit/tests/rest-api/rest-view-config-controller.php +++ b/tests/phpunit/tests/rest-api/rest-view-config-controller.php @@ -302,6 +302,35 @@ public function test_get_items_matches_underlying_config() { $this->assertSame( $config['form'], $data['form'] ); } + /** + * The `root`/`site` entity provides the form of the site identity screen. + * + * @ticket 65981 + * + * @covers ::get_items + */ + public function test_get_items_root_site_form() { + // Admin: reading root config requires `manage_options`. + wp_set_current_user( self::$admin_id ); + + $response = $this->dispatch_request( 'root', 'site' ); + $this->assertSame( 200, $response->get_status() ); + + $data = json_decode( wp_json_encode( $response->get_data() ), true ); + + $this->assertSame( + array( + 'type' => 'regular', + 'labelPosition' => 'top', + ), + $data['form']['layout'] + ); + $this->assertSame( + array( 'title', 'description', 'site_logo', 'site_icon' ), + $data['form']['fields'] + ); + } + /** * Empty object-typed config values serialize as JSON objects ({}), not arrays ([]). * From 8fd586426d7da9034ad1f0808e0914a8390f5521 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 10 Sep 2026 10:48:20 +0000 Subject: [PATCH 465/634] Script Loader: Avoid a false entry in inline script data. `WP_Scripts::get_data()` returns `false` when a handle has no `before` or `after` data, and casting that to an array produced `array( false )`. The first inline script added for a handle was therefore stored after an unused `false` entry. Missing inline script data is now treated as an empty array. Developed in: https://github.com/WordPress/wordpress-develop/pull/12217 Follow-up to r36633. Props vanyukov, sukhendu2002, jonsurrell, apermo. Fixes #52320. git-svn-id: https://develop.svn.wordpress.org/trunk@63579 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/class-wp-scripts.php | 3 +- tests/phpunit/tests/dependencies/scripts.php | 32 ++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/class-wp-scripts.php b/src/wp-includes/class-wp-scripts.php index f8d32d375d040..36a0487bede56 100644 --- a/src/wp-includes/class-wp-scripts.php +++ b/src/wp-includes/class-wp-scripts.php @@ -527,7 +527,8 @@ public function add_inline_script( $handle, $data, $position = 'after' ) { $position = 'before'; } - $script = (array) $this->get_data( $handle, $position ); + $script = $this->get_data( $handle, $position ); + $script = false === $script ? array() : (array) $script; $script[] = $data; return $this->add_data( $handle, $position, $script ); diff --git a/tests/phpunit/tests/dependencies/scripts.php b/tests/phpunit/tests/dependencies/scripts.php index 1fabd1dbe4f35..63e5947e50abe 100644 --- a/tests/phpunit/tests/dependencies/scripts.php +++ b/tests/phpunit/tests/dependencies/scripts.php @@ -230,6 +230,38 @@ public function data_provider_delayed_strategies() { ); } + /** + * Tests that inline scripts do not include a false entry when no data exists yet. + * + * @ticket 52320 + * @dataProvider data_inline_script_positions + * + * @param string $position Inline script position. + */ + public function test_add_inline_script_does_not_store_false_for_empty_existing_data( $position ): void { + $handle = 'test-inline-script-' . $position; + + wp_register_script( $handle, '/test.js', array(), null ); + wp_add_inline_script( $handle, 'console.log( "test" );', $position ); + + $this->assertSame( + array( 'console.log( "test" );' ), + wp_scripts()->get_data( $handle, $position ) + ); + } + + /** + * Data provider for inline script positions. + * + * @return array Inline script positions. + */ + public function data_inline_script_positions(): array { + return array( + 'before' => array( 'before' ), + 'after' => array( 'after' ), + ); + } + /** * Tests that inline scripts in the `after` position, attached to delayed main scripts, remain unaffected. * From 3b66b016e8fbfa828a0c48b16320efdc67ef2aa3 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 10 Sep 2026 11:18:52 +0000 Subject: [PATCH 466/634] I18N: Validate cached translation file lists. Prevent possible fatal errors on bad cached values by validating the caches is an array of strings. Developed in: https://github.com/WordPress/wordpress-develop/pull/13429 Props josephscott, jonsurrell. Fixes #66063. git-svn-id: https://develop.svn.wordpress.org/trunk@63580 602fd350-edb4-49c9-b593-d223f7449a82 --- .../class-wp-textdomain-registry.php | 8 +++ .../tests/l10n/wpTextdomainRegistry.php | 69 +++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/src/wp-includes/class-wp-textdomain-registry.php b/src/wp-includes/class-wp-textdomain-registry.php index 7d924d5abdf1d..8387d382ec1c0 100644 --- a/src/wp-includes/class-wp-textdomain-registry.php +++ b/src/wp-includes/class-wp-textdomain-registry.php @@ -209,6 +209,14 @@ public function get_language_files_from_path( $path ) { $cache_key = md5( $path ); $files = wp_cache_get( $cache_key, 'translation_files' ); + /* + * Verify that the cached value is an array and that all entries in that array + * are strings. + */ + if ( ! is_array( $files ) || array_filter( $files, 'is_string' ) !== $files ) { + $files = false; + } + if ( false === $files ) { $files = glob( $path . '*.mo' ); if ( false === $files ) { diff --git a/tests/phpunit/tests/l10n/wpTextdomainRegistry.php b/tests/phpunit/tests/l10n/wpTextdomainRegistry.php index 1402a86ce0ad4..60661830c464c 100644 --- a/tests/phpunit/tests/l10n/wpTextdomainRegistry.php +++ b/tests/phpunit/tests/l10n/wpTextdomainRegistry.php @@ -111,6 +111,75 @@ public function test_get_language_files_from_path_short_circuit() { $this->assertFalse( $cache ); } + /** + * A cached value that is not an array of strings is discarded and replaced + * by a fresh lookup. + * + * @ticket 66063 + * + * @covers ::get_language_files_from_path + * + * @dataProvider data_get_language_files_from_path_ignores_invalid_cached_values + * + * @param mixed $cached_value Value seeded into the cache. + */ + public function test_get_language_files_from_path_ignores_invalid_cached_values( $cached_value ): void { + $path = WP_LANG_DIR . '/plugins/'; + $cache_key = md5( $path ); + + wp_cache_set( $cache_key, $cached_value, 'translation_files' ); + + $result = $this->instance->get_language_files_from_path( $path ); + + $this->assertIsArray( $result, 'An array should be returned' ); + $this->assertNotEmpty( $result, 'The files should have been looked up instead of using the cached value' ); + foreach ( $result as $file ) { + $this->assertIsString( $file, 'All returned entries should be strings' ); + } + $this->assertSame( + $result, + wp_cache_get( $cache_key, 'translation_files' ), + 'The invalid cached value should have been replaced' + ); + } + + /** + * Data provider. + * + * @return array[] + */ + public static function data_get_language_files_from_path_ignores_invalid_cached_values(): array { + return array( + 'string' => array( 'not-an-array' ), + 'integer' => array( 1 ), + 'null' => array( null ), + 'object' => array( (object) array( WP_LANG_DIR . '/plugins/foo-de_DE.mo' ) ), + 'array with an array' => array( array( WP_LANG_DIR . '/plugins/foo-de_DE.mo', array( 'bar-de_DE.mo' ) ) ), + 'array with an integer' => array( array( WP_LANG_DIR . '/plugins/foo-de_DE.mo', 1 ) ), + 'array with null' => array( array( null ) ), + ); + } + + /** + * An empty array is a valid cached result for a directory without translation + * files and must not cause a new lookup. + * + * @ticket 66063 + * + * @covers ::get_language_files_from_path + */ + public function test_get_language_files_from_path_keeps_cached_empty_array(): void { + $path = WP_LANG_DIR . '/plugins/'; + + wp_cache_set( md5( $path ), array(), 'translation_files' ); + + $this->assertSame( + array(), + $this->instance->get_language_files_from_path( $path ), + 'A cached empty array should be returned without looking up the files' + ); + } + /** * @covers ::invalidate_mo_files_cache */ From ecb1850a895d570e79aad68c9dc353aa3816983c Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Thu, 10 Sep 2026 13:28:17 +0000 Subject: [PATCH 467/634] Privacy: Correct closing tag in results row on personal data tables. Developed in https://github.com/WordPress/wordpress-develop/pull/13470. Follow-up to r43216. Props hbhalodia, dhruvang21, afercia, sabernhardt. Fixes #66085. git-svn-id: https://develop.svn.wordpress.org/trunk@63581 602fd350-edb4-49c9-b593-d223f7449a82 --- src/js/_enqueues/admin/privacy-tools.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/_enqueues/admin/privacy-tools.js b/src/js/_enqueues/admin/privacy-tools.js index df24538ffaefc..0ffecfc1e9535 100644 --- a/src/js/_enqueues/admin/privacy-tools.js +++ b/src/js/_enqueues/admin/privacy-tools.js @@ -75,7 +75,7 @@ jQuery( function( $ ) { '

' + summaryMessage + '

' + itemList + '
' + - '' + + '' + ''; }); } From 032936fe3ea1ac616153e47c50ce22e10886cf3b Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 10 Sep 2026 13:58:33 +0000 Subject: [PATCH 468/634] Application Passwords: Send email notification when an application password is added. This introduces a filterable email notification so users get alerted when an application password is added to their account. The email can be filtered via the `wp_application_password_created_email` filter and disabled via the `wp_send_application_password_created_email` filter. Props prasadkarmalkar, johnbillion, audrasjb. Developed in https://github.com/WordPress/wordpress-develop/pull/9795 Fixes #63927 git-svn-id: https://develop.svn.wordpress.org/trunk@63582 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/default-filters.php | 3 + src/wp-includes/functions.php | 115 ++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) diff --git a/src/wp-includes/default-filters.php b/src/wp-includes/default-filters.php index a839ef92966b4..025a371781200 100644 --- a/src/wp-includes/default-filters.php +++ b/src/wp-includes/default-filters.php @@ -345,6 +345,9 @@ add_filter( 'rest_authentication_errors', 'rest_application_password_check_errors', 90 ); add_filter( 'rest_authentication_errors', 'rest_cookie_check_errors', 100 ); +// Application password notifications. +add_action( 'wp_create_application_password', 'wp_application_password_created_notification', 10, 2 ); + // Actions. add_action( 'wp_head', '_wp_render_title_tag', 1 ); add_action( 'wp_head', 'wp_enqueue_scripts', 1 ); diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index 4c323812991d7..4f5916a322620 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -9464,3 +9464,118 @@ function wp_verify_fast_hash( return hash_equals( $hash, wp_fast_hash( $message ) ); } + +/** + * Sends an email to the user when a new application password is created. + * + * @since 7.2.0 + * + * @param int $user_id The user ID. + * @param array $new_item The application password details. + */ +function wp_application_password_created_notification( $user_id, $new_item ) { + $send = true; + + // Get current user data. + $user = get_userdata( $user_id ); + + if ( ! $user ) { + return; + } + + if ( ! is_email( $user->user_email ) ) { + return; + } + + // Validate that the application password has a name. + if ( empty( $new_item['name'] ) ) { + return; + } + + /** + * Filters whether to send the application password created notification email. + * + * @since 7.2.0 + * + * @param bool $send Whether to send the email notification. + * @param WP_User $user The user object. + * @param array $new_item The application password details. + */ + $send = apply_filters( 'wp_send_application_password_created_email', $send, $user, $new_item ); + + if ( ! $send ) { + return; + } + + /* translators: Do not translate USERNAME, APPLICATION_PASSWORD_NAME, SITENAME, SITEURL, EMAIL: those are placeholders. */ + $application_password_create_text = __( + 'Hi ###USERNAME###, + +A new application password was added to your account on ###SITENAME###. This password allows access to your account via the REST API. + +If you did not expect this, please contact the Site Administrator at +###ADMIN_EMAIL### + +Application password name: ###APPLICATION_PASSWORD_NAME### +Site: ###SITEURL### + +You can manage your application passwords in your account settings. + +This email has been sent to ###EMAIL### + +Regards, +All at ###SITENAME### +###SITEURL###' + ); + + $email = array( + 'to' => $user->user_email, + /* translators: Application password creation email subject. %s: Site title. */ + 'subject' => __( '[%s] Application Password Created' ), + 'message' => $application_password_create_text, + 'headers' => '', + ); + + // Get site name. + $site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); + + /** + * Filters the contents of the email notification sent to a user when a new application password is created. + * + * @since 7.2.0 + * + * @param array $email { + * Used to build wp_mail(). + * + * @type string $to The email address of the intended recipient. + * @type string $subject The subject of the email. + * @type string $message The content of the email. + * The following strings have a special meaning and will get replaced dynamically: + * - `###USERNAME###` The user's display name. + * - `###APPLICATION_PASSWORD_NAME###` The name of the application password. + * - `###EMAIL###` The user's email address. + * - `###SITENAME###` The name of the site. + * - `###SITEURL###` The URL to the site. + * @type string $headers Headers. + * } + * @param WP_User $user The user object. + * @param array $new_item The application password details. + */ + $email = apply_filters( 'wp_application_password_created_email', $email, $user, $new_item ); + + $email['message'] = str_replace( '###USERNAME###', $user->display_name, $email['message'] ); + $email['message'] = str_replace( '###APPLICATION_PASSWORD_NAME###', $new_item['name'], $email['message'] ); + $email['message'] = str_replace( '###EMAIL###', $user->user_email, $email['message'] ); + $email['message'] = str_replace( '###SITENAME###', $site_name, $email['message'] ); + $email['message'] = str_replace( '###SITEURL###', home_url(), $email['message'] ); + + wp_mail( + $email['to'], + sprintf( + $email['subject'], + $site_name + ), + $email['message'], + $email['headers'] + ); +} From 9a2e38e2f3804f97ed47f241dc7f3081220b5f40 Mon Sep 17 00:00:00 2001 From: Lance Willett Date: Thu, 10 Sep 2026 14:24:56 +0000 Subject: [PATCH 469/634] Build/Test Tools: Log relevant URLs in GitHub Actions. Log the workflow run, pull request, Trac ticket, and SVN changeset URLs handled by the automation workflows. Report skipped reruns and empty pull request searches, and avoid processing the same pull request more than once. Await comment creation so failures are reported and success notices reflect completed requests. Developed in: https://github.com/WordPress/wordpress-develop/pull/11223 Props arkaprabhachowdhury, adrianmoldovanwp, desrosj. Fixes #64299. git-svn-id: https://develop.svn.wordpress.org/trunk@63583 602fd350-edb4-49c9-b593-d223f7449a82 --- .github/workflows/failed-workflow.yml | 3 +++ .github/workflows/props-bot.yml | 5 +++++ .github/workflows/pull-request-comments.yml | 6 ++++-- .github/workflows/reusable-cleanup-pull-requests.yml | 11 ++++++++++- 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/.github/workflows/failed-workflow.yml b/.github/workflows/failed-workflow.yml index 288a2a9e0e930..2da0ff56989d7 100644 --- a/.github/workflows/failed-workflow.yml +++ b/.github/workflows/failed-workflow.yml @@ -43,9 +43,12 @@ jobs: // Only rerun after the first run attempt. if ( workflow_run.data.run_attempt > 1 ) { + core.info(`Skipping rerun, attempt ${workflow_run.data.run_attempt}: ${workflow_run.data.html_url}`); return; } + core.notice(`Rerunning workflow run "${workflow_run.data.name}" on ${workflow_run.data.head_branch}: ${workflow_run.data.html_url}`); + const rerun = await github.rest.actions.reRunWorkflowFailedJobs({ owner: context.repo.owner, repo: context.repo.repo, diff --git a/.github/workflows/props-bot.yml b/.github/workflows/props-bot.yml index 38acc07113c2c..eea736f5c4ea3 100644 --- a/.github/workflows/props-bot.yml +++ b/.github/workflows/props-bot.yml @@ -70,6 +70,11 @@ jobs: ( ! github.event.pull_request.draft && github.event.pull_request.state == 'open' || ! github.event.issue.draft && github.event.issue.state == 'open' ) steps: + - name: Output PR link + env: + PR_URL: ${{ github.event.pull_request.html_url || github.event.issue.html_url }} + run: 'echo "::notice::Pull request: $PR_URL"' + - name: Gather a list of contributors uses: WordPress/props-bot-action@trunk with: diff --git a/.github/workflows/pull-request-comments.yml b/.github/workflows/pull-request-comments.yml index 8dff8e1c1fcce..6c56326774b8d 100644 --- a/.github/workflows/pull-request-comments.yml +++ b/.github/workflows/pull-request-comments.yml @@ -121,7 +121,8 @@ jobs: [Test this pull request with WordPress Playground](https://playground.wordpress.net/wordpress.html?pr=${ issue_number }). `; - github.rest.issues.createComment( commentInfo ); + await github.rest.issues.createComment( commentInfo ); + core.notice( `Created Playground comment for pull request: ${ pr.data.html_url }` ); # Manages comments reminding contributors to include a Trac ticket link when opening a pull request. trac-ticket-check: @@ -160,7 +161,8 @@ jobs: const tracTicketMatches = prBody.match( tracTicketRegex ) || prTitle.match( tracTicketRegex ); if ( ! tracTicketMatches ) { - github.rest.issues.createComment( { + core.info( `Creating missing Trac ticket comment for pull request: ${ pr.html_url }` ); + await github.rest.issues.createComment( { owner, repo, issue_number: number, diff --git a/.github/workflows/reusable-cleanup-pull-requests.yml b/.github/workflows/reusable-cleanup-pull-requests.yml index 012f99adbec3b..a4c1e57d4ab5e 100644 --- a/.github/workflows/reusable-cleanup-pull-requests.yml +++ b/.github/workflows/reusable-cleanup-pull-requests.yml @@ -56,10 +56,14 @@ jobs: const githubSha = process.env.GITHUB_SHA; let prNumbers = []; + core.notice(`Processing pull request cleanup for SVN changeset: https://core.trac.wordpress.org/changeset/${svnRevisionNumber}`); + for (const ticket of fixedList) { const tracTicketUrl = `https://core.trac.wordpress.org/ticket/${ticket}`; const corePrefix = `core-${ticket}`; + core.info(`Ticket: ${tracTicketUrl}`); + const query = ` query($searchQuery: String!) { search(query: $searchQuery, type: ISSUE_ADVANCED, first: 20) { @@ -97,8 +101,13 @@ jobs: This PR will be closed, but please confirm the accuracy of this and reopen if there is more work to be done.`; + const uniquePrNumbers = [...new Set(prNumbers)]; + core.info(`Found ${uniquePrNumbers.length} pull request(s) to close.`); + // Update all matched pull requests. - for (const prNumber of prNumbers) { + for (const prNumber of uniquePrNumbers) { + core.info(`Closing pull request: https://github.com/${context.repo.owner}/${context.repo.repo}/pull/${prNumber}`); + // Comment on the pull request with details. await github.rest.issues.createComment({ owner: context.repo.owner, From 43e329df4bf23e55aff0b10132c93847f5121882 Mon Sep 17 00:00:00 2001 From: Lance Willett Date: Thu, 10 Sep 2026 15:14:03 +0000 Subject: [PATCH 470/634] Build/Test Tools: Trim the routine PHPUnit database matrix. Test MySQL 5.7, 8.0, and 8.4 and MariaDB 5.5, 10.6, 10.11, 11.4, and 11.8 on pushes, pull requests, and manual runs. Keep the complete database matrix on the weekly schedule. Reduce routine coverage from 86 to 68 jobs while retaining the 182-job weekly matrix. Preserve the reporting, memcached, alternate-domain, HTML API, innovation-release, and PHP prerelease configurations. Developed in: https://github.com/WordPress/wordpress-develop/pull/13447 Props lucatume, adrianmoldovanwp. Fixes #66069. git-svn-id: https://develop.svn.wordpress.org/trunk@63584 602fd350-edb4-49c9-b593-d223f7449a82 --- .github/workflows/phpunit-tests.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/phpunit-tests.yml b/.github/workflows/phpunit-tests.yml index 8223d78780750..906674e285e2f 100644 --- a/.github/workflows/phpunit-tests.yml +++ b/.github/workflows/phpunit-tests.yml @@ -113,7 +113,8 @@ jobs: # The scheduled run tests every supported PHP version. Other events test the highest and lowest of each major. php: ${{ github.event_name == 'schedule' && fromJSON('["7.4","8.0","8.1","8.2","8.3","8.4","8.5"]') || fromJSON('["7.4","8.0","8.5"]') }} db-type: [ 'mysql' ] - db-version: [ '5.7', '8.0', '8.4', '9.7' ] + # The scheduled run tests the full database matrix. Other events retain MySQL 5.7 compatibility and the widely used 8.x releases. + db-version: ${{ github.event_name == 'schedule' && fromJSON('["5.7","8.0","8.4","9.7"]') || fromJSON('["5.7","8.0","8.4"]') }} tests-domain: [ 'example.org' ] multisite: [ false, true ] memcached: [ false ] @@ -173,8 +174,8 @@ jobs: # # Creates a PHPUnit test job for each PHP/MariaDB combination. # - # All LTS versions of MariaDB supported by WordPress with greater than 1% usage according to w.org/stats should be - # tested. The exceptions to this rule are the most recent LTS and version 5.5. + # The scheduled run tests all LTS versions of MariaDB supported by WordPress with greater than 1% usage according to + # w.org/stats. The exceptions to this rule are the most recent LTS and version 5.5. # # The 5.5 release was intended as a drop-in replacement for MySQL. Because the MySQL 5.5 Docker containers do not # work, this ensures some level of MySQL 5.5 testing. @@ -205,7 +206,8 @@ jobs: # The scheduled run tests every supported PHP version. Other events test the highest and lowest of each major. php: ${{ github.event_name == 'schedule' && fromJSON('["7.4","8.0","8.1","8.2","8.3","8.4","8.5"]') || fromJSON('["7.4","8.0","8.5"]') }} db-type: [ 'mariadb' ] - db-version: [ '5.5', '10.3', '10.5', '10.6', '10.11', '11.4', '11.8' ] + # The scheduled run tests the full database matrix. Other events retain MariaDB 5.5 compatibility, 10.6, and newer LTS releases. + db-version: ${{ github.event_name == 'schedule' && fromJSON('["5.5","10.3","10.5","10.6","10.11","11.4","11.8"]') || fromJSON('["5.5","10.6","10.11","11.4","11.8"]') }} multisite: [ false, true ] memcached: [ false ] From 0ee9f304ac249547bdcba342fdb156b875313095 Mon Sep 17 00:00:00 2001 From: Lance Willett Date: Thu, 10 Sep 2026 15:16:09 +0000 Subject: [PATCH 471/634] Build/Test Tools: Run the full PHPUnit matrix by label. Allow reviewers to trigger the weekly PHP and database matrix on eligible pull requests by adding the Full PHPUnit Matrix label. Keep full coverage on subsequent commits while the label remains. Use a separate label-triggered workflow so unrelated labels do not replace PHPUnit checks or cancel active runs. Preserve the existing path filters and document the manual request process for contributors without label access. Developed in: https://github.com/WordPress/wordpress-develop/pull/13448 Props lucatume, adrianmoldovanwp. Fixes #66071. git-svn-id: https://develop.svn.wordpress.org/trunk@63585 602fd350-edb4-49c9-b593-d223f7449a82 --- .../workflows/phpunit-tests-full-matrix.yml | 65 +++++++++++++++++++ .github/workflows/phpunit-tests.yml | 43 ++++++++---- tests/phpunit/README.md | 12 ++++ 3 files changed, 108 insertions(+), 12 deletions(-) create mode 100644 .github/workflows/phpunit-tests-full-matrix.yml diff --git a/.github/workflows/phpunit-tests-full-matrix.yml b/.github/workflows/phpunit-tests-full-matrix.yml new file mode 100644 index 0000000000000..a6b42f6401174 --- /dev/null +++ b/.github/workflows/phpunit-tests-full-matrix.yml @@ -0,0 +1,65 @@ +name: PHPUnit Tests (label) +run-name: PHPUnit Tests${{ github.event.label.name == 'Full PHPUnit Matrix' && ' (full matrix)' || ' (ignored label)' }} + +on: + pull_request: + types: [ labeled ] + branches: + - trunk + - '3.[7-9]' + - '[4-9].[0-9]' + # Keep these paths in sync with phpunit-tests.yml. + paths: + - '**' + # Documentation and repository metadata. + - '!**.md' + - '!.devcontainer/**' + - '!.editorconfig' + - '!.git-blame-ignore-revs' + - '!.gitignore' + - '!.mailmap' + - '!typings/**' + # Configuration for unrelated checks. + - '!.eslintrc-jsdoc.js' + - '!.prettierrc.js' + - '!.version-support-*.json' + - '!eslint.config.js' + - '!jsdoc.conf.json' + - '!phpcompat.xml.dist' + - '!phpcs.xml.dist' + - '!phpstan.neon.dist' + - '!tsconfig.json' + # Other test suites, tools, and workflows do not affect these tests. + - '!tests/**' + - '!tools/**' + - '!.github/**' + # Re-include documentation, tests, tools, and workflows used here. + - 'SECURITY.md' + - 'src/license.txt' + - 'tests/phpunit/**' + - 'tools/gutenberg/**' + - 'tools/local-env/**' + - 'tools/vendors/**' + - 'tools/webpack/**' + - 'phpunit.xml.dist' + - '.github/workflows/phpunit-tests.yml' + - '.github/workflows/phpunit-tests-full-matrix.yml' + - '.github/workflows/reusable-phpunit-tests-*.yml' + - '.github/workflows/reusable-prepare-gutenberg.yml' + +# Disable permissions for all available scopes by default. +permissions: {} + +# The called workflow manages concurrency. Unrelated labels never enter it. +jobs: + full-matrix: + if: github.event.label.name == 'Full PHPUnit Matrix' + permissions: + # Required by the called workflow's recovery job, which is skipped on PR events. + actions: write + contents: read + uses: ./.github/workflows/phpunit-tests.yml + secrets: + CODEVITALS_PROJECT_TOKEN: ${{ secrets.CODEVITALS_PROJECT_TOKEN }} + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + WPT_REPORT_API_KEY: ${{ secrets.WPT_REPORT_API_KEY }} diff --git a/.github/workflows/phpunit-tests.yml b/.github/workflows/phpunit-tests.yml index 906674e285e2f..1e4a22bb61afc 100644 --- a/.github/workflows/phpunit-tests.yml +++ b/.github/workflows/phpunit-tests.yml @@ -1,4 +1,5 @@ name: PHPUnit Tests +run-name: PHPUnit Tests${{ ( github.event_name == 'schedule' || ( github.event_name == 'pull_request' && contains( github.event.pull_request.labels.*.name, 'Full PHPUnit Matrix' ) ) ) && ' (full matrix)' || '' }} on: push: @@ -11,6 +12,7 @@ on: - trunk - '3.[7-9]' - '[4-9].[0-9]' + # Keep these paths in sync with phpunit-tests-full-matrix.yml. paths: - '**' # Documentation and repository metadata. @@ -45,9 +47,26 @@ on: - 'tools/webpack/**' - 'phpunit.xml.dist' - '.github/workflows/phpunit-tests.yml' + - '.github/workflows/phpunit-tests-full-matrix.yml' - '.github/workflows/reusable-phpunit-tests-*.yml' - '.github/workflows/reusable-prepare-gutenberg.yml' workflow_dispatch: + workflow_call: + secrets: + CODEVITALS_PROJECT_TOKEN: + required: false + CODECOV_TOKEN: + required: false + WPT_REPORT_API_KEY: + required: false + SLACK_GHA_SUCCESS_WEBHOOK: + required: false + SLACK_GHA_CANCELLED_WEBHOOK: + required: false + SLACK_GHA_FIXED_WEBHOOK: + required: false + SLACK_GHA_FAILURE_WEBHOOK: + required: false # Once weekly On Sundays at 00:00 UTC. schedule: - cron: '0 0 * * 0' @@ -110,11 +129,11 @@ jobs: fail-fast: false matrix: os: [ ubuntu-24.04 ] - # The scheduled run tests every supported PHP version. Other events test the highest and lowest of each major. - php: ${{ github.event_name == 'schedule' && fromJSON('["7.4","8.0","8.1","8.2","8.3","8.4","8.5"]') || fromJSON('["7.4","8.0","8.5"]') }} + # Scheduled and labeled runs test every supported PHP version. Other runs test the highest and lowest of each major. + php: ${{ ( github.event_name == 'schedule' || ( github.event_name == 'pull_request' && contains( github.event.pull_request.labels.*.name, 'Full PHPUnit Matrix' ) ) ) && fromJSON('["7.4","8.0","8.1","8.2","8.3","8.4","8.5"]') || fromJSON('["7.4","8.0","8.5"]') }} db-type: [ 'mysql' ] - # The scheduled run tests the full database matrix. Other events retain MySQL 5.7 compatibility and the widely used 8.x releases. - db-version: ${{ github.event_name == 'schedule' && fromJSON('["5.7","8.0","8.4","9.7"]') || fromJSON('["5.7","8.0","8.4"]') }} + # Scheduled and labeled runs test the full database matrix. Other runs retain MySQL 5.7 compatibility and the widely used 8.x releases. + db-version: ${{ ( github.event_name == 'schedule' || ( github.event_name == 'pull_request' && contains( github.event.pull_request.labels.*.name, 'Full PHPUnit Matrix' ) ) ) && fromJSON('["5.7","8.0","8.4","9.7"]') || fromJSON('["5.7","8.0","8.4"]') }} tests-domain: [ 'example.org' ] multisite: [ false, true ] memcached: [ false ] @@ -174,8 +193,8 @@ jobs: # # Creates a PHPUnit test job for each PHP/MariaDB combination. # - # The scheduled run tests all LTS versions of MariaDB supported by WordPress with greater than 1% usage according to - # w.org/stats. The exceptions to this rule are the most recent LTS and version 5.5. + # Scheduled and labeled runs test all LTS versions of MariaDB supported by WordPress with greater than 1% usage + # according to w.org/stats. The exceptions to this rule are the most recent LTS and version 5.5. # # The 5.5 release was intended as a drop-in replacement for MySQL. Because the MySQL 5.5 Docker containers do not # work, this ensures some level of MySQL 5.5 testing. @@ -203,11 +222,11 @@ jobs: fail-fast: false matrix: os: [ ubuntu-24.04 ] - # The scheduled run tests every supported PHP version. Other events test the highest and lowest of each major. - php: ${{ github.event_name == 'schedule' && fromJSON('["7.4","8.0","8.1","8.2","8.3","8.4","8.5"]') || fromJSON('["7.4","8.0","8.5"]') }} + # Scheduled and labeled runs test every supported PHP version. Other runs test the highest and lowest of each major. + php: ${{ ( github.event_name == 'schedule' || ( github.event_name == 'pull_request' && contains( github.event.pull_request.labels.*.name, 'Full PHPUnit Matrix' ) ) ) && fromJSON('["7.4","8.0","8.1","8.2","8.3","8.4","8.5"]') || fromJSON('["7.4","8.0","8.5"]') }} db-type: [ 'mariadb' ] - # The scheduled run tests the full database matrix. Other events retain MariaDB 5.5 compatibility, 10.6, and newer LTS releases. - db-version: ${{ github.event_name == 'schedule' && fromJSON('["5.5","10.3","10.5","10.6","10.11","11.4","11.8"]') || fromJSON('["5.5","10.6","10.11","11.4","11.8"]') }} + # Scheduled and labeled runs test the full database matrix. Other runs retain MariaDB 5.5 compatibility, 10.6, and newer LTS releases. + db-version: ${{ ( github.event_name == 'schedule' || ( github.event_name == 'pull_request' && contains( github.event.pull_request.labels.*.name, 'Full PHPUnit Matrix' ) ) ) && fromJSON('["5.5","10.3","10.5","10.6","10.11","11.4","11.8"]') || fromJSON('["5.5","10.6","10.11","11.4","11.8"]') }} multisite: [ false, true ] memcached: [ false ] @@ -271,8 +290,8 @@ jobs: fail-fast: false matrix: os: [ ubuntu-24.04 ] - # The scheduled run tests every supported PHP version. Other events test the highest and lowest of each major. - php: ${{ github.event_name == 'schedule' && fromJSON('["7.4","8.0","8.1","8.2","8.3","8.4","8.5"]') || fromJSON('["7.4","8.0","8.5"]') }} + # Scheduled and labeled runs test every supported PHP version. Other runs test the highest and lowest of each major. + php: ${{ ( github.event_name == 'schedule' || ( github.event_name == 'pull_request' && contains( github.event.pull_request.labels.*.name, 'Full PHPUnit Matrix' ) ) ) && fromJSON('["7.4","8.0","8.1","8.2","8.3","8.4","8.5"]') || fromJSON('["7.4","8.0","8.5"]') }} db-type: [ 'mysql', 'mariadb' ] db-version: [ '12.1' ] multisite: [ false, true ] diff --git a/tests/phpunit/README.md b/tests/phpunit/README.md index b5fd1513600d6..679ed831112d2 100644 --- a/tests/phpunit/README.md +++ b/tests/phpunit/README.md @@ -5,3 +5,15 @@ PHPUnit is the official testing framework chosen by the core team to test PHP co For more information, please review the relevant Core Handbook pages: - [PHP: PHPUnit](https://make.wordpress.org/core/handbook/testing/automated-testing/phpunit/) - [Writing PHP Tests](https://make.wordpress.org/core/handbook/testing/automated-testing/writing-phpunit-tests/) + +## Run the full matrix on a pull request + +Add the `Full PHPUnit Matrix` label to a pull request in `WordPress/wordpress-develop` to run the same PHP and database combinations as the weekly scheduled run. The label-triggered workflow uses the same path filters as normal PHPUnit runs. + +If you cannot apply labels, leave a PR comment asking a reviewer with triage access to add it. Fork PRs follow GitHub's usual workflow approval requirements. + +Adding the label starts a separate run without another code push. An existing reduced-matrix run continues alongside it; its checks and results are preserved. New commits run the full matrix while the label remains. Remove and reapply it to request another run for the current revision, or remove it to return subsequent runs to the reduced matrix. + +Unrelated labels skip only the label-triggered workflow's `full-matrix` job and do not replace or cancel PHPUnit checks. + +Look for `PHPUnit Tests (full matrix)` in GitHub Actions and the PHPUnit checks on the PR. Each run tests the PR's merge commit and retains its own logs and results, so check the revision before relying on an older run. From 2c6ec190fed195492439cd75177223bdf0812016 Mon Sep 17 00:00:00 2001 From: Lance Willett Date: Thu, 10 Sep 2026 15:32:10 +0000 Subject: [PATCH 472/634] Build/Test Tools: Delete attachment files during test cleanup. Delete attachments before the bulk database cleanup so their uploaded files and generated image sizes are removed while attachment metadata is still available. Preserve the existing bulk SQL cleanup for other records. Add regression coverage for attachment file and post deletion. Developed in: https://github.com/WordPress/wordpress-develop/pull/8898 Props sirlouen, johnbillion, adrianmoldovanwp. Fixes #41978. git-svn-id: https://develop.svn.wordpress.org/trunk@63586 602fd350-edb4-49c9-b593-d223f7449a82 --- tests/phpunit/includes/functions.php | 10 ++++++- tests/phpunit/tests/includes/functions.php | 33 ++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 tests/phpunit/tests/includes/functions.php diff --git a/tests/phpunit/includes/functions.php b/tests/phpunit/includes/functions.php index d27af5c172a7a..473ed341e9571 100644 --- a/tests/phpunit/includes/functions.php +++ b/tests/phpunit/includes/functions.php @@ -105,11 +105,19 @@ function _test_filter_build_unique_id( $hook_name, $callback, $priority ) { } /** - * Deletes all data from the database. + * Deletes all data from the database, except: + * - The default category. + * - The default user. */ function _delete_all_data() { global $wpdb; + // Retrieve all attachment posts, and delete them along with the attached media. + $attachments = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'attachment'" ); + foreach ( $attachments as $attachment ) { + wp_delete_attachment( $attachment, true ); + } + foreach ( array( $wpdb->posts, $wpdb->postmeta, diff --git a/tests/phpunit/tests/includes/functions.php b/tests/phpunit/tests/includes/functions.php new file mode 100644 index 0000000000000..df5fc31a6156e --- /dev/null +++ b/tests/phpunit/tests/includes/functions.php @@ -0,0 +1,33 @@ +attachment->create_upload_object( + DIR_TESTDATA . '/images/waffles.jpg' + ); + + // Retrieve the path to the image. + $attachment_file = get_attached_file( $attachment_id ); + $this->assertFileExists( $attachment_file ); + + _delete_all_data(); + + // Verify that the image has been deleted along with the attachment. + $this->assertFileDoesNotExist( $attachment_file ); + $this->assertNull( get_post( $attachment_id ) ); + } +} From f8fb8d026abe119d2d5fcd2e3152e2d47e524f9b Mon Sep 17 00:00:00 2001 From: Lance Willett Date: Thu, 10 Sep 2026 20:29:08 +0000 Subject: [PATCH 473/634] Build/Test Tools: Discard stale roles before test installation. Discard the roles object loaded before the test tables are dropped. Let WordPress recreate it from the fresh tables so capabilities from a previous test run do not survive reinstallation. Developed in: https://github.com/WordPress/wordpress-develop/pull/13286 Props ekamran. Fixes #65972. git-svn-id: https://develop.svn.wordpress.org/trunk@63590 602fd350-edb4-49c9-b593-d223f7449a82 --- tests/phpunit/includes/install.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/phpunit/includes/install.php b/tests/phpunit/includes/install.php index 61b27e22dd097..01b438289b6f5 100644 --- a/tests/phpunit/includes/install.php +++ b/tests/phpunit/includes/install.php @@ -79,6 +79,15 @@ } $wpdb->query( 'SET foreign_key_checks = 1' ); +/* + * Discard the roles object created while bootstrapping WordPress above, as it + * holds role data loaded from the tables that were just dropped. If it were + * kept, populate_roles() would see the default roles as already existing and + * write the stale capabilities back to the database. The next call to + * wp_roles() recreates the object after the fresh tables are in place. + */ +unset( $GLOBALS['wp_roles'] ); + // Prefill a permalink structure so that WP doesn't try to determine one itself. add_action( 'populate_options', '_set_default_permalink_structure_for_tests' ); From a1c3fe13303f79c5492681d795b6b6821dbcecee Mon Sep 17 00:00:00 2001 From: Lance Willett Date: Thu, 10 Sep 2026 20:53:44 +0000 Subject: [PATCH 474/634] Tests: Reduce repeated token map test setup. Check all HTML5 named character references within each token map test instead of running a separate test for every token. Preserve the per-token assertions and include token names in failure messages. Reduce test invocations from 4,474 to 14, avoiding repeated test runner setup and teardown. Developed in: https://github.com/WordPress/wordpress-develop/pull/13478 Props sainathpoojary. See #66074. git-svn-id: https://develop.svn.wordpress.org/trunk@63591 602fd350-edb4-49c9-b593-d223f7449a82 --- .../phpunit/tests/wp-token-map/wpTokenMap.php | 83 +++++++++---------- 1 file changed, 38 insertions(+), 45 deletions(-) diff --git a/tests/phpunit/tests/wp-token-map/wpTokenMap.php b/tests/phpunit/tests/wp-token-map/wpTokenMap.php index 23edc5de80b94..85311eeb76e7c 100644 --- a/tests/phpunit/tests/wp-token-map/wpTokenMap.php +++ b/tests/phpunit/tests/wp-token-map/wpTokenMap.php @@ -306,68 +306,63 @@ public static function data_short_substring_matches_of_each_other() { * Ensures that Token Map searches at appropriate starting offset. * * @ticket 60698 - * - * @dataProvider data_html5_test_dataset - * - * @param string $token Token to find. - * @param string $replacement Replacement string for token. */ - public function test_reads_token_at_given_offset( $token, $replacement ) { - $document = "& another {$token} & then some"; - $map = self::get_html5_token_map(); + public function test_reads_token_at_given_offset() { + $map = self::get_html5_token_map(); - $skip_bytes = 0; - $this->assertNull( - $map->read_token( $document, 0, $skip_bytes ), - "Shouldn't have found token at start of document." - ); + foreach ( $this->get_html5_test_dataset() as $token => $replacement ) { + $document = "& another {$token} & then some"; - $response = $map->read_token( $document, 10, $skip_bytes ); + $skip_bytes = 0; + $this->assertNull( + $map->read_token( $document, 0, $skip_bytes ), + "Shouldn't have found token '{$token}' at start of document." + ); - $this->assertSame( - strlen( $token ), - $skip_bytes, - "Found the wrong length for token '{$token}'." - ); + $response = $map->read_token( $document, 10, $skip_bytes ); - $this->assertSame( - $response, - $replacement, - 'Found the wrong replacement value for the token.' - ); + $this->assertSame( + strlen( $token ), + $skip_bytes, + "Found the wrong length for token '{$token}'." + ); + + $this->assertSame( + $response, + $replacement, + "Found the wrong replacement value for token '{$token}'." + ); + } } /** * Ensures that all given tokens exist inside a constructed Token Map. * * @ticket 60698 - * - * @dataProvider data_html5_test_dataset - * - * @param string $token Token to find. - * @param string $replacement Not used in this test. */ - public function test_detects_all_tokens( $token, $replacement ) { + public function test_detects_all_tokens() { $map = self::get_html5_token_map(); - $this->assertTrue( - $map->contains( $token ), - "Should have found '{$token}' inside the Token Map, but didn't." - ); + foreach ( $this->get_html5_test_dataset() as $token => $replacement ) { + $this->assertTrue( + $map->contains( $token ), + "Should have found '{$token}' inside the Token Map, but didn't." + ); - $double_escaped_token = str_replace( '&', '&', $token ); - $this->assertFalse( - $map->contains( $double_escaped_token ), - "Should not have found '{$double_escaped_token}' in Token Map, but did." - ); + $double_escaped_token = str_replace( '&', '&', $token ); + $this->assertFalse( + $map->contains( $double_escaped_token ), + "Should not have found '{$double_escaped_token}' in Token Map, but did." + ); + } } /** - * Data provider. + * Gets all HTML5 named character references to check within each test. * - * @return array[]. + * @return string[] Replacement strings keyed by token. */ - public function data_html5_test_dataset() { + private function get_html5_test_dataset() { $html5 = self::get_test_input_array( 'HTML5' ); $this->assertSame( @@ -376,9 +371,7 @@ public function data_html5_test_dataset() { 'Found the wrong number of HTML5 named character references: confirm the entities.json file."' ); - foreach ( $html5 as $token => $replacement ) { - yield $token => array( $token, $replacement ); - } + return $html5; } /** From fe4400bf5d35fb98d207c78eff4775099e94be32 Mon Sep 17 00:00:00 2001 From: Lance Willett Date: Thu, 10 Sep 2026 21:10:52 +0000 Subject: [PATCH 475/634] Build/Test Tools: Reset comment globals between tests. Clear the global comment fixture after author URL link tests and reset the comment-loop flag between tests to prevent order-dependent failures. Developed in: https://github.com/WordPress/wordpress-develop/pull/13186 Props jonsurrell. See #65893. git-svn-id: https://develop.svn.wordpress.org/trunk@63592 602fd350-edb4-49c9-b593-d223f7449a82 --- tests/phpunit/includes/abstract-testcase.php | 2 +- tests/phpunit/tests/comment/getCommentAuthorUrlLink.php | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/phpunit/includes/abstract-testcase.php b/tests/phpunit/includes/abstract-testcase.php index 25b207092c110..7116d3076266b 100644 --- a/tests/phpunit/includes/abstract-testcase.php +++ b/tests/phpunit/includes/abstract-testcase.php @@ -220,7 +220,7 @@ public function tear_down() { } // Reset comment globals. - $comment_globals = array( 'comment_alt', 'comment_depth', 'comment_thread_alt' ); + $comment_globals = array( 'comment_alt', 'comment_depth', 'comment_thread_alt', 'in_comment_loop' ); foreach ( $comment_globals as $global ) { $GLOBALS[ $global ] = null; } diff --git a/tests/phpunit/tests/comment/getCommentAuthorUrlLink.php b/tests/phpunit/tests/comment/getCommentAuthorUrlLink.php index ee964d96d9de0..043d38869e5e6 100644 --- a/tests/phpunit/tests/comment/getCommentAuthorUrlLink.php +++ b/tests/phpunit/tests/comment/getCommentAuthorUrlLink.php @@ -9,6 +9,12 @@ class Tests_Comment_GetCommentAuthorUrlLink extends WP_UnitTestCase { protected static $comments = array(); + public function tear_down() { + unset( $GLOBALS['comment'] ); + + parent::tear_down(); + } + public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) { unset( $GLOBALS['comment'] ); From a508c69fe88c7c4a58da5ee454e64719375e40b0 Mon Sep 17 00:00:00 2001 From: Lance Willett Date: Thu, 10 Sep 2026 21:20:48 +0000 Subject: [PATCH 476/634] Tests: Restore core Ajax hooks before each test. Register core Ajax callbacks during each test setup so restoring the shared hook snapshot cannot leave later tests without their required callbacks. Remove the automatic update checks from admin_init during each setup as well. Developed in: https://github.com/WordPress/wordpress-develop/pull/13191 Props jonsurrell. See #65893. git-svn-id: https://develop.svn.wordpress.org/trunk@63593 602fd350-edb4-49c9-b593-d223f7449a82 --- tests/phpunit/includes/testcase-ajax.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/phpunit/includes/testcase-ajax.php b/tests/phpunit/includes/testcase-ajax.php index 2e86c29e67284..dcba2e58c3a5c 100644 --- a/tests/phpunit/includes/testcase-ajax.php +++ b/tests/phpunit/includes/testcase-ajax.php @@ -122,7 +122,13 @@ public static function set_up_before_class() { remove_action( 'admin_init', '_maybe_update_plugins' ); remove_action( 'admin_init', '_maybe_update_themes' ); - // Register the core actions. + self::register_core_actions(); + } + + /** + * Registers the core Ajax actions. + */ + protected static function register_core_actions() { foreach ( array_merge( self::$_core_actions_get, self::$_core_actions_post ) as $action ) { if ( function_exists( 'wp_ajax_' . str_replace( '-', '_', $action ) ) ) { add_action( 'wp_ajax_' . $action, 'wp_ajax_' . str_replace( '-', '_', $action ), 1 ); @@ -138,6 +144,15 @@ public static function set_up_before_class() { public function set_up() { parent::set_up(); + /* + * The shared hook snapshot may have been captured before an Ajax test case + * registered these callbacks, then restored after another randomized test. + */ + self::register_core_actions(); + remove_action( 'admin_init', '_maybe_update_core' ); + remove_action( 'admin_init', '_maybe_update_plugins' ); + remove_action( 'admin_init', '_maybe_update_themes' ); + add_filter( 'wp_doing_ajax', '__return_true' ); add_filter( 'wp_die_ajax_handler', array( $this, 'getDieHandler' ), 1, 1 ); From ac38246ae9c515094105800c8da25613375421e9 Mon Sep 17 00:00:00 2001 From: Lance Willett Date: Thu, 10 Sep 2026 21:32:50 +0000 Subject: [PATCH 477/634] Tests: Improve isolation of rewrite tests. Flush rewrite rules after registering the initial taxonomies in conditional-query test setup. Clear the HTTPS server flag during rewrite test teardown so later tests do not inherit it. Developed in: https://github.com/WordPress/wordpress-develop/pull/13193 Props jonsurrell. See #65893. git-svn-id: https://develop.svn.wordpress.org/trunk@63594 602fd350-edb4-49c9-b593-d223f7449a82 --- tests/phpunit/tests/query/conditionals.php | 1 + tests/phpunit/tests/rewrite.php | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/phpunit/tests/query/conditionals.php b/tests/phpunit/tests/query/conditionals.php index 4b473178897ae..913e19f650de6 100644 --- a/tests/phpunit/tests/query/conditionals.php +++ b/tests/phpunit/tests/query/conditionals.php @@ -39,6 +39,7 @@ public function set_up() { $this->set_permalink_structure( '/%year%/%monthnum%/%day%/%postname%/' ); create_initial_taxonomies(); + flush_rewrite_rules(); } public function test_home() { diff --git a/tests/phpunit/tests/rewrite.php b/tests/phpunit/tests/rewrite.php index 085998e4b7eec..3ffb3ba2a81a2 100644 --- a/tests/phpunit/tests/rewrite.php +++ b/tests/phpunit/tests/rewrite.php @@ -31,6 +31,7 @@ public function tear_down() { $wp_rewrite->init(); update_option( 'home', $this->home_url ); + unset( $_SERVER['HTTPS'] ); unset( $this->blog_id_35531 ); parent::tear_down(); } From f07d9757b32ff72eb688f791bbcb1b0df4e56013 Mon Sep 17 00:00:00 2001 From: Lance Willett Date: Thu, 10 Sep 2026 21:39:21 +0000 Subject: [PATCH 478/634] Tests: Restore themes after block tests. Save the incoming stylesheet in block and theme test fixtures and switch back during teardown when it changes. Restore the theme before database rollback so theme-related runtime state and caches do not leak into later tests. Developed in: https://github.com/WordPress/wordpress-develop/pull/13205 Props jonsurrell. See #65893. git-svn-id: https://develop.svn.wordpress.org/trunk@63595 602fd350-edb4-49c9-b593-d223f7449a82 --- tests/phpunit/tests/blocks/editor.php | 13 +++++++++++++ tests/phpunit/tests/blocks/getBlockAssetUrl.php | 12 ++++++++++++ tests/phpunit/tests/blocks/getBlockTemplates.php | 16 ++++++++++++++++ tests/phpunit/tests/blocks/getHookedBlocks.php | 16 ++++++++++++++++ tests/phpunit/tests/blocks/register.php | 12 ++++++++++++ .../tests/blocks/wpBlockPatternsRegistry.php | 13 +++++++++++++ .../tests/theme/wpThemeGetBlockPatterns.php | 13 +++++++++++++ 7 files changed, 95 insertions(+) diff --git a/tests/phpunit/tests/blocks/editor.php b/tests/phpunit/tests/blocks/editor.php index 1de4dbf1719a6..ed740a35bbcbc 100644 --- a/tests/phpunit/tests/blocks/editor.php +++ b/tests/phpunit/tests/blocks/editor.php @@ -16,6 +16,7 @@ public function set_up() { global $post; parent::set_up(); + $this->original_stylesheet = get_stylesheet(); remove_action( 'wp_print_styles', 'print_emoji_styles' ); @@ -51,6 +52,11 @@ public function tear_down() { $wp_rest_server = null; global $post_ID; $post_ID = null; + + if ( get_stylesheet() !== $this->original_stylesheet ) { + switch_theme( $this->original_stylesheet ); + } + parent::tear_down(); } @@ -64,6 +70,13 @@ public function tear_down() { */ protected $original_wp_styles; + /** + * Original stylesheet. + * + * @var string + */ + private $original_stylesheet; + public function filter_set_block_categories_post( $block_categories, $post ) { if ( empty( $post ) ) { return $block_categories; diff --git a/tests/phpunit/tests/blocks/getBlockAssetUrl.php b/tests/phpunit/tests/blocks/getBlockAssetUrl.php index ee1c541cf0c2c..fba6757369242 100644 --- a/tests/phpunit/tests/blocks/getBlockAssetUrl.php +++ b/tests/phpunit/tests/blocks/getBlockAssetUrl.php @@ -18,10 +18,18 @@ class Tests_Get_Block_Asset_Url extends WP_UnitTestCase { */ private $orig_theme_dir; + /** + * Original stylesheet. + * + * @var string + */ + private $original_stylesheet; + public function set_up() { global $wp_theme_directories; parent::set_up(); + $this->original_stylesheet = get_stylesheet(); // Sets up the `wp-content/themes/` directory to ensure consistency when running tests. $this->orig_theme_dir = $wp_theme_directories; @@ -34,6 +42,10 @@ public function set_up() { public function tear_down() { global $wp_theme_directories; + if ( get_stylesheet() !== $this->original_stylesheet ) { + switch_theme( $this->original_stylesheet ); + } + $wp_theme_directories = $this->orig_theme_dir; wp_clean_themes_cache(); diff --git a/tests/phpunit/tests/blocks/getBlockTemplates.php b/tests/phpunit/tests/blocks/getBlockTemplates.php index 791f449a163c5..783dfbabfd1eb 100644 --- a/tests/phpunit/tests/blocks/getBlockTemplates.php +++ b/tests/phpunit/tests/blocks/getBlockTemplates.php @@ -9,6 +9,13 @@ class Tests_Blocks_GetBlockTemplates extends WP_UnitTestCase { const TEST_THEME = 'block-theme'; + /** + * Original stylesheet. + * + * @var string + */ + private $original_stylesheet; + /** * @var WP_Post */ @@ -91,9 +98,18 @@ public static function wpTearDownAfterClass() { public function set_up() { parent::set_up(); + $this->original_stylesheet = get_stylesheet(); switch_theme( self::TEST_THEME ); } + public function tear_down() { + if ( get_stylesheet() !== $this->original_stylesheet ) { + switch_theme( $this->original_stylesheet ); + } + + parent::tear_down(); + } + /** * Gets the template IDs from the given array. * diff --git a/tests/phpunit/tests/blocks/getHookedBlocks.php b/tests/phpunit/tests/blocks/getHookedBlocks.php index 83a741b4d0771..d0d17886bd4d8 100644 --- a/tests/phpunit/tests/blocks/getHookedBlocks.php +++ b/tests/phpunit/tests/blocks/getHookedBlocks.php @@ -16,6 +16,18 @@ class Tests_Blocks_GetHookedBlocks extends WP_UnitTestCase { const TEST_THEME_NAME = 'block-theme-with-hooked-blocks'; + /** + * Original stylesheet. + * + * @var string + */ + private $original_stylesheet; + + public function set_up() { + parent::set_up(); + $this->original_stylesheet = get_stylesheet(); + } + /** * Tear down after each test. * @@ -43,6 +55,10 @@ public function tear_down() { } } + if ( get_stylesheet() !== $this->original_stylesheet ) { + switch_theme( $this->original_stylesheet ); + } + parent::tear_down(); } diff --git a/tests/phpunit/tests/blocks/register.php b/tests/phpunit/tests/blocks/register.php index d2a836ba85e68..81cebf27c798c 100644 --- a/tests/phpunit/tests/blocks/register.php +++ b/tests/phpunit/tests/blocks/register.php @@ -20,6 +20,13 @@ class Tests_Blocks_Register extends WP_UnitTestCase { */ protected $original_wp_styles; + /** + * Original stylesheet. + * + * @var string + */ + private $original_stylesheet; + /** * ID for a test post. * @@ -61,6 +68,7 @@ public function render_stub() {} */ public function set_up() { parent::set_up(); + $this->original_stylesheet = get_stylesheet(); global $wp_scripts, $wp_styles; $this->original_wp_scripts = $wp_scripts; @@ -96,6 +104,10 @@ public function tear_down() { $wp_scripts = $this->original_wp_scripts; $wp_styles = $this->original_wp_styles; + if ( get_stylesheet() !== $this->original_stylesheet ) { + switch_theme( $this->original_stylesheet ); + } + parent::tear_down(); } diff --git a/tests/phpunit/tests/blocks/wpBlockPatternsRegistry.php b/tests/phpunit/tests/blocks/wpBlockPatternsRegistry.php index 738d086f4a30e..b4b83be1048f3 100644 --- a/tests/phpunit/tests/blocks/wpBlockPatternsRegistry.php +++ b/tests/phpunit/tests/blocks/wpBlockPatternsRegistry.php @@ -27,6 +27,13 @@ class Tests_Blocks_wpBlockPatternsRegistry extends WP_UnitTestCase { */ private $original_registered_patterns = null; + /** + * Original stylesheet. + * + * @var string + */ + private $original_stylesheet; + /** * Set up each test method. * @@ -37,6 +44,7 @@ public function set_up() { $this->registry = new WP_Block_Patterns_Registry(); $this->original_registered_patterns = $this->get_registered_patterns_variable_value(); + $this->original_stylesheet = get_stylesheet(); } /** @@ -54,6 +62,11 @@ public function tear_down() { } $this->set_registered_patterns_variable_value( $this->original_registered_patterns ); + + if ( get_stylesheet() !== $this->original_stylesheet ) { + switch_theme( $this->original_stylesheet ); + } + parent::tear_down(); } diff --git a/tests/phpunit/tests/theme/wpThemeGetBlockPatterns.php b/tests/phpunit/tests/theme/wpThemeGetBlockPatterns.php index cd27aa00fd034..cc1827496a92f 100644 --- a/tests/phpunit/tests/theme/wpThemeGetBlockPatterns.php +++ b/tests/phpunit/tests/theme/wpThemeGetBlockPatterns.php @@ -19,14 +19,27 @@ class Tests_Theme_WPThemeGetBlockPatterns extends WP_UnitTestCase { */ private $initial_cache_object; + /** + * Original stylesheet. + * + * @var string + */ + private $original_stylesheet; + public function set_up() { parent::set_up(); $this->initial_cache_object = wp_using_ext_object_cache(); + $this->original_stylesheet = get_stylesheet(); } public function tear_down() { wp_using_ext_object_cache( $this->initial_cache_object ); + + if ( get_stylesheet() !== $this->original_stylesheet ) { + switch_theme( $this->original_stylesheet ); + } + parent::tear_down(); } From 2a616e3e7cd70b40f718ff0ebaba3fadccf00587 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 10 Sep 2026 22:57:55 +0000 Subject: [PATCH 479/634] Docs: Use the `bool` and `int` short type forms in PHPDoc. The PHP inline documentation standards call for `bool` and `int` in `@param`, `@return` and `@global` tags, but six docblocks in `src/wp-includes` still carried the long `boolean` and `integer` spellings. Developed in https://github.com/WordPress/wordpress-develop/pull/13476. Follow-up to r63495. Props njones35. See #65860. git-svn-id: https://develop.svn.wordpress.org/trunk@63596 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/class-wp-theme-json.php | 12 ++++++------ src/wp-includes/global-styles-and-settings.php | 2 +- .../html-api/class-wp-html-tag-processor.php | 2 +- src/wp-includes/media.php | 2 +- .../class-wp-rest-global-styles-controller.php | 2 +- .../endpoints/class-wp-rest-templates-controller.php | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/wp-includes/class-wp-theme-json.php b/src/wp-includes/class-wp-theme-json.php index 1252ca6736fd6..e91d547eb58f1 100644 --- a/src/wp-includes/class-wp-theme-json.php +++ b/src/wp-includes/class-wp-theme-json.php @@ -3009,12 +3009,12 @@ protected static function flatten_tree( $tree, $prefix = '', $token = '--' ) { * @since 6.6.0 Pass current theme JSON settings to wp_get_typography_font_size_value(), and process background properties. * @since 6.7.0 `ref` resolution of background properties, and assigning custom default values. * - * @param array $styles Styles to process. - * @param array $settings Theme settings. - * @param array $properties Properties metadata. - * @param array $theme_json Theme JSON array. - * @param string $selector The style block selector. - * @param boolean $use_root_padding Whether to add custom properties at root level. + * @param array $styles Styles to process. + * @param array $settings Theme settings. + * @param array $properties Properties metadata. + * @param array $theme_json Theme JSON array. + * @param string $selector The style block selector. + * @param bool $use_root_padding Whether to add custom properties at root level. * @return array Returns the modified $declarations. */ protected static function compute_style_properties( $styles, $settings = array(), $properties = null, $theme_json = null, $selector = null, $use_root_padding = null ) { diff --git a/src/wp-includes/global-styles-and-settings.php b/src/wp-includes/global-styles-and-settings.php index 0534d8b0dee58..c4a3284dadb91 100644 --- a/src/wp-includes/global-styles-and-settings.php +++ b/src/wp-includes/global-styles-and-settings.php @@ -497,7 +497,7 @@ function wp_get_theme_data_template_parts() { * * @param WP_Block_Type $block_type The block's type. * @param string|array $target The desired selector's target, `root` or array path. - * @param boolean $fallback Whether to fall back to broader selector. + * @param bool $fallback Whether to fall back to broader selector. * @return string|null CSS selector or `null` if no selector available. */ function wp_get_block_css_selector( $block_type, $target = 'root', $fallback = false ) { diff --git a/src/wp-includes/html-api/class-wp-html-tag-processor.php b/src/wp-includes/html-api/class-wp-html-tag-processor.php index b59baaf5a81cb..cd5814f0a4ad3 100644 --- a/src/wp-includes/html-api/class-wp-html-tag-processor.php +++ b/src/wp-includes/html-api/class-wp-html-tag-processor.php @@ -2789,7 +2789,7 @@ private static function sort_start_ascending( WP_HTML_Text_Replacement $a, WP_HT * @ignore * * @param string $comparable_name The attribute name in its comparable form. - * @return string|boolean|null Value of enqueued update if present, otherwise false. + * @return string|bool|null Value of enqueued update if present, otherwise false. */ private function get_enqueued_attribute_value( string $comparable_name ) { if ( self::STATE_MATCHED_TAG !== $this->parser_state ) { diff --git a/src/wp-includes/media.php b/src/wp-includes/media.php index be0b2fbf098cc..1e0b86655e82a 100644 --- a/src/wp-includes/media.php +++ b/src/wp-includes/media.php @@ -2120,7 +2120,7 @@ function wp_img_tag_add_auto_sizes( string $image ): string { * * @since 6.7.1 * - * @param boolean $enabled Whether auto-sizes for lazy loaded images is enabled. + * @param bool $enabled Whether auto-sizes for lazy loaded images is enabled. */ if ( ! apply_filters( 'wp_img_tag_add_auto_sizes', true ) ) { return $image; diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php index ed8195cbb91b7..83466acad0948 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php @@ -386,7 +386,7 @@ public function prepare_item_for_response( $post, $request ) { * @since 5.9.0 * @since 6.3.0 Adds revisions count and rest URL href to version-history. * - * @param integer $id ID. + * @param int $id ID. * @return array Links for the given post. */ protected function prepare_links( $id ) { diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-templates-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-templates-controller.php index 0941ee4ea53e3..190eea6b203bb 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-templates-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-templates-controller.php @@ -967,7 +967,7 @@ private static function get_wp_templates_author_text_field( $template_object ) { * * @since 5.8.0 * - * @param integer $id ID. + * @param int $id ID. * @return array Links for the given post. */ protected function prepare_links( $id ) { From 5aac49a2d6bf28944a3c9ed5827a622e02696649 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 10 Sep 2026 23:07:39 +0000 Subject: [PATCH 480/634] Build/Test Tools: Add `libxml` to the suggested extensions in `composer.json`. There are `LIBXML_*` constants conditionally used in SimplePie, ID3, and PHPUnit tests. Follow-up to r63004. See #65819, #65571. git-svn-id: https://develop.svn.wordpress.org/trunk@63597 602fd350-edb4-49c9-b593-d223f7449a82 --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 06edbbf0e776d..b510b99156d53 100644 --- a/composer.json +++ b/composer.json @@ -29,6 +29,7 @@ "ext-igbinary": "*", "ext-imagick": "*", "ext-intl": "*", + "ext-libxml": "*", "ext-mbstring": "*", "ext-memcached": "*", "ext-mysqli": "*", From 501d9201eba3c12fdb761ea49c27b720ee112713 Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Fri, 11 Sep 2026 06:29:08 +0000 Subject: [PATCH 481/634] General: Enable the JSDoc rule require-param-description. Enables the JSDoc rule `require-param-description` and fixes all the reported violations. Part of the effort to improve JS inline documentation for 7.2. Developed in https://github.com/WordPress/wordpress-develop/pull/13475 Props afercia, westonruter. See #66033. git-svn-id: https://develop.svn.wordpress.org/trunk@63598 602fd350-edb4-49c9-b593-d223f7449a82 --- .eslintrc-jsdoc.js | 1 + src/js/_enqueues/admin/postbox.js | 8 ++-- src/js/_enqueues/admin/site-health.js | 4 +- src/js/_enqueues/lib/embed-template.js | 4 +- src/js/_enqueues/lib/lists.js | 4 +- src/js/_enqueues/wp/api.js | 2 +- src/js/_enqueues/wp/dashboard.js | 4 +- src/js/_enqueues/wp/heartbeat.js | 4 +- src/js/_enqueues/wp/media/editor.js | 10 ++--- src/js/_enqueues/wp/media/models.js | 14 +++--- src/js/_enqueues/wp/media/views.js | 4 +- src/js/_enqueues/wp/updates.js | 10 ++--- src/js/media/controllers/embed.js | 2 +- src/js/media/controllers/library.js | 10 ++--- src/js/media/controllers/region.js | 10 ++--- src/js/media/controllers/state-machine.js | 4 +- src/js/media/models/attachment.js | 12 +++--- src/js/media/models/attachments.js | 52 +++++++++++------------ src/js/media/models/query.js | 40 ++++++++--------- src/js/media/models/selection.js | 10 ++--- src/js/media/views/attachment-compat.js | 4 +- src/js/media/views/attachment.js | 42 +++++++++--------- src/js/media/views/attachments.js | 2 +- src/js/media/views/button.js | 2 +- src/js/media/views/embed.js | 2 +- src/js/media/views/frame.js | 6 +-- src/js/media/views/frame/post.js | 6 +-- src/js/media/views/frame/select.js | 8 ++-- src/js/media/views/media-details.js | 6 +-- src/js/media/views/media-frame.js | 12 +++--- src/js/media/views/menu.js | 4 +- src/js/media/views/modal.js | 11 ++--- src/js/media/views/priority-list.js | 12 +++--- src/js/media/views/settings.js | 4 +- src/js/media/views/toolbar.js | 12 +++--- src/js/media/views/uploader/status.js | 4 +- 36 files changed, 176 insertions(+), 170 deletions(-) diff --git a/.eslintrc-jsdoc.js b/.eslintrc-jsdoc.js index e3c98d449f3c5..dc6559c520cbe 100644 --- a/.eslintrc-jsdoc.js +++ b/.eslintrc-jsdoc.js @@ -52,6 +52,7 @@ module.exports = [ 'jsdoc/require-param': [ 'error', { enableFixer: false, } ], + 'jsdoc/require-param-description': 'error', 'jsdoc/require-param-name': 'error', 'jsdoc/require-param-type': 'error', 'jsdoc/require-returns': 'error', diff --git a/src/js/_enqueues/admin/postbox.js b/src/js/_enqueues/admin/postbox.js index b6d1b6569dc84..1f101d3fd1c41 100644 --- a/src/js/_enqueues/admin/postbox.js +++ b/src/js/_enqueues/admin/postbox.js @@ -246,10 +246,10 @@ * * @memberof postboxes * - * @param {string} page The page we are currently on. - * @param {Object} [args] - * @param {Function} args.pbshow A callback that is called when a postbox opens. - * @param {Function} args.pbhide A callback that is called when a postbox closes. + * @param {string} page The page we are currently on. + * @param {Object} [args] Optional arguments for the postbox toggles. + * @param {Function} [args.pbshow] A callback that is called when a postbox opens. + * @param {Function} [args.pbhide] A callback that is called when a postbox closes. * @return {void} */ add_postbox_toggles : function (page, args) { diff --git a/src/js/_enqueues/admin/site-health.js b/src/js/_enqueues/admin/site-health.js index dc9107a3ebc2f..0a1b052e56f3b 100644 --- a/src/js/_enqueues/admin/site-health.js +++ b/src/js/_enqueues/admin/site-health.js @@ -350,8 +350,8 @@ jQuery( function( $ ) { /** * Add the details of a failed asynchronous test to the list of test results. * - * @param {string} url - * @param {string} description + * @param {string} url The URL of the failed test. + * @param {string} description The description of the failed test. * @since 5.6.0 */ function addFailedSiteHealthCheckNotice( url, description ) { diff --git a/src/js/_enqueues/lib/embed-template.js b/src/js/_enqueues/lib/embed-template.js index e43ef97b8fe96..85c1369322b98 100644 --- a/src/js/_enqueues/lib/embed-template.js +++ b/src/js/_enqueues/lib/embed-template.js @@ -196,7 +196,7 @@ /** * Detect clicks to external (_top) links. * - * @param {MouseEvent} event + * @param {MouseEvent} event The click event object. */ function linkClickHandler( event ) { /* @@ -237,7 +237,7 @@ /** * Message handler. * - * @param {MessageEvent} event + * @param {MessageEvent} event The message event object. */ function onMessage( event ) { var data = event.data; diff --git a/src/js/_enqueues/lib/lists.js b/src/js/_enqueues/lib/lists.js index 3f667a043478a..44e71a84ed488 100644 --- a/src/js/_enqueues/lib/lists.js +++ b/src/js/_enqueues/lib/lists.js @@ -739,7 +739,7 @@ wpList = { /** * Registers event handlers to add, delete, and dim items. * - * @param {string} elementId + * @param {string} elementId ID of the element to process, including leading #. */ process: function( elementId ) { var list = this, @@ -812,7 +812,7 @@ wpList = { /** * Initializes wpList object. * - * @param {Object} settings + * @param {Object} settings The settings for the wpList instance. * @param {string} settings.url URL for ajax calls. Default: ajaxurl. * @param {string} settings.type The HTTP method to use for Ajax requests. Default: 'POST'. * @param {string} settings.response ID of the element the parsed ajax response will be stored in. diff --git a/src/js/_enqueues/wp/api.js b/src/js/_enqueues/wp/api.js index a66d96c3fb81c..b15a74628a92c 100644 --- a/src/js/_enqueues/wp/api.js +++ b/src/js/_enqueues/wp/api.js @@ -1546,7 +1546,7 @@ /** * Initialize the wp-api, optionally passing the API root. * - * @param {Object} [args] + * @param {Object} [args] The arguments for initializing the wp-api. * @param {string} [args.nonce] The nonce. Optional, defaults to wpApiSettings.nonce. * @param {string} [args.apiRoot] The api root. Optional, defaults to wpApiSettings.root. * @param {string} [args.versionString] The version string. Optional, defaults to wpApiSettings.root. diff --git a/src/js/_enqueues/wp/dashboard.js b/src/js/_enqueues/wp/dashboard.js index 31c9cd7cb1547..595133d790782 100644 --- a/src/js/_enqueues/wp/dashboard.js +++ b/src/js/_enqueues/wp/dashboard.js @@ -703,7 +703,7 @@ jQuery( function( $ ) { * * @since 5.5.2 * - * @param {number} startTimestamp + * @param {number} startTimestamp The start timestamp of the event. * * @return {number} The offset from UTC in minutes, with the sign flipped to be more intuitive. */ @@ -716,7 +716,7 @@ jQuery( function( $ ) { * * @since 5.5.2 * - * @param {number} startTimestamp + * @param {number} startTimestamp The start timestamp of the event. * * @return {string} A short time zone name, like `PST`, or a string like `GMT+5` if the abbreviation can't be determined. */ diff --git a/src/js/_enqueues/wp/heartbeat.js b/src/js/_enqueues/wp/heartbeat.js index e7abe77bb378f..e816959bda1bf 100644 --- a/src/js/_enqueues/wp/heartbeat.js +++ b/src/js/_enqueues/wp/heartbeat.js @@ -244,8 +244,8 @@ /** * Handles pageshow event, specifically when page navigation is restored from back/forward cache. * - * @param {jQuery.Event} event - * @param {PageTransitionEvent} event.originalEvent + * @param {JQuery.Event} event The jQuery event object. + * @param {PageTransitionEvent} event.originalEvent The original PageTransitionEvent object. */ function ( event ) { if ( event.originalEvent.persisted ) { diff --git a/src/js/_enqueues/wp/media/editor.js b/src/js/_enqueues/wp/media/editor.js index bec97f27f0dd3..b6357520db557 100644 --- a/src/js/_enqueues/wp/media/editor.js +++ b/src/js/_enqueues/wp/media/editor.js @@ -341,7 +341,7 @@ * * @class wp.media.collection * - * @param {Object} attributes + * @param {Object} attributes The attributes for the media collection. */ wp.media.collection = function(attributes) { var collections = {}; @@ -786,8 +786,8 @@ * Setup 'workflow' and add to the 'workflows' cache. 'open' can * subsequently be called upon it. * - * @param {string} id A slug used to identify the workflow. - * @param {Object} [options={}] + * @param {string} id A slug used to identify the workflow. + * @param {Object} [options={}] The options for the media workflow. * * @this wp.media.editor * @@ -1001,7 +1001,7 @@ /** * Called when 'Insert From URL' source is not an image. Example: YouTube url. * - * @param {Object} embed + * @param {Object} embed The embed object containing the link URL and link text. * @return {Promise} A promise that resolves when the link has been sent to the editor. */ link: function( embed ) { @@ -1018,7 +1018,7 @@ * Opens a workflow. * * @param {string} [id=undefined] Optional. A slug used to identify the workflow. - * @param {Object} [options={}] + * @param {Object} [options={}] The options for the media workflow. * * @this wp.media.editor * diff --git a/src/js/_enqueues/wp/media/models.js b/src/js/_enqueues/wp/media/models.js index f184ebdba60ad..e10db02bfd4b2 100644 --- a/src/js/_enqueues/wp/media/models.js +++ b/src/js/_enqueues/wp/media/models.js @@ -136,7 +136,11 @@ _.extend( media, /** @lends wp.media */{ /** * Scales a set of dimensions to fit within bounding dimensions. * - * @param {Object} dimensions + * @param {Object} dimensions The dimensions to scale. + * @param {number} dimensions.width The width to scale. + * @param {number} dimensions.height The height to scale. + * @param {number} dimensions.maxWidth The maxWidth to scale. + * @param {number} dimensions.maxHeight The maxHeight to scale. * @return {Object} The scaled dimensions. */ fit: function( dimensions ) { @@ -182,9 +186,9 @@ _.extend( media, /** @lends wp.media */{ * Truncates a string by injecting an ellipsis into the middle. * Useful for filenames. * - * @param {string} string - * @param {number} [length=30] - * @param {string} [replacement=…] + * @param {string} string The string to truncate. + * @param {number} [length=30] The maximum length of the truncated string. + * @param {string} [replacement=…] The string to use as the ellipsis replacement. * @return {string} The string, unless length is greater than string.length. */ truncate: function( string, length, replacement ) { @@ -228,7 +232,7 @@ Attachments.all = new Attachments(); * * Shorthand for creating a new Attachments Query. * - * @param {Object} [props] + * @param {Object} [props] The properties to filter the attachments by. * @return {wp.media.model.Attachments} A collection of attachments matching the query. */ media.query = function( props ) { diff --git a/src/js/_enqueues/wp/media/views.js b/src/js/_enqueues/wp/media/views.js index 2f845bb7a82c5..1eec769227e12 100644 --- a/src/js/_enqueues/wp/media/views.js +++ b/src/js/_enqueues/wp/media/views.js @@ -47,8 +47,8 @@ media.events = _.extend( {}, Backbone.Events ); /** * Makes it easier to bind events using transitions. * - * @param {string} selector - * @param {number} sensitivity + * @param {string} selector The CSS selector for the element to bind the transition event to. + * @param {number} sensitivity The maximum time to wait for the transition event before resolving the promise. * @return {Promise} A promise that resolves when the transition has completed. */ media.transition = function( selector, sensitivity ) { diff --git a/src/js/_enqueues/wp/updates.js b/src/js/_enqueues/wp/updates.js index 22e7ac886ff30..7c971f4bb7d80 100644 --- a/src/js/_enqueues/wp/updates.js +++ b/src/js/_enqueues/wp/updates.js @@ -241,7 +241,7 @@ * * @since 4.6.0 * - * @param {Object} data + * @param {Object} data The data for the admin notice. * @param {*} [data.selector] Optional. Selector of an element to be replaced with the admin notice. * @param {string} [data.id] Optional. Unique id that will be used as the notice's id attribute. * @param {string} [data.className] Optional. Class names that will be used in the admin notice. @@ -334,7 +334,7 @@ * * @since 4.6.0 * - * @param {Object} response + * @param {Object} response The response object from the Ajax request. * @param {Array} [response.debug] Optional. Debug information. * @param {string} [response.errorCode] Optional. Error code for an error that occurred. */ @@ -1594,7 +1594,7 @@ * @since 4.6.0 * @since 5.5.0 Auto-update "time to next update" text cleared. * - * @param {Object} response + * @param {Object} response The response object from the Ajax request. * @param {string} response.slug Slug of the theme to be updated. * @param {Object} response.theme Updated theme. * @param {string} response.oldVersion Old version of the theme. @@ -1709,7 +1709,7 @@ * * @since 4.6.0 * - * @param {Object} args + * @param {Object} args The arguments for the theme installation request. * @param {string} args.slug Theme stylesheet. * @param {installThemeSuccess} args.success Optional. Success callback. Default: wp.updates.installThemeSuccess * @param {installThemeError} args.error Optional. Error callback. Default: wp.updates.installThemeError @@ -1901,7 +1901,7 @@ * * @since 4.6.0 * - * @param {Object} args + * @param {Object} args The arguments for the theme deletion request. * @param {string} args.slug Theme stylesheet. * @param {deleteThemeSuccess} args.success Optional. Success callback. Default: wp.updates.deleteThemeSuccess * @param {deleteThemeError} args.error Optional. Error callback. Default: wp.updates.deleteThemeError diff --git a/src/js/media/controllers/embed.js b/src/js/media/controllers/embed.js index 3c33769704c68..e485260cc5fe3 100644 --- a/src/js/media/controllers/embed.js +++ b/src/js/media/controllers/embed.js @@ -89,7 +89,7 @@ Embed = wp.media.controller.State.extend(/** @lends wp.media.controller.Embed.pr /** * Try scanning the embed as an image to discover its dimensions. * - * @param {Object} attributes + * @param {Object} attributes The attributes for the embed scan. */ scanImage: function( attributes ) { var frame = this.frame, diff --git a/src/js/media/controllers/library.js b/src/js/media/controllers/library.js index 231b49b718256..4d41d5ed0e353 100644 --- a/src/js/media/controllers/library.js +++ b/src/js/media/controllers/library.js @@ -158,7 +158,7 @@ Library = wp.media.controller.State.extend(/** @lends wp.media.controller.Librar * * @since 3.5.0 * - * @param {wp.media.model.Attachment} attachment + * @param {wp.media.model.Attachment} attachment The attachment for which to create display settings. * @return {Backbone.Model} A model representing the display settings for the attachment. */ display: function( attachment ) { @@ -175,7 +175,7 @@ Library = wp.media.controller.State.extend(/** @lends wp.media.controller.Librar * * @since 3.6.0 * - * @param {wp.media.model.Attachment} attachment + * @param {wp.media.model.Attachment} attachment The attachment for which to get the default display settings. * @return {Object} The default display settings for the attachment. */ defaultDisplaySettings: function( attachment ) { @@ -196,7 +196,7 @@ Library = wp.media.controller.State.extend(/** @lends wp.media.controller.Librar * * @since 4.4.1 * - * @param {wp.media.model.Attachment} attachment + * @param {wp.media.model.Attachment} attachment The attachment to check. * @return {boolean} True if the attachment is an image, false otherwise. */ isImageAttachment: function( attachment ) { @@ -213,7 +213,7 @@ Library = wp.media.controller.State.extend(/** @lends wp.media.controller.Librar * * @since 3.6.0 * - * @param {wp.media.model.Attachment} attachment + * @param {wp.media.model.Attachment} attachment The attachment to check. * @return {boolean} True if the attachment can be embedded, false otherwise. */ canEmbed: function( attachment ) { @@ -262,7 +262,7 @@ Library = wp.media.controller.State.extend(/** @lends wp.media.controller.Librar * * @since 3.5.0 * - * @param {wp.media.model.Attachment} attachment + * @param {wp.media.model.Attachment} attachment The attachment that was uploaded. */ uploading: function( attachment ) { var content = this.frame.content; diff --git a/src/js/media/controllers/region.js b/src/js/media/controllers/region.js index 982182469b12a..120b43f2937c4 100644 --- a/src/js/media/controllers/region.js +++ b/src/js/media/controllers/region.js @@ -33,7 +33,7 @@ _.extend( Region.prototype,/** @lends wp.media.controller.Region.prototype */{ * * @since 3.5.0 * - * @param {string} mode + * @param {string} mode The mode to activate on the region. * * @fires Region#activate * @fires Region#deactivate @@ -72,7 +72,7 @@ _.extend( Region.prototype,/** @lends wp.media.controller.Region.prototype */{ * * @since 3.5.0 * - * @param {string} mode + * @param {string} mode The mode to render on the region. * * @fires Region#create * @fires Region#render @@ -131,8 +131,8 @@ _.extend( Region.prototype,/** @lends wp.media.controller.Region.prototype */{ * * @since 3.5.0 * - * @param {Array|Object} views - * @param {Object} [options={}] + * @param {Array|Object} views The views to set on the region. + * @param {Object} [options={}] Optional. Additional options for setting the views on the region. * @return {wp.Backbone.Subviews} Subviews is returned to allow chaining. */ set: function( views, options ) { @@ -147,7 +147,7 @@ _.extend( Region.prototype,/** @lends wp.media.controller.Region.prototype */{ * * @since 3.5.0 * - * @param {string} event + * @param {string} event The event to trigger on the region. * @return {undefined|wp.media.controller.Region} Returns itself to allow chaining. */ trigger: function( event ) { diff --git a/src/js/media/controllers/state-machine.js b/src/js/media/controllers/state-machine.js index fb97c4e3cac58..d7ebd815a2c52 100644 --- a/src/js/media/controllers/state-machine.js +++ b/src/js/media/controllers/state-machine.js @@ -35,7 +35,7 @@ _.extend( StateMachine.prototype, Backbone.Events,/** @lends wp.media.controller * * @since 3.5.0 * - * @param {string} id + * @param {string} id The ID of the state to fetch. If omitted, the active state is returned. * @return {wp.media.controller.State} Returns a State model from * the StateMachine collection. */ @@ -60,7 +60,7 @@ _.extend( StateMachine.prototype, Backbone.Events,/** @lends wp.media.controller * * @since 3.5.0 * - * @param {string} id + * @param {string} id The ID of the state to set as active. * * @fires wp.media.controller.State#deactivate * @fires wp.media.controller.State#activate diff --git a/src/js/media/models/attachment.js b/src/js/media/models/attachment.js index c10f87447e0c2..a116edf4add40 100644 --- a/src/js/media/models/attachment.js +++ b/src/js/media/models/attachment.js @@ -14,9 +14,9 @@ Attachment = Backbone.Model.extend(/** @lends wp.media.model.Attachment.prototyp * Triggered when attachment details change * Overrides Backbone.Model.sync * - * @param {string} method - * @param {wp.media.model.Attachment} model - * @param {Object} [options={}] + * @param {string} method The method to be performed: 'read', 'update', or 'delete'. + * @param {wp.media.model.Attachment} model The attachment model being synced. + * @param {Object} [options={}] Optional. Additional options for the sync operation. * * @return {jQuery.Promise} A jQuery Promise that is resolved or rejected based on the success of the sync operation. */ @@ -144,7 +144,7 @@ Attachment = Backbone.Model.extend(/** @lends wp.media.model.Attachment.prototyp * * @static * - * @param {Object} attrs + * @param {Object} attrs The attributes for the new attachment model. * @return {wp.media.model.Attachment} The newly created attachment model. */ create: function( attrs ) { @@ -158,8 +158,8 @@ Attachment = Backbone.Model.extend(/** @lends wp.media.model.Attachment.prototyp * it returns the specified attachment. * * @static - * @param {string} id A string used to identify a model. - * @param {Backbone.Model|undefined} attachment + * @param {string} id A string used to identify a model. + * @param {Backbone.Model|undefined} attachment The attachment model to retrieve or create. * @return {wp.media.model.Attachment} */ get: _.memoize( function( id, attachment ) { diff --git a/src/js/media/models/attachments.js b/src/js/media/models/attachments.js index 80289cb43a061..fc6d79632d745 100644 --- a/src/js/media/models/attachments.js +++ b/src/js/media/models/attachments.js @@ -30,8 +30,8 @@ var Attachments = Backbone.Collection.extend(/** @lends wp.media.model.Attachmen /** * Initializes the Attachments collection. * - * @param {Array} [models=[]] Array of models used to populate the collection. - * @param {Object} [options={}] + * @param {Array} [models=[]] Optional. Array of models used to populate the collection. + * @param {Object} [options={}] Optional. Additional options for the collection. */ initialize: function( models, options ) { var normalizedOrder; @@ -81,8 +81,8 @@ var Attachments = Backbone.Collection.extend(/** @lends wp.media.model.Attachmen * * @access private * - * @param {Backbone.Model} model - * @param {string} orderby + * @param {Backbone.Model} model The model that triggered the change. + * @param {string} orderby The new orderby value. */ _changeOrderby: function( model, orderby ) { // If a different comparator is defined, bail. @@ -101,8 +101,8 @@ var Attachments = Backbone.Collection.extend(/** @lends wp.media.model.Attachmen * * @access private * - * @param {Backbone.Model} model - * @param {boolean} query + * @param {Backbone.Model} model The model that triggered the change. + * @param {boolean} query The new query value. */ _changeQuery: function( model, query ) { if ( query ) { @@ -117,7 +117,7 @@ var Attachments = Backbone.Collection.extend(/** @lends wp.media.model.Attachmen * * @access private * - * @param {Backbone.Model} model + * @param {Backbone.Model} model The model that triggered the change. */ _changeFilteredProps: function( model ) { // If this is a query, updating the collection will be handled by @@ -163,7 +163,7 @@ var Attachments = Backbone.Collection.extend(/** @lends wp.media.model.Attachmen /** * Checks whether an attachment is valid. * - * @param {wp.media.model.Attachment} attachment + * @param {wp.media.model.Attachment} attachment The attachment to validate. * @return {boolean} True if the attachment is valid, false otherwise. */ validator: function( attachment ) { @@ -178,8 +178,8 @@ var Attachments = Backbone.Collection.extend(/** @lends wp.media.model.Attachmen /** * Adds or removes an attachment to the collection depending on its validity. * - * @param {wp.media.model.Attachment} attachment - * @param {Object} options + * @param {wp.media.model.Attachment} attachment The attachment to validate and potentially add or remove. + * @param {Object} options Additional options for the operation. * @return {wp.media.model.Attachments} Returns itself to allow chaining. */ validate: function( attachment, options ) { @@ -198,8 +198,8 @@ var Attachments = Backbone.Collection.extend(/** @lends wp.media.model.Attachmen /** * Adds or removes all attachments from another collection depending on each one's validity. * - * @param {wp.media.model.Attachments} attachments - * @param {Object} [options={}] + * @param {wp.media.model.Attachments} attachments The attachments collection to validate against. + * @param {Object} [options={}] Additional options for the operation. * * @fires wp.media.model.Attachments#reset * @@ -281,9 +281,9 @@ var Attachments = Backbone.Collection.extend(/** @lends wp.media.model.Attachmen * * @access private * - * @param {wp.media.model.Attachments} attachment - * @param {wp.media.model.Attachments} attachments - * @param {Object} options + * @param {wp.media.model.Attachments} attachment The attachment to validate. + * @param {wp.media.model.Attachments} attachments The attachments collection the attachment belongs to. + * @param {Object} options Additional options for the operation. * * @return {wp.media.model.Attachments} Returns itself to allow chaining. */ @@ -301,8 +301,8 @@ var Attachments = Backbone.Collection.extend(/** @lends wp.media.model.Attachmen * * @access private * - * @param {wp.media.model.Attachments} attachments - * @param {Object} options + * @param {wp.media.model.Attachments} attachments The attachments collection to validate against. + * @param {Object} options Additional options for the operation. * @return {wp.media.model.Attachments} Returns itself to allow chaining. */ _validateAllHandler: function( attachments, options ) { @@ -355,7 +355,7 @@ var Attachments = Backbone.Collection.extend(/** @lends wp.media.model.Attachmen * and forwards to its `more` method. This collection class doesn't have * server persistence by itself. * - * @param {Object} options + * @param {Object} options Additional options for the operation. * @return {Promise} A promise that resolves when the request is complete. */ more: function( options ) { @@ -424,7 +424,7 @@ var Attachments = Backbone.Collection.extend(/** @lends wp.media.model.Attachmen * the collection items. * * @param {Object|Array} response The raw response Object/Array. - * @param {Object} xhr + * @param {Object} xhr The XMLHttpRequest object. * @return {Array} The array of model attributes to be added to the collection */ parse: function( response, xhr ) { @@ -505,9 +505,9 @@ var Attachments = Backbone.Collection.extend(/** @lends wp.media.model.Attachmen * Used as the default comparator for instances of wp.media.model.Attachments * and its subclasses. @see wp.media.model.Attachments._changeOrderby(). * - * @param {Backbone.Model} a - * @param {Backbone.Model} b - * @param {Object} options + * @param {Backbone.Model} a The first attachment model to compare. + * @param {Backbone.Model} b The second attachment model to compare. + * @param {Object} options Additional options for the comparison. * @return {number} -1 if the first model should come before the second, * 0 if they are of the same rank and * 1 if the first model should come after. @@ -542,7 +542,7 @@ var Attachments = Backbone.Collection.extend(/** @lends wp.media.model.Attachmen * Note that this client-side searching is *not* equivalent * to our server-side searching. * - * @param {wp.media.model.Attachment} attachment + * @param {wp.media.model.Attachment} attachment The attachment to filter based on the search query. * * @this wp.media.model.Attachments * @@ -562,7 +562,7 @@ var Attachments = Backbone.Collection.extend(/** @lends wp.media.model.Attachmen * Filters attachments based on their type. * * @static - * @param {wp.media.model.Attachment} attachment + * @param {wp.media.model.Attachment} attachment The attachment to filter based on its type. * * @this wp.media.model.Attachments * @@ -591,7 +591,7 @@ var Attachments = Backbone.Collection.extend(/** @lends wp.media.model.Attachmen * Filters attachments based on their uploadedTo property. * * @static - * @param {wp.media.model.Attachment} attachment + * @param {wp.media.model.Attachment} attachment The attachment to filter based on its uploadedTo property. * * @this wp.media.model.Attachments * @@ -609,7 +609,7 @@ var Attachments = Backbone.Collection.extend(/** @lends wp.media.model.Attachmen * Filters attachments based on their status property. * * @static - * @param {wp.media.model.Attachment} attachment + * @param {wp.media.model.Attachment} attachment The attachment to filter based on its status property. * * @this wp.media.model.Attachments * diff --git a/src/js/media/models/query.js b/src/js/media/models/query.js index db6008a6fecf4..dbcdb87d77466 100644 --- a/src/js/media/models/query.js +++ b/src/js/media/models/query.js @@ -25,7 +25,7 @@ Query = Attachments.extend(/** @lends wp.media.model.Query.prototype */{ * Initializes the Query collection. * * @param {Array} [models=[]] Array of initial models to populate the collection. - * @param {Object} [options={}] + * @param {Object} [options={}] Additional options for initializing the query. */ initialize: function( models, options ) { var allowed; @@ -96,7 +96,7 @@ Query = Attachments.extend(/** @lends wp.media.model.Query.prototype */{ /** * Fetch more attachments from the server for the collection. * - * @param {Object} [options={}] + * @param {Object} [options={}] Additional options for fetching more attachments. * @return {Promise} A promise that resolves when the fetch is complete. */ more: function( options ) { @@ -124,9 +124,9 @@ Query = Attachments.extend(/** @lends wp.media.model.Query.prototype */{ * Overrides Backbone.Collection.sync * Overrides wp.media.model.Attachments.sync * - * @param {string} method - * @param {Backbone.Model} model - * @param {Object} [options={}] + * @param {string} method The sync method to be used (e.g., 'read', 'create', 'update', 'delete'). + * @param {Backbone.Model} model The model to be synced. + * @param {Object} [options={}] Additional options for syncing the query. * @return {Promise} A promise that resolves when the sync is complete. */ sync: function( method, model, options ) { @@ -214,19 +214,19 @@ Query = Attachments.extend(/** @lends wp.media.model.Query.prototype */{ * @static * @function * - * @param {Object} [props] - * @param {Object} [props.order] - * @param {Object} [props.orderby] - * @param {Object} [props.include] - * @param {Object} [props.exclude] - * @param {Object} [props.s] - * @param {Object} [props.post_mime_type] - * @param {Object} [props.posts_per_page] - * @param {Object} [props.menu_order] - * @param {Object} [props.post_parent] - * @param {Object} [props.post_status] - * @param {Object} [props.author] - * @param {Object} [options] + * @param {Object} [props] The properties to initialize the query with. + * @param {Object} [props.order] The order in which to sort the query results. + * @param {Object} [props.orderby] The property by which to order the query results. + * @param {Object} [props.include] The IDs of attachments to include in the query. + * @param {Object} [props.exclude] The IDs of attachments to exclude from the query. + * @param {Object} [props.s] The search term to filter attachments by. + * @param {Object} [props.post_mime_type] The MIME type to filter attachments by. + * @param {Object} [props.posts_per_page] The number of attachments to retrieve per page. + * @param {Object} [props.menu_order] The menu order to filter attachments by. + * @param {Object} [props.post_parent] The parent post ID to filter attachments by. + * @param {Object} [props.post_status] The status to filter attachments by. + * @param {Object} [props.author] The author ID to filter attachments by. + * @param {Object} [options] Additional options for the query. * * @return {wp.media.model.Query} A new Attachments Query collection. */ @@ -240,8 +240,8 @@ Query = Attachments.extend(/** @lends wp.media.model.Query.prototype */{ /** * Creates and returns an Attachments Query collection given the properties. * - * @param {Object} [props] - * @param {Object} [options] + * @param {Object} [props] The properties to initialize the query with. + * @param {Object} [options] Additional options for the query. * @return {Query} A new Attachments Query collection. */ return function( props, options ) { diff --git a/src/js/media/models/selection.js b/src/js/media/models/selection.js index b7ae7bbadd816..7e03ce4f4119e 100644 --- a/src/js/media/models/selection.js +++ b/src/js/media/models/selection.js @@ -18,8 +18,8 @@ Selection = Attachments.extend(/** @lends wp.media.model.Selection.prototype */{ * Binds `single` instead of using the context argument to ensure * it receives no parameters. * - * @param {Array} [models=[]] Array of models used to populate the collection. - * @param {Object} [options={}] + * @param {Array} [models=[]] Array of models used to populate the collection. + * @param {Object} [options={}] Additional options for the selection. */ initialize: function( models, options ) { /** @@ -35,8 +35,8 @@ Selection = Attachments.extend(/** @lends wp.media.model.Selection.prototype */{ * If the workflow does not support multi-select, clear out the selection * before adding a new attachment to it. * - * @param {Array} models - * @param {Object} options + * @param {Array} models The models to add to the selection. + * @param {Object} options Additional options for adding the models. * @return {wp.media.model.Attachment[]} The added attachments. */ add: function( models, options ) { @@ -52,7 +52,7 @@ Selection = Attachments.extend(/** @lends wp.media.model.Selection.prototype */{ /** * Fired when toggling (clicking on) an attachment in the modal. * - * @param {undefined|boolean|wp.media.model.Attachment} model + * @param {undefined|boolean|wp.media.model.Attachment} model The model to set as the single selection, or a boolean to clear it. * * @fires wp.media.model.Selection#selection:single * @fires wp.media.model.Selection#selection:unsingle diff --git a/src/js/media/views/attachment-compat.js b/src/js/media/views/attachment-compat.js index 3871b6e43f3fb..f2ba1872d76c4 100644 --- a/src/js/media/views/attachment-compat.js +++ b/src/js/media/views/attachment-compat.js @@ -62,7 +62,7 @@ AttachmentCompat = View.extend(/** @lends wp.media.view.AttachmentCompat.prototy /** * Prevents the default action of the event. * - * @param {Object} event + * @param {JQuery.Event} event The jQuery event object associated with the action. */ preventDefault: function( event ) { event.preventDefault(); @@ -70,7 +70,7 @@ AttachmentCompat = View.extend(/** @lends wp.media.view.AttachmentCompat.prototy /** * Saves the attachment compat data. * - * @param {Object} event + * @param {JQuery.Event} event The jQuery event object associated with the action. */ save: function( event ) { var data = {}; diff --git a/src/js/media/views/attachment.js b/src/js/media/views/attachment.js index e0033d355a1c6..152c150200a75 100644 --- a/src/js/media/views/attachment.js +++ b/src/js/media/views/attachment.js @@ -173,7 +173,7 @@ Attachment = View.extend(/** @lends wp.media.view.Attachment.prototype */{ /** * Toggles the selection state of the attachment. * - * @param {Object} event + * @param {JQuery.Event} event The jQuery event object that triggered the selection toggle. */ toggleSelectionHandler: function( event ) { var method; @@ -229,7 +229,7 @@ Attachment = View.extend(/** @lends wp.media.view.Attachment.prototype */{ /** * Toggles the selection state of the attachment. * - * @param {Object} options + * @param {Object} options The options for toggling the selection state of the attachment. */ toggleSelection: function( options ) { var collection = this.collection, @@ -322,8 +322,8 @@ Attachment = View.extend(/** @lends wp.media.view.Attachment.prototype */{ /** * Selects the model in the selection. * - * @param {Backbone.Model} model - * @param {Backbone.Collection} collection + * @param {Backbone.Model} model The model to select. + * @param {Backbone.Collection} collection The collection containing the model. */ select: function( model, collection ) { var selection = this.options.selection, @@ -353,8 +353,8 @@ Attachment = View.extend(/** @lends wp.media.view.Attachment.prototype */{ /** * Deselects the model in the selection. * - * @param {Backbone.Model} model - * @param {Backbone.Collection} collection + * @param {Backbone.Model} model The model to deselect. + * @param {Backbone.Collection} collection The collection containing the model. */ deselect: function( model, collection ) { var selection = this.options.selection; @@ -373,8 +373,8 @@ Attachment = View.extend(/** @lends wp.media.view.Attachment.prototype */{ /** * Updates the view to reflect whether the model is the single model in the selection. * - * @param {Backbone.Model} model - * @param {Backbone.Collection} collection + * @param {Backbone.Model} model The model to check for details. + * @param {Backbone.Collection} collection The collection containing the model. */ details: function( model, collection ) { var selection = this.options.selection, @@ -390,7 +390,7 @@ Attachment = View.extend(/** @lends wp.media.view.Attachment.prototype */{ /** * Gets the image size object for the specified size. * - * @param {string} size + * @param {string} size The desired image size. * @return {Object} Returns an object containing the image size information. */ imageSize: function( size ) { @@ -425,7 +425,7 @@ Attachment = View.extend(/** @lends wp.media.view.Attachment.prototype */{ /** * Update the model's setting with the value from the input. * - * @param {Object} event + * @param {JQuery.Event} event The jQuery event object that triggered the setting update. */ updateSetting: function( event ) { var $setting = $( event.target ).closest('[data-setting]'), @@ -478,7 +478,7 @@ Attachment = View.extend(/** @lends wp.media.view.Attachment.prototype */{ /** * Updates the view's save status. * - * @param {string} status + * @param {string} status The new save status to apply to the view. * @return {wp.media.view.Attachment} Returns itself to allow chaining. */ updateSave: function( status ) { @@ -522,7 +522,7 @@ Attachment = View.extend(/** @lends wp.media.view.Attachment.prototype */{ /** * Removes the model from the collection. * - * @param {Object} event + * @param {JQuery.Event} event The jQuery event object that triggered the removal from the library. */ removeFromLibrary: function( event ) { // Catch enter and space events. @@ -540,7 +540,7 @@ Attachment = View.extend(/** @lends wp.media.view.Attachment.prototype */{ * Adds the model if it isn't in the selection, if it is in the selection, * removes it. * - * @param {Object} event + * @param {JQuery.Event} event The jQuery event object that triggered the selection toggle. * @return {void} */ checkClickHandler: function ( event ) { @@ -576,8 +576,8 @@ _.each({ * @memberOf wp.media.view.Attachment * @instance * - * @param {Backbone.Model} model - * @param {string} value + * @param {Backbone.Model} model The model containing the caption. + * @param {string} value The new caption value. * @return {wp.media.view.Attachment} Returns itself to allow chaining. */ /** @@ -587,8 +587,8 @@ _.each({ * @memberOf wp.media.view.Attachment * @instance * - * @param {Backbone.Model} model - * @param {string} value + * @param {Backbone.Model} model The model containing the title. + * @param {string} value The new title value. * @return {wp.media.view.Attachment} Returns itself to allow chaining. */ /** @@ -598,8 +598,8 @@ _.each({ * @memberOf wp.media.view.Attachment * @instance * - * @param {Backbone.Model} model - * @param {string} value + * @param {Backbone.Model} model The model containing the artist. + * @param {string} value The new artist value. * @return {wp.media.view.Attachment} Returns itself to allow chaining. */ /** @@ -609,8 +609,8 @@ _.each({ * @memberOf wp.media.view.Attachment * @instance * - * @param {Backbone.Model} model - * @param {string} value + * @param {Backbone.Model} model The model containing the album. + * @param {string} value The new album value. * @return {wp.media.view.Attachment} Returns itself to allow chaining. */ Attachment.prototype[ method ] = function( model, value ) { diff --git a/src/js/media/views/attachments.js b/src/js/media/views/attachments.js index b2e91624cb159..5b8d91426c38c 100644 --- a/src/js/media/views/attachments.js +++ b/src/js/media/views/attachments.js @@ -365,7 +365,7 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ * * @since 3.5.0 * - * @param {wp.media.model.Attachment} attachment + * @param {wp.media.model.Attachment} attachment The attachment model for which to create a view. * * @return {wp.media.View} The created view. */ diff --git a/src/js/media/views/button.js b/src/js/media/views/button.js index a4fe1d7b7b2b2..0c8316340c2bb 100644 --- a/src/js/media/views/button.js +++ b/src/js/media/views/button.js @@ -74,7 +74,7 @@ var Button = wp.media.View.extend(/** @lends wp.media.view.Button.prototype */{ /** * Handles the click event. * - * @param {Object} event + * @param {JQuery.Event} event The jQuery event object for the click action. */ click: function( event ) { if ( '#' === this.attributes.href ) { diff --git a/src/js/media/views/embed.js b/src/js/media/views/embed.js index a842974ba6c37..286eb16f8378c 100644 --- a/src/js/media/views/embed.js +++ b/src/js/media/views/embed.js @@ -32,7 +32,7 @@ var Embed = wp.media.View.extend(/** @lends wp.media.view.Embed.prototype */{ /** * Sets the settings for the embed view. * - * @param {Object} view + * @param {Object} view The view object to be set as the settings for the embed view. */ settings: function( view ) { if ( this._settings ) { diff --git a/src/js/media/views/frame.js b/src/js/media/views/frame.js index 851557d9f3ccb..3bbf47c7f8bb1 100644 --- a/src/js/media/views/frame.js +++ b/src/js/media/views/frame.js @@ -89,9 +89,9 @@ var Frame = wp.media.View.extend(/** @lends wp.media.view.Frame.prototype */{ /** * Map activeMode collection events to the frame. * - * @param {Backbone.Model} model - * @param {Backbone.Collection} collection - * @param {Object} options + * @param {Backbone.Model} model The model that triggered the event. + * @param {Backbone.Collection} collection The collection to which the model belongs. + * @param {Object} options The options object associated with the event. */ triggerModeEvents: function( model, collection, options ) { var collectionEvent, diff --git a/src/js/media/views/frame/post.js b/src/js/media/views/frame/post.js index e106b5457ae32..632779d56e7cb 100644 --- a/src/js/media/views/frame/post.js +++ b/src/js/media/views/frame/post.js @@ -263,7 +263,7 @@ Post = Select.extend(/** @lends wp.media.view.MediaFrame.Post.prototype */{ /** * Handles the main menu for the frame. * - * @param {wp.Backbone.View} view + * @param {wp.Backbone.View} view The menu view for the main menu. */ mainMenu: function( view ) { view.set({ @@ -294,7 +294,7 @@ Post = Select.extend(/** @lends wp.media.view.MediaFrame.Post.prototype */{ /** * Handles the gallery menu for the frame. * - * @param {wp.Backbone.View} view + * @param {wp.Backbone.View} view The menu view for the gallery menu. */ galleryMenu: function( view ) { var lastState = this.lastState(), @@ -326,7 +326,7 @@ Post = Select.extend(/** @lends wp.media.view.MediaFrame.Post.prototype */{ /** * Handles the playlist menu for the frame. * - * @param {wp.Backbone.View} view The menu view. + * @param {wp.Backbone.View} view The menu view for the playlist menu. */ playlistMenu: function( view ) { var lastState = this.lastState(), diff --git a/src/js/media/views/frame/select.js b/src/js/media/views/frame/select.js index 3f3c0642eea53..f736aa33be2a2 100644 --- a/src/js/media/views/frame/select.js +++ b/src/js/media/views/frame/select.js @@ -108,7 +108,7 @@ Select = MediaFrame.extend(/** @lends wp.media.view.MediaFrame.Select.prototype /** * Render callback for the router region in the `browse` mode. * - * @param {wp.media.view.Router} routerView + * @param {wp.media.view.Router} routerView The router view for the `browse` mode. */ browseRouter: function( routerView ) { routerView.set({ @@ -126,7 +126,7 @@ Select = MediaFrame.extend(/** @lends wp.media.view.MediaFrame.Select.prototype /** * Render callback for the content region in the `browse` mode. * - * @param {wp.media.controller.Region} contentRegion + * @param {wp.media.controller.Region} contentRegion The content region for the `browse` mode. */ browseContent: function( contentRegion ) { var state = this.state(); @@ -167,8 +167,8 @@ Select = MediaFrame.extend(/** @lends wp.media.view.MediaFrame.Select.prototype /** * Toolbars * - * @param {Object} toolbar - * @param {Object} [options={}] + * @param {Object} toolbar The toolbar object for the `select` mode. + * @param {Object} [options={}] The options for creating the select toolbar view. * @this wp.media.controller.Region */ createSelectToolbar: function( toolbar, options ) { diff --git a/src/js/media/views/media-details.js b/src/js/media/views/media-details.js index 988c6a88b2fb7..02286a55617bd 100644 --- a/src/js/media/views/media-details.js +++ b/src/js/media/views/media-details.js @@ -61,7 +61,7 @@ MediaDetails = AttachmentDisplay.extend(/** @lends wp.media.view.MediaDetails.pr * * @fires wp.media.view.MediaDetails#media:setting:remove * - * @param {Event} e + * @param {JQuery.Event} e The jQuery event object. */ removeSetting : function(e) { var wrap = $( e.currentTarget ).parent(), setting; @@ -94,7 +94,7 @@ MediaDetails = AttachmentDisplay.extend(/** @lends wp.media.view.MediaDetails.pr /** * Adds a source to the media details view. * - * @param {JQuery.Event} e The event object. + * @param {JQuery.Event} e The jQuery event object. */ addSource : function( e ) { this.controller.lastMime = $( e.currentTarget ).data( 'mime' ); @@ -184,7 +184,7 @@ MediaDetails = AttachmentDisplay.extend(/** @lends wp.media.view.MediaDetails.pr /** * When multiple players in the DOM contain the same src, things get weird. * - * @param {HTMLElement} elem + * @param {HTMLElement} elem The HTML element containing the media sources to be prepared. * @return {HTMLElement} The prepared element. */ prepareSrc : function( elem ) { diff --git a/src/js/media/views/media-frame.js b/src/js/media/views/media-frame.js index 2eb567051c885..99dfc675729da 100644 --- a/src/js/media/views/media-frame.js +++ b/src/js/media/views/media-frame.js @@ -160,7 +160,7 @@ MediaFrame = Frame.extend(/** @lends wp.media.view.MediaFrame.prototype */{ /** * Creates the title view. * - * @param {Object} title + * @param {Object} title The title object for creating the title view. * @this wp.media.controller.Region */ createTitle: function( title ) { @@ -172,7 +172,7 @@ MediaFrame = Frame.extend(/** @lends wp.media.view.MediaFrame.prototype */{ /** * Creates the menu view. * - * @param {Object} menu + * @param {Object} menu The menu object for creating the menu view. * @this wp.media.controller.Region */ createMenu: function( menu ) { @@ -203,7 +203,7 @@ MediaFrame = Frame.extend(/** @lends wp.media.view.MediaFrame.prototype */{ /** * Creates the toolbar view. * - * @param {Object} toolbar + * @param {Object} toolbar The toolbar object for creating the toolbar view. * @this wp.media.controller.Region */ createToolbar: function( toolbar ) { @@ -214,7 +214,7 @@ MediaFrame = Frame.extend(/** @lends wp.media.view.MediaFrame.prototype */{ /** * Creates the router view. * - * @param {Object} router + * @param {Object} router The router object for creating the router view. * @this wp.media.controller.Region */ createRouter: function( router ) { @@ -232,7 +232,7 @@ MediaFrame = Frame.extend(/** @lends wp.media.view.MediaFrame.prototype */{ /** * Creates the iframe states. * - * @param {Object} options + * @param {Object} options The options for creating the iframe states. */ createIframeStates: function( options ) { var settings = wp.media.view.settings, @@ -271,7 +271,7 @@ MediaFrame = Frame.extend(/** @lends wp.media.view.MediaFrame.prototype */{ /** * Creates the iframe content view. * - * @param {Object} content + * @param {Object} content The content object for creating the iframe content view. * @this wp.media.controller.Region */ iframeContent: function( content ) { diff --git a/src/js/media/views/menu.js b/src/js/media/views/menu.js index e970b2dc436e3..e0e2324402636 100644 --- a/src/js/media/views/menu.js +++ b/src/js/media/views/menu.js @@ -51,8 +51,8 @@ Menu = PriorityList.extend(/** @lends wp.media.view.Menu.prototype */{ /** * Creates a view for the given options and id. * - * @param {Object} options - * @param {string} id + * @param {Object} options The options for creating the view. + * @param {string} id The id of the view to create. * @return {wp.media.View} The view instance. */ toView: function( options, id ) { diff --git a/src/js/media/views/modal.js b/src/js/media/views/modal.js index 29150515a45cd..42f8da3c5024a 100644 --- a/src/js/media/views/modal.js +++ b/src/js/media/views/modal.js @@ -134,7 +134,8 @@ Modal = wp.media.View.extend(/** @lends wp.media.view.Modal.prototype */{ /** * Closes the modal and triggers the close event. * - * @param {Object} options + * @param {Object} [options={}] The options for closing the modal. + * @param {boolean} [options.escape] Whether the modal is being closed due to the escape key. * @return {wp.media.view.Modal} Returns itself to allow chaining. */ close: function( options ) { @@ -187,7 +188,7 @@ Modal = wp.media.View.extend(/** @lends wp.media.view.Modal.prototype */{ /** * Handles the escape key press event to close the modal. * - * @param {Object} event + * @param {JQuery.Event} event The jQuery event object. */ escapeHandler: function( event ) { event.preventDefault(); @@ -199,7 +200,7 @@ Modal = wp.media.View.extend(/** @lends wp.media.view.Modal.prototype */{ * * @since 6.7 * - * @param {Object} event The keydown event object. + * @param {JQuery.Event} event The jQuery event object. */ selectHandler: function( event ) { var selection = this.controller.state().get( 'selection' ); @@ -232,7 +233,7 @@ Modal = wp.media.View.extend(/** @lends wp.media.view.Modal.prototype */{ * Triggers a modal event and if the `propagate` option is set, * forwards events to the modal's controller. * - * @param {string} id + * @param {string} id The ID of the event to propagate. * @return {wp.media.view.Modal} Returns itself to allow chaining. */ propagate: function( id ) { @@ -247,7 +248,7 @@ Modal = wp.media.View.extend(/** @lends wp.media.view.Modal.prototype */{ /** * Handles keydown events within the modal. * - * @param {Object} event + * @param {JQuery.Event} event The jQuery keydown event object. */ keydown: function( event ) { // Close the modal when escape is pressed. diff --git a/src/js/media/views/priority-list.js b/src/js/media/views/priority-list.js index 28a83f753d78b..f0ed9dbeab84e 100644 --- a/src/js/media/views/priority-list.js +++ b/src/js/media/views/priority-list.js @@ -24,9 +24,9 @@ var PriorityList = wp.media.View.extend(/** @lends wp.media.view.PriorityList.pr /** * Adds a view to the list, sorted by its priority. * - * @param {string} id - * @param {wp.media.View|Object} view - * @param {Object} options + * @param {string} id The ID of the view to set. + * @param {wp.media.View|Object} view The view to set. + * @param {Object} options The options for setting the view. * @return {wp.media.view.PriorityList} Returns itself to allow chaining. */ set: function( id, view, options ) { @@ -69,7 +69,7 @@ var PriorityList = wp.media.View.extend(/** @lends wp.media.view.PriorityList.pr /** * Retrieves a view by its ID. * - * @param {string} id + * @param {string} id The ID of the view to retrieve. * @return {wp.media.View} Returns the view if found, otherwise undefined. */ get: function( id ) { @@ -78,7 +78,7 @@ var PriorityList = wp.media.View.extend(/** @lends wp.media.view.PriorityList.pr /** * Removes a view by its ID. * - * @param {string} id + * @param {string} id The ID of the view to remove. * @return {wp.media.view.PriorityList} Returns itself to allow chaining. */ unset: function( id ) { @@ -94,7 +94,7 @@ var PriorityList = wp.media.View.extend(/** @lends wp.media.view.PriorityList.pr /** * Creates a view from an object of options. * - * @param {Object} options + * @param {Object} options The options for creating the view. * @return {wp.media.View} Returns the created view. */ toView: function( options ) { diff --git a/src/js/media/views/settings.js b/src/js/media/views/settings.js index 0bbe7da8b21fd..c737a3b52e0bb 100644 --- a/src/js/media/views/settings.js +++ b/src/js/media/views/settings.js @@ -52,7 +52,7 @@ Settings = View.extend(/** @lends wp.media.view.Settings.prototype */{ /** * Updates the selected value for a setting. * - * @param {string} key + * @param {string} key The key of the setting to update. */ update: function( key ) { var value = this.model.get( key ), @@ -101,7 +101,7 @@ Settings = View.extend(/** @lends wp.media.view.Settings.prototype */{ /** * Updates the model when a setting is changed. * - * @param {Object} event + * @param {JQuery.Event} event The jQuery event object associated with the setting change. */ updateHandler: function( event ) { var $setting = $( event.target ).closest('[data-setting]'), diff --git a/src/js/media/views/toolbar.js b/src/js/media/views/toolbar.js index 99b88bfaa1d65..68d58d93faffc 100644 --- a/src/js/media/views/toolbar.js +++ b/src/js/media/views/toolbar.js @@ -83,9 +83,9 @@ Toolbar = View.extend(/** @lends wp.media.view.Toolbar.prototype */{ /** * Sets a view by its ID. * - * @param {string} id - * @param {Backbone.View|Object} view - * @param {Object} [options={}] + * @param {string} id The ID of the view to set. + * @param {Backbone.View|Object} view The view to set. + * @param {Object} [options={}] The options for setting the view. * @return {wp.media.view.Toolbar} Returns itself to allow chaining. */ set: function( id, view, options ) { @@ -121,7 +121,7 @@ Toolbar = View.extend(/** @lends wp.media.view.Toolbar.prototype */{ /** * Retrieves a view by its ID. * - * @param {string} id + * @param {string} id The ID of the view to retrieve. * @return {wp.media.view.Button} The view associated with the given ID, or undefined if no view is found. */ get: function( id ) { @@ -130,8 +130,8 @@ Toolbar = View.extend(/** @lends wp.media.view.Toolbar.prototype */{ /** * Unsets a view by its ID. * - * @param {string} id - * @param {Object} options + * @param {string} id The ID of the view to unset. + * @param {Object} [options={}] The options for unsetting the view. * @return {wp.media.view.Toolbar} Returns itself to allow chaining. */ unset: function( id, options ) { diff --git a/src/js/media/views/uploader/status.js b/src/js/media/views/uploader/status.js index 370f4df223ece..390b17f9155ec 100644 --- a/src/js/media/views/uploader/status.js +++ b/src/js/media/views/uploader/status.js @@ -107,7 +107,7 @@ UploaderStatus = View.extend(/** @lends wp.media.view.UploaderStatus.prototype * /** * Escapes the filename to prevent XSS attacks. * - * @param {string} filename + * @param {string} filename The name of the file to be escaped. * @return {string} Escaped filename. */ filename: function( filename ) { @@ -116,7 +116,7 @@ UploaderStatus = View.extend(/** @lends wp.media.view.UploaderStatus.prototype * /** * Handles an error event from the uploader queue. * - * @param {Backbone.Model} error + * @param {Backbone.Model} error The error model from the uploader queue. * @return {void} */ error: function( error ) { From 5b1696e12c15d8354061f079ad6cca4273a895f6 Mon Sep 17 00:00:00 2001 From: Aki Hamano Date: Fri, 11 Sep 2026 07:56:45 +0000 Subject: [PATCH 482/634] Docs: Add missing blank line after `@since` in block parser The PHP inline documentation standards require a blank line between the `@since` tag and the following `@param`/`@return` tags. Developed in: https://github.com/WordPress/wordpress-develop/pull/13482 Props mukesh27, wildworks. See #65818. git-svn-id: https://develop.svn.wordpress.org/trunk@63599 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/class-wp-block-parser.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/wp-includes/class-wp-block-parser.php b/src/wp-includes/class-wp-block-parser.php index 81cb7a8fa21f7..c7e087ece8711 100644 --- a/src/wp-includes/class-wp-block-parser.php +++ b/src/wp-includes/class-wp-block-parser.php @@ -85,6 +85,7 @@ public function parse( $document ) { * * @internal * @since 5.0.0 + * * @return bool */ public function proceed() { @@ -231,6 +232,7 @@ public function proceed() { * @internal * @since 5.0.0 * @since 4.6.1 fixed a bug in attribute parsing which caused catastrophic backtracking on invalid block comments + * * @return array */ public function next_token() { @@ -318,6 +320,7 @@ public function freeform( $inner_html ) { * * @internal * @since 5.0.0 + * * @param null|int $length How many bytes of document text to output. */ public function add_freeform( $length = null ) { @@ -336,6 +339,7 @@ public function add_freeform( $length = null ) { * * @internal * @since 5.0.0 + * * @param WP_Block_Parser_Block $block The block to add to the output. * @param int $token_start Byte offset into the document where the first token for the block starts. * @param int $token_length Byte length of entire block from start of opening token to end of closing token. @@ -360,6 +364,7 @@ public function add_inner_block( WP_Block_Parser_Block $block, $token_start, $to * * @internal * @since 5.0.0 + * * @param int|null $end_offset byte offset into document for where we should stop sending text output as HTML. */ public function add_block_from_stack( $end_offset = null ) { From 27e5189217d8a28c4bbf05e0827b3a17319aa951 Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Fri, 11 Sep 2026 10:50:50 +0000 Subject: [PATCH 483/634] General: Fix indentation and alignments in JavaScript inline documentation blocks. Enables the following JSDoc rules: - `jsdoc/check-alignment` - `jsdoc/check-indentation` - `jsdoc/check-line-alignment` - `jsdoc/require-hyphen-before-param-description` -> never Fixes all the reported violations. Also removes hyphens before descriptions. Part of the effort to improve JS inline documentation for 7.2. Developed in https://github.com/WordPress/wordpress-develop/pull/13490 Props afercia, mukesh27. See #66033. git-svn-id: https://develop.svn.wordpress.org/trunk@63600 602fd350-edb4-49c9-b593-d223f7449a82 --- .eslintrc-jsdoc.js | 16 ++ .../_enqueues/admin/application-passwords.js | 4 +- src/js/_enqueues/admin/common.js | 21 ++- src/js/_enqueues/admin/custom-background.js | 2 +- src/js/_enqueues/admin/edit-comments.js | 26 +-- src/js/_enqueues/admin/inline-edit-post.js | 8 +- src/js/_enqueues/admin/inline-edit-tax.js | 13 +- src/js/_enqueues/admin/media.js | 2 +- src/js/_enqueues/admin/postbox.js | 4 +- src/js/_enqueues/admin/tags-box.js | 14 +- src/js/_enqueues/admin/widgets.js | 2 +- src/js/_enqueues/lib/accordion.js | 3 + src/js/_enqueues/lib/admin-bar.js | 12 +- src/js/_enqueues/lib/auth-check.js | 5 +- .../_enqueues/lib/codemirror/htmlhint-kses.js | 6 +- .../lib/codemirror/javascript-lint.js | 22 +-- src/js/_enqueues/lib/color-picker.js | 8 +- src/js/_enqueues/lib/cookies.js | 12 +- src/js/_enqueues/lib/emoji-loader.js | 22 +-- src/js/_enqueues/lib/image-edit.js | 32 ++-- src/js/_enqueues/lib/lists.js | 2 +- src/js/_enqueues/lib/pointer.js | 2 +- src/js/_enqueues/lib/quicktags.js | 8 +- src/js/_enqueues/lib/user-suggest.js | 8 +- src/js/_enqueues/wp/api.js | 11 +- src/js/_enqueues/wp/backbone.js | 6 +- src/js/_enqueues/wp/code-editor.js | 160 +++++++++--------- src/js/_enqueues/wp/custom-header.js | 2 +- src/js/_enqueues/wp/customize/base.js | 2 +- src/js/_enqueues/wp/customize/controls.js | 2 +- src/js/_enqueues/wp/customize/loader.js | 2 +- src/js/_enqueues/wp/dashboard.js | 8 +- src/js/_enqueues/wp/editor/base.js | 41 +++-- src/js/_enqueues/wp/editor/dfw.js | 10 +- src/js/_enqueues/wp/embed.js | 2 +- src/js/_enqueues/wp/emoji.js | 4 +- src/js/_enqueues/wp/heartbeat.js | 9 +- src/js/_enqueues/wp/media/audiovideo.js | 4 +- src/js/_enqueues/wp/media/editor.js | 38 ++--- .../_enqueues/wp/password-strength-meter.js | 6 +- src/js/_enqueues/wp/sanitize.js | 4 +- src/js/_enqueues/wp/theme-plugin-editor.js | 48 +++--- src/js/_enqueues/wp/theme.js | 4 +- src/js/_enqueues/wp/updates.js | 8 +- src/js/_enqueues/wp/utils/word-count.js | 4 +- src/js/_enqueues/wp/widgets/custom-html.js | 22 +-- src/js/_enqueues/wp/widgets/media-audio.js | 2 +- src/js/_enqueues/wp/widgets/media-gallery.js | 10 +- src/js/_enqueues/wp/widgets/media-image.js | 2 +- src/js/_enqueues/wp/widgets/media-video.js | 2 +- src/js/_enqueues/wp/widgets/media.js | 46 ++--- src/js/_enqueues/wp/widgets/text.js | 14 +- src/js/media/controllers/state.js | 12 +- src/js/media/models/attachment.js | 2 +- src/js/media/models/attachments.js | 4 +- src/js/media/models/post-media.js | 2 +- src/js/media/models/query.js | 2 +- src/js/media/views/attachments/browser.js | 4 +- src/js/media/views/focus-manager.js | 16 +- tools/gutenberg/copy.js | 36 ++-- 60 files changed, 421 insertions(+), 384 deletions(-) diff --git a/.eslintrc-jsdoc.js b/.eslintrc-jsdoc.js index dc6559c520cbe..93c13a857b7b3 100644 --- a/.eslintrc-jsdoc.js +++ b/.eslintrc-jsdoc.js @@ -36,6 +36,21 @@ module.exports = [ }, }, rules: { + 'jsdoc/check-alignment': 'error', + 'jsdoc/check-indentation': [ 'error', { + excludeTags: [ + 'deprecated', + 'example', + 'param', + 'property', + 'return', + 'since', + 'todo', + ], + } ], + 'jsdoc/check-line-alignment': [ 'error', 'always', { + tags: [ 'param', 'property' ], + } ], 'jsdoc/check-param-names': 'error', 'jsdoc/check-syntax': 'error', 'jsdoc/check-tag-names': [ 'error', { @@ -48,6 +63,7 @@ module.exports = [ } ], 'jsdoc/check-types': 'error', 'jsdoc/require-description': 'error', + 'jsdoc/require-hyphen-before-param-description': [ 'error', 'never' ], 'jsdoc/require-jsdoc': 'error', 'jsdoc/require-param': [ 'error', { enableFixer: false, diff --git a/src/js/_enqueues/admin/application-passwords.js b/src/js/_enqueues/admin/application-passwords.js index ab3d2fc4de35a..21fbeb65820af 100644 --- a/src/js/_enqueues/admin/application-passwords.js +++ b/src/js/_enqueues/admin/application-passwords.js @@ -172,8 +172,8 @@ * * @since 5.6.0 * - * @param {jqXHR} xhr The XHR object from the ajax call. - * @param {string} textStatus The string categorizing the ajax request's status. + * @param {jqXHR} xhr The XHR object from the ajax call. + * @param {string} textStatus The string categorizing the ajax request's status. * @param {string} errorThrown The HTTP status error text. */ function handleErrorResponse( xhr, textStatus, errorThrown ) { diff --git a/src/js/_enqueues/admin/common.js b/src/js/_enqueues/admin/common.js index 735a9aeeaabef..fe83cc7e9f2ae 100644 --- a/src/js/_enqueues/admin/common.js +++ b/src/js/_enqueues/admin/common.js @@ -2,15 +2,14 @@ * @output wp-admin/js/common.js */ -/* global setUserSetting, ajaxurl, alert, confirm, pagenow */ -/* global columns, screenMeta */ +/* global setUserSetting, ajaxurl, alert, confirm, pagenow, columns, screenMeta */ /** - * Adds common WordPress functionality to the window. + * Adds common WordPress functionality to the window. * - * @param {JQueryStatic} $ The jQuery object. - * @param {Object} window The window object. - * @param {*} undefined Unused. + * @param {JQueryStatic} $ The jQuery object. + * @param {Object} window The window object. + * @param {*} undefined Unused. */ ( function( $, window, undefined ) { var $document = $( document ), @@ -568,8 +567,8 @@ window.showNotice = { * @since 3.2.0 * * @type {{element: null, toggles: null, page: null, init: screenMeta.init, - * toggleEvent: screenMeta.toggleEvent, open: screenMeta.open, - * close: screenMeta.close}} + * toggleEvent: screenMeta.toggleEvent, open: screenMeta.open, + * close: screenMeta.close}} * * @return {void} */ @@ -980,8 +979,8 @@ $( function() { /* * Show the sub instead of following the link if: - * - the submenu is not open. - * - the submenu is not shown inline or the menu is not folded. + * - the submenu is not open. + * - the submenu is not shown inline or the menu is not folded. */ if ( ! $menuItem.hasClass( 'opensub' ) && ( ! $menuItem.hasClass( 'wp-menu-open' ) || $menuItem.width() < 40 ) ) { event.preventDefault(); @@ -1485,7 +1484,7 @@ $( function() { * @param {Event} e The event object. * * @return {void} - */ + */ $('#contextual-help-link, #show-settings-link').on( 'focus.scroll-into-view', function(e){ if ( e.target.scrollIntoViewIfNeeded ) e.target.scrollIntoViewIfNeeded(false); diff --git a/src/js/_enqueues/admin/custom-background.js b/src/js/_enqueues/admin/custom-background.js index d8ef84e618bc1..b10a72296d2c6 100644 --- a/src/js/_enqueues/admin/custom-background.js +++ b/src/js/_enqueues/admin/custom-background.js @@ -124,7 +124,7 @@ * @since 3.5.0 * * @return {void} - */ + */ frame.on( 'select', function() { // Grab the selected attachment. var attachment = frame.state().get('selection').first(); diff --git a/src/js/_enqueues/admin/edit-comments.js b/src/js/_enqueues/admin/edit-comments.js index b6763c386149e..7e89f1c0dd7cb 100644 --- a/src/js/_enqueues/admin/edit-comments.js +++ b/src/js/_enqueues/admin/edit-comments.js @@ -42,7 +42,7 @@ var getCount, updateCount, updateCountText, updatePending, updateApproved, * @access private * * @param {jQuery} el The jQuery element to update. - * @param {number} n Number to be put in the element. + * @param {number} n Number to be put in the element. * * @return {void} */ @@ -68,7 +68,7 @@ var getCount, updateCount, updateCountText, updatePending, updateApproved, * @since 4.4.0 * @access private * - * @param {number} diff The amount to lower or raise the approved count with. + * @param {number} diff The amount to lower or raise the approved count with. * @param {number} commentPostId The ID of the post to be updated. * * @return {void} @@ -122,7 +122,7 @@ var getCount, updateCount, updateCountText, updatePending, updateApproved, * * @param {string} selector The jQuery selector for elements to update a count * for. - * @param {number} diff The amount to lower or raise the count with. + * @param {number} diff The amount to lower or raise the count with. * * @return {void} */ @@ -231,7 +231,7 @@ var getCount, updateCount, updateCountText, updatePending, updateApproved, * @since 3.2.0 * @access private * - * @param {number} diff The amount to lower or raise the pending count with. + * @param {number} diff The amount to lower or raise the pending count with. * @param {number} commentPostId The ID of the post to be updated. * * @return {void} @@ -322,9 +322,9 @@ window.setCommentsList = function() { * @since 2.8.0 * @access private * - * @param {number} total Total number of comments. - * @param {number} time Unix timestamp of response. - * @param {boolean} setConfidentTime Whether to update the last confident time + * @param {number} total Total number of comments. + * @param {number} time Unix timestamp of response. + * @param {boolean} setConfidentTime Whether to update the last confident time * with the given time. * * @return {void} @@ -345,7 +345,7 @@ window.setCommentsList = function() { * @since 2.5.0 * @access private * - * @param {Object} r Ajax response object. + * @param {Object} r Ajax response object. * @param {Object} settings Settings for the wpList object. * * @return {void} @@ -398,8 +398,8 @@ window.setCommentsList = function() { * @since 2.8.0 * @access private * - * @param {Object} settings Settings for the wpList object. - * @param {HTMLElement} list Comments table element. + * @param {Object} settings Settings for the wpList object. + * @param {HTMLElement} list Comments table element. * * @return {Object} The settings object. */ @@ -471,7 +471,7 @@ window.setCommentsList = function() { * @since 2.5.0 * @access private * - * @param {Object} r Ajax response object. + * @param {Object} r Ajax response object. * @param {Object} settings Settings for the wpList object. * * @return {void} @@ -945,8 +945,8 @@ window.commentReply = { * @memberof commentReply * * @param {number} comment_id The comment ID to open an editor for. - * @param {number} post_id The post ID to open an editor for. - * @param {string} action The action to perform. Either 'edit' or 'replyto'. + * @param {number} post_id The post ID to open an editor for. + * @param {string} action The action to perform. Either 'edit' or 'replyto'. * * @return {boolean} Always false. */ diff --git a/src/js/_enqueues/admin/inline-edit-post.js b/src/js/_enqueues/admin/inline-edit-post.js index 7f469137fc1bd..aaf4bcc5bc3ec 100644 --- a/src/js/_enqueues/admin/inline-edit-post.js +++ b/src/js/_enqueues/admin/inline-edit-post.js @@ -18,11 +18,11 @@ window.wp = window.wp || {}; * * @type {Object} * - * @property {string} type The type of inline editor. - * @property {string} what The prefix before the post ID. + * @property {string} type The type of inline editor. + * @property {string} what The prefix before the post ID. * - * @param {JQueryStatic} $ The jQuery object. - * @param {wp} wp The WordPress global object. + * @param {JQueryStatic} $ The jQuery object. + * @param {wp} wp The WordPress global object. * */ ( function( $, wp ) { diff --git a/src/js/_enqueues/admin/inline-edit-tax.js b/src/js/_enqueues/admin/inline-edit-tax.js index 620533455f6be..cedbefa256d93 100644 --- a/src/js/_enqueues/admin/inline-edit-tax.js +++ b/src/js/_enqueues/admin/inline-edit-tax.js @@ -13,12 +13,11 @@ window.wp = window.wp || {}; * * @namespace inlineEditTax * - * @property {string} type The type of inline edit we are currently on. - * @property {string} what The type property with a hash prefixed and a dash - * suffixed. + * @property {string} type The type of inline edit we are currently on. + * @property {string} what The type property with a hash prefixed and a dash suffixed. * - * @param {JQueryStatic} $ The jQuery object. - * @param {Object} wp The WordPress object. + * @param {JQueryStatic} $ The jQuery object. + * @param {Object} wp The WordPress object. */ ( function( $, wp ) { @@ -117,7 +116,7 @@ window.inlineEditTax = { * * @param {string|HTMLElement} id The ID of the term we want to quick edit or an * element within the table row or the - * table row itself. + * table row itself. * @return {boolean} Always returns false. */ edit : function(id) { @@ -164,7 +163,7 @@ window.inlineEditTax = { * * @param {string|HTMLElement} id The ID of the term we want to quick edit or an * element within the table row or the - * table row itself. + * table row itself. * @return {boolean} Always returns false. */ save : function(id) { diff --git a/src/js/_enqueues/admin/media.js b/src/js/_enqueues/admin/media.js index db61220b50e5f..f464fe960b03f 100644 --- a/src/js/_enqueues/admin/media.js +++ b/src/js/_enqueues/admin/media.js @@ -24,7 +24,7 @@ * @memberOf findPosts * * @param {string} af_name The name of the affected element. - * @param {string} af_val The value of the affected post element. + * @param {string} af_val The value of the affected post element. * * @return {boolean} Always returns false. */ diff --git a/src/js/_enqueues/admin/postbox.js b/src/js/_enqueues/admin/postbox.js index 1f101d3fd1c41..fd227b798eafb 100644 --- a/src/js/_enqueues/admin/postbox.js +++ b/src/js/_enqueues/admin/postbox.js @@ -353,8 +353,8 @@ * * @memberof postboxes * - * @param {string} page The page we are currently on. - * @param {Object} [args={}] The arguments for the postbox initializer. + * @param {string} page The page we are currently on. + * @param {Object} [args={}] The arguments for the postbox initializer. * @param {Function} args.pbshow A callback that is called when a postbox opens. * @param {Function} args.pbhide A callback that is called when a postbox * closes. diff --git a/src/js/_enqueues/admin/tags-box.js b/src/js/_enqueues/admin/tags-box.js index 99d664691c9c8..a3e1e901be22c 100644 --- a/src/js/_enqueues/admin/tags-box.js +++ b/src/js/_enqueues/admin/tags-box.js @@ -219,11 +219,11 @@ * * @memberOf tagBox * - * @param {Object} el The container HTML element. - * @param {Object|boolean} a When this is an HTML element the text of that - * element will be used for the new tag. - * @param {number|boolean} f If this value is not passed then the tag input - * field is focused. + * @param {Object} el The container HTML element. + * @param {Object|boolean} a When this is an HTML element the text of that + * element will be used for the new tag. + * @param {number|boolean} f If this value is not passed then the tag input + * field is focused. * * @return {boolean} Always returns false. */ @@ -287,8 +287,8 @@ * * @since 2.9.0 * - * @param {number|string} r The response message from the Ajax call. - * @param {string} stat The status of the Ajax request. + * @param {number|string} r The response message from the Ajax call. + * @param {string} stat The status of the Ajax request. * * @return {void} */ diff --git a/src/js/_enqueues/admin/widgets.js b/src/js/_enqueues/admin/widgets.js index cbd8f8dd4a222..f63f0182853ef 100644 --- a/src/js/_enqueues/admin/widgets.js +++ b/src/js/_enqueues/admin/widgets.js @@ -752,7 +752,7 @@ $( function(){ wpWidgets.init(); } ); * @deprecated 5.5.0 * * @type {Object} -*/ + */ wpWidgets.l10n = wpWidgets.l10n || { save: '', saved: '', diff --git a/src/js/_enqueues/lib/accordion.js b/src/js/_enqueues/lib/accordion.js index 867b6d7ac0a04..1310033f4c1ff 100644 --- a/src/js/_enqueues/lib/accordion.js +++ b/src/js/_enqueues/lib/accordion.js @@ -5,6 +5,8 @@ * with one section opening at a time when its title is clicked. * Use the following markup structure for accordion behavior: * + * @example + * ```html *
*
*

@@ -22,6 +24,7 @@ *
*
*

+ * ``` * * Note that any appropriate tags may be used, as long as the above classes are present. * diff --git a/src/js/_enqueues/lib/admin-bar.js b/src/js/_enqueues/lib/admin-bar.js index 3d6f4e3c8b94d..4430ccc7ecb77 100644 --- a/src/js/_enqueues/lib/admin-bar.js +++ b/src/js/_enqueues/lib/admin-bar.js @@ -174,7 +174,7 @@ * @since 5.3.1 * * @param {NodeList} topMenuItems All menu items. - * @param {Event} event The click event. + * @param {Event} event The click event. */ function mobileHover( topMenuItems, event ) { var wrapper; @@ -260,7 +260,7 @@ * * @since 5.3.1 * - * @param {HTMLElement} element The HTML element. + * @param {HTMLElement} element The HTML element. * @param {string} className The class name. * @return {boolean} Whether the element has the className. */ @@ -286,7 +286,7 @@ * * @since 5.3.1 * - * @param {HTMLElement} element The HTML element. + * @param {HTMLElement} element The HTML element. * @param {string} className The class name. */ function addClass( element, className ) { @@ -315,7 +315,7 @@ * * @since 5.3.1 * - * @param {HTMLElement} element The HTML element. + * @param {HTMLElement} element The HTML element. * @param {string} className The class name. */ function removeClass( element, className ) { @@ -395,8 +395,8 @@ * * @since 5.3.1 * - * @param {HTMLElement} el Element to get parent. - * @param {string} selector CSS selector to match. + * @param {HTMLElement} el Element to get parent. + * @param {string} selector CSS selector to match. * * @return {HTMLElement|null} The closest matching element or null if not found. */ diff --git a/src/js/_enqueues/lib/auth-check.js b/src/js/_enqueues/lib/auth-check.js index 1617da0cb25bd..f05d6643bf776 100644 --- a/src/js/_enqueues/lib/auth-check.js +++ b/src/js/_enqueues/lib/auth-check.js @@ -137,14 +137,13 @@ * Binds to the Heartbeat Tick event. * * - Shows the authentication form popup if user is not logged in. - * - Hides the authentication form popup if it is already visible and user is - * logged in. + * - Hides the authentication form popup if it is already visible and user is logged in. * * @ignore * * @since 3.6.0 * - * @param {Object} e The heartbeat-tick event that has been triggered. + * @param {Object} e The heartbeat-tick event that has been triggered. * @param {Object} data Response data. */ $( function() { diff --git a/src/js/_enqueues/lib/codemirror/htmlhint-kses.js b/src/js/_enqueues/lib/codemirror/htmlhint-kses.js index e08c4c0f5b756..e40a8ca8f3631 100644 --- a/src/js/_enqueues/lib/codemirror/htmlhint-kses.js +++ b/src/js/_enqueues/lib/codemirror/htmlhint-kses.js @@ -8,9 +8,9 @@ HTMLHint.addRule( { * Initialize. * * @this {import('htmlhint/types').Rule} - * @param {import('htmlhint').HTMLParser} parser - Parser. - * @param {import('htmlhint').Reporter} reporter - Reporter. - * @param {Record>} options - KSES options. + * @param {import('htmlhint').HTMLParser} parser Parser. + * @param {import('htmlhint').Reporter} reporter Reporter. + * @param {Record>} options KSES options. * @return {void} */ init: function ( parser, reporter, options ) { diff --git a/src/js/_enqueues/lib/codemirror/javascript-lint.js b/src/js/_enqueues/lib/codemirror/javascript-lint.js index 74c4cbacc0c5f..15fefe832805c 100644 --- a/src/js/_enqueues/lib/codemirror/javascript-lint.js +++ b/src/js/_enqueues/lib/codemirror/javascript-lint.js @@ -12,10 +12,10 @@ import CodeMirror from 'codemirror'; * @see https://codemirror.net/5/doc/manual.html#addon_lint * * @typedef {Object} CodeMirrorLintError - * @property {string} message Error message. - * @property {'error'} severity Severity. - * @property {CodeMirror.Position} from From position. - * @property {CodeMirror.Position} to To position. + * @property {string} message Error message. + * @property {'error'} severity Severity. + * @property {CodeMirror.Position} from From position. + * @property {CodeMirror.Position} to To position. */ /** @@ -25,12 +25,12 @@ import CodeMirror from 'codemirror'; * @see https://www.npmjs.com/package/espree#options * * @typedef {Object} SupportedJSHintOptions - * @property {import('espree').Options['ecmaVersion']} [esversion] "This option is used to specify the ECMAScript version to which the code must adhere." - * @property {boolean} [es5] "This option enables syntax first defined in the ECMAScript 5.1 specification. This includes allowing reserved keywords as object properties." - * @property {boolean} [es3] "This option tells JSHint that your code needs to adhere to ECMAScript 3 specification. Use this option if you need your program to be executable in older browsers—such as Internet Explorer 6/7/8/9—and other legacy JavaScript environments." - * @property {boolean} [module] "This option informs JSHint that the input code describes an ECMAScript 6 module. All module code is interpreted as strict mode code." - * @property {'implied'} [strict] "This option requires the code to run in ECMAScript 5's strict mode." - * @property {string} [espreeModuleUrl] The URL to the espree script module. + * @property {import('espree').Options['ecmaVersion']} [esversion] "This option is used to specify the ECMAScript version to which the code must adhere." + * @property {boolean} [es5] "This option enables syntax first defined in the ECMAScript 5.1 specification. This includes allowing reserved keywords as object properties." + * @property {boolean} [es3] "This option tells JSHint that your code needs to adhere to ECMAScript 3 specification. Use this option if you need your program to be executable in older browsers—such as Internet Explorer 6/7/8/9—and other legacy JavaScript environments." + * @property {boolean} [module] "This option informs JSHint that the input code describes an ECMAScript 6 module. All module code is interpreted as strict mode code." + * @property {'implied'} [strict] "This option requires the code to run in ECMAScript 5's strict mode." + * @property {string} [espreeModuleUrl] The URL to the espree script module. */ /** @@ -38,7 +38,7 @@ import CodeMirror from 'codemirror'; * * @since 7.0.0 * - * @param {string} text Source. + * @param {string} text Source. * @param {SupportedJSHintOptions} options Linting options. * @return {Promise} Linting errors. */ diff --git a/src/js/_enqueues/lib/color-picker.js b/src/js/_enqueues/lib/color-picker.js index bcf3d0eb842a4..d8258c53de22c 100644 --- a/src/js/_enqueues/lib/color-picker.js +++ b/src/js/_enqueues/lib/color-picker.js @@ -69,8 +69,8 @@ * * @ignore * - * @param {Event} event The event that's being called. - * @param {HTMLElement} ui The HTMLElement containing the color picker. + * @param {Event} event The event that's being called. + * @param {HTMLElement} ui The HTMLElement containing the color picker. * * @return {void} */ @@ -189,8 +189,8 @@ * * @ignore * - * @param {Event} event The event that's being called. - * @param {HTMLElement} ui The HTMLElement containing the color picker. + * @param {Event} event The event that's being called. + * @param {HTMLElement} ui The HTMLElement containing the color picker. * * @return {void} */ diff --git a/src/js/_enqueues/lib/cookies.js b/src/js/_enqueues/lib/cookies.js index 30a29d496a02e..bb398fe8ce487 100644 --- a/src/js/_enqueues/lib/cookies.js +++ b/src/js/_enqueues/lib/cookies.js @@ -63,12 +63,12 @@ window.wpCookies = { * * 'values_obj' is the JS object that is stored. It is encoded as URI in wpCookies.set(). * - * @param {string} name The name of the cookie. - * @param {Object} values_obj The values to store in the cookie. - * @param {number|Date} [expires] Optional. Expiration time in seconds or a Date object. - * @param {string} [path] Optional. The path on the server in which the cookie will be available on. - * @param {string} [domain] Optional. The domain that the cookie is available to. - * @param {boolean} [secure] Optional. Whether the cookie should only be transmitted over a secure HTTPS connection. + * @param {string} name The name of the cookie. + * @param {Object} values_obj The values to store in the cookie. + * @param {number|Date} [expires] Optional. Expiration time in seconds or a Date object. + * @param {string} [path] Optional. The path on the server in which the cookie will be available on. + * @param {string} [domain] Optional. The domain that the cookie is available to. + * @param {boolean} [secure] Optional. Whether the cookie should only be transmitted over a secure HTTPS connection. */ setHash: function( name, values_obj, expires, path, domain, secure ) { var str = ''; diff --git a/src/js/_enqueues/lib/emoji-loader.js b/src/js/_enqueues/lib/emoji-loader.js index 86963a2a3af24..5bce5aa43a44e 100644 --- a/src/js/_enqueues/lib/emoji-loader.js +++ b/src/js/_enqueues/lib/emoji-loader.js @@ -57,7 +57,7 @@ function supportsWorkerOffloading() { /** * @typedef SessionSupportTests * @type {Object} - * @property {number} timestamp + * @property {number} timestamp * @property {SupportTests} supportTests */ @@ -128,8 +128,8 @@ function setSessionSupportTests( supportTests ) { * @private * * @param {CanvasRenderingContext2D} context 2D Context. - * @param {string} set1 Set of Emoji to test. - * @param {string} set2 Set of Emoji to test. + * @param {string} set1 Set of Emoji to test. + * @param {string} set2 Set of Emoji to test. * * @return {boolean} True if the two sets render the same. */ @@ -178,7 +178,7 @@ function emojiSetsRenderIdentically( context, set1, set2 ) { * @private * * @param {CanvasRenderingContext2D} context 2D Context. - * @param {string} emoji Emoji to test. + * @param {string} emoji Emoji to test. * * @return {boolean} True if the center point is empty. */ @@ -209,10 +209,10 @@ function emojiRendersEmptyCenterPoint( context, emoji ) { * * @private * - * @param {CanvasRenderingContext2D} context 2D Context. - * @param {string} type Whether to test for support of "flag" or "emoji". - * @param {Function} emojiSetsRenderIdentically Reference to emojiSetsRenderIdentically function, needed due to minification. - * @param {Function} emojiRendersEmptyCenterPoint Reference to emojiRendersEmptyCenterPoint function, needed due to minification. + * @param {CanvasRenderingContext2D} context 2D Context. + * @param {string} type Whether to test for support of "flag" or "emoji". + * @param {Function} emojiSetsRenderIdentically Reference to emojiSetsRenderIdentically function, needed due to minification. + * @param {Function} emojiRendersEmptyCenterPoint Reference to emojiRendersEmptyCenterPoint function, needed due to minification. * * @return {boolean} True if the browser can render emoji, false if it cannot. */ @@ -302,9 +302,9 @@ function browserSupportsEmoji( context, type, emojiSetsRenderIdentically, emojiR * * @private * - * @param {string[]} tests Tests. - * @param {Function} browserSupportsEmoji Reference to browserSupportsEmoji function, needed due to minification. - * @param {Function} emojiSetsRenderIdentically Reference to emojiSetsRenderIdentically function, needed due to minification. + * @param {string[]} tests Tests. + * @param {Function} browserSupportsEmoji Reference to browserSupportsEmoji function, needed due to minification. + * @param {Function} emojiSetsRenderIdentically Reference to emojiSetsRenderIdentically function, needed due to minification. * @param {Function} emojiRendersEmptyCenterPoint Reference to emojiRendersEmptyCenterPoint function, needed due to minification. * * @return {SupportTests} Support tests. diff --git a/src/js/_enqueues/lib/image-edit.js b/src/js/_enqueues/lib/image-edit.js index 0431551aeb615..3ddc6eded840e 100644 --- a/src/js/_enqueues/lib/image-edit.js +++ b/src/js/_enqueues/lib/image-edit.js @@ -307,8 +307,8 @@ * * @memberof imageEdit * - * @param {Event} event The key or click event. - * @param {HTMLElement} el The current element. + * @param {Event} event The key or click event. + * @param {HTMLElement} el The current element. * * @return {boolean} Always returns false. */ @@ -438,10 +438,10 @@ * * @memberof imageEdit * - * @param {number} postid The current post ID. - * @param {number} x Is 0 when it applies the y-axis - * and 1 when applicable for the x-axis. - * @param {jQuery} el Element. + * @param {number} postid The current post ID. + * @param {number} x Is 0 when it applies the y-axis + * and 1 when applicable for the x-axis. + * @param {jQuery} el Element. * * @return {void} */ @@ -732,8 +732,8 @@ * * @memberof imageEdit * - * @param {number} postid The post ID to get the image from the database. - * @param {string} nonce The nonce to verify the request. + * @param {number} postid The post ID to get the image from the database. + * @param {string} nonce The nonce to verify the request. * * @return {boolean|void} If the actions are successfully saved a response message is shown. * Returns false if there is no image editing history, @@ -801,9 +801,9 @@ * * @memberof imageEdit * - * @param {number} postid The post ID for the image. - * @param {string} nonce The nonce to verify the request. - * @param {Object} view The image editor view to be used for the editing. + * @param {number} postid The post ID for the image. + * @param {string} nonce The nonce to verify the request. + * @param {Object} view The image editor view to be used for the editing. * * @return {void|promise} Either returns void if the button was already activated * or returns an instance of the image editor, wrapped in a promise. @@ -1290,8 +1290,8 @@ * * @memberof imageEdit * - * @param {number} postid The post ID. - * @param {string} nonce The nonce. + * @param {number} postid The post ID. + * @param {string} nonce The nonce. * * @return {void|false} Returns false if the undo button is disabled. */ @@ -1448,9 +1448,9 @@ * * @memberof imageEdit * - * @param {number} postid The post ID. - * @param {number} n The ratio to set. - * @param {jQuery} el The element containing the values. + * @param {number} postid The post ID. + * @param {number} n The ratio to set. + * @param {jQuery} el The element containing the values. * * @return {void} */ diff --git a/src/js/_enqueues/lib/lists.js b/src/js/_enqueues/lib/lists.js index 44e71a84ed488..deb1814bf9214 100644 --- a/src/js/_enqueues/lib/lists.js +++ b/src/js/_enqueues/lib/lists.js @@ -226,7 +226,7 @@ wpList = { * data[2] - ID of the parent element of all inputs necessary for the request. * data[3] - Hex color to be used in this request. If data[0] is 'dim', dim class. * data[4] - Additional arguments in query syntax that are added to the request. Example: 'post_id=1234'. - * If data[0] is 'dim', dim add color. + * If data[0] is 'dim', dim add color. * data[5] - Only available if data[0] is 'dim', dim delete color. * data[6] - Only available if data[0] is 'dim', additional arguments in query syntax that are added to the request. * diff --git a/src/js/_enqueues/lib/pointer.js b/src/js/_enqueues/lib/pointer.js index d946d6c015121..7e63d0e009b53 100644 --- a/src/js/_enqueues/lib/pointer.js +++ b/src/js/_enqueues/lib/pointer.js @@ -74,7 +74,7 @@ * There are 4 special values that do something extra: * * - `document` will transfer the pointer to the body of the new document - * specified by the value. + * specified by the value. * - `pointerClass` will change the class of the pointer element. * - `position` will reposition the pointer. * - `content` will update the content of the pointer. diff --git a/src/js/_enqueues/lib/quicktags.js b/src/js/_enqueues/lib/quicktags.js index bdb978750e549..ffdbfaeef7349 100644 --- a/src/js/_enqueues/lib/quicktags.js +++ b/src/js/_enqueues/lib/quicktags.js @@ -333,12 +333,12 @@ window.edToolbar = function(){}; * use add_action( 'admin_print_footer_scripts', 'output_my_js', 100 ) or add_action( 'wp_footer', 'output_my_js', 100 ) * * Minimum required to add a button that calls an external function: - * QTags.addButton( 'my_id', 'my button', my_callback ); - * function my_callback() { alert('yeah!'); } + * QTags.addButton( 'my_id', 'my button', my_callback ); + * function my_callback() { alert('yeah!'); } * * Minimum required to add a button that inserts a tag: - * QTags.addButton( 'my_id', 'my button', '', '' ); - * QTags.addButton( 'my_id2', 'my button', '
' ); + * QTags.addButton( 'my_id', 'my button', '', '' ); + * QTags.addButton( 'my_id2', 'my button', '
' ); * * @param {string} id Required. Button HTML ID * @param {string} display Required. Button's value="..." diff --git a/src/js/_enqueues/lib/user-suggest.js b/src/js/_enqueues/lib/user-suggest.js index f05b7ffa8892f..fc58ac4ef0044 100644 --- a/src/js/_enqueues/lib/user-suggest.js +++ b/src/js/_enqueues/lib/user-suggest.js @@ -34,11 +34,11 @@ * * Optional data-attributes: * - data-autocomplete-type (add, search) - * The action that is going to be performed: search for existing users - * or add a new one. Default: add + * The action that is going to be performed: search for existing users + * or add a new one. Default: add * - data-autocomplete-field (user_login, user_email) - * The field that is returned as the value for the suggestion. - * Default: user_login + * The field that is returned as the value for the suggestion. + * Default: user_login * * @see wp-admin/includes/admin-actions.php:wp_ajax_autocomplete_user() */ diff --git a/src/js/_enqueues/wp/api.js b/src/js/_enqueues/wp/api.js index b15a74628a92c..c91558b20a200 100644 --- a/src/js/_enqueues/wp/api.js +++ b/src/js/_enqueues/wp/api.js @@ -206,8 +206,8 @@ /** * Extract a route part based on negative index. * - * @param {string} route The endpoint route. - * @param {number} part The number of parts from the end of the route to retrieve. Default 1. + * @param {string} route The endpoint route. + * @param {number} part The number of parts from the end of the route to retrieve. Default 1. * Example route `/a/b/c`: part 1 is `c`, part 2 is `b`, part 3 is `a`. * @param {string} [versionString] Version string, defaults to `wp.api.versionString`. * @param {boolean} [reverse] Whether to reverse the order when extracting the route part. Optional, default false. @@ -313,7 +313,7 @@ * * @param {Backbone Model} model The model to attach helpers and mixins to. * @param {string} modelClassName The classname of the constructed model. - * @param {Object} loadingObjects An object containing the models and collections we are building. + * @param {Object} loadingObjects An object containing the models and collections we are building. * @return {undefined} No return value. */ wp.api.utils.addMixinsAndHelpers = function( model, modelClassName, loadingObjects ) { @@ -858,9 +858,8 @@ initialize: function() { /** - * Types that don't support trashing require passing ?force=true to delete. - * - */ + * Types that don't support trashing require passing ?force=true to delete. + */ if ( -1 === _.indexOf( trashableTypes, this.name ) ) { this.requireForceForDelete = true; } diff --git a/src/js/_enqueues/wp/backbone.js b/src/js/_enqueues/wp/backbone.js index 4fd194f5737d5..2c8e62d23cca3 100644 --- a/src/js/_enqueues/wp/backbone.js +++ b/src/js/_enqueues/wp/backbone.js @@ -284,7 +284,7 @@ window.wp = window.wp || {}; * @since 3.5.0 * * @return {wp.Backbone.Subviews} The current Subviews instance. - */ + */ render: function() { var options = { ready: this._isReady() @@ -314,7 +314,7 @@ window.wp = window.wp || {}; * the master views' parent. * * @return {wp.Backbone.Subviews} The current Subviews instance. - */ + */ remove: function( options ) { if ( ! options || ! options.silent ) { if ( this.parent && this.parent.views ) @@ -338,7 +338,7 @@ window.wp = window.wp || {}; * @since 3.5.0 * * @param {string} $target Selector where to put the elements. - * @param {*} els HTML or elements to put into the selector's HTML. + * @param {*} els HTML or elements to put into the selector's HTML. * * @return {wp.Backbone.Subviews} The current Subviews instance. */ diff --git a/src/js/_enqueues/wp/code-editor.js b/src/js/_enqueues/wp/code-editor.js index a40a943fed4ad..18451a0a7881e 100644 --- a/src/js/_enqueues/wp/code-editor.js +++ b/src/js/_enqueues/wp/code-editor.js @@ -19,89 +19,89 @@ if ( 'undefined' === typeof window.wp.codeEditor ) { /** * @typedef {Object} CodeMirrorState - * @property {boolean} [completionActive] - Whether completion is active. - * @property {boolean} [focused] - Whether the editor is focused. + * @property {boolean} [completionActive] Whether completion is active. + * @property {boolean} [focused] Whether the editor is focused. */ /** * @typedef {import('codemirror').EditorFromTextArea & { - * options: import('codemirror').EditorConfiguration, - * performLint?: () => void, - * showHint?: (options: import('codemirror').ShowHintOptions) => void, - * state: CodeMirrorState + * options: import('codemirror').EditorConfiguration, + * performLint?: () => void, + * showHint?: (options: import('codemirror').ShowHintOptions) => void, + * state: CodeMirrorState * }} CodeMirrorEditor */ /** * @typedef {Object} LintAnnotation - * @property {string} message - Message. - * @property {'error'|'warning'} severity - Severity. - * @property {import('codemirror').Position} from - From position. - * @property {import('codemirror').Position} to - To position. + * @property {string} message Message. + * @property {'error'|'warning'} severity Severity. + * @property {import('codemirror').Position} from From position. + * @property {import('codemirror').Position} to To position. */ /** * @typedef {Object} CodeMirrorTokenState - * @property {Object} [htmlState] - HTML state. - * @property {string} [htmlState.tagName] - Tag name. - * @property {CodeMirrorTokenState} [curState] - Current state. + * @property {Object} [htmlState] HTML state. + * @property {string} [htmlState.tagName] Tag name. + * @property {CodeMirrorTokenState} [curState] Current state. */ /** * @typedef {import('codemirror').EditorConfiguration & { - * lint?: boolean | CombinedLintOptions, - * autoCloseBrackets?: boolean, - * matchBrackets?: boolean, - * continueComments?: boolean, - * styleActiveLine?: boolean + * lint?: boolean | CombinedLintOptions, + * autoCloseBrackets?: boolean, + * matchBrackets?: boolean, + * continueComments?: boolean, + * styleActiveLine?: boolean * }} CodeMirrorSettings */ /** * @typedef {Object} CSSLintRules - * @property {boolean} [errors] - Errors. - * @property {boolean} [box-model] - Box model rules. - * @property {boolean} [display-property-grouping] - Display property grouping rules. - * @property {boolean} [duplicate-properties] - Duplicate properties rules. - * @property {boolean} [known-properties] - Known properties rules. - * @property {boolean} [outline-none] - Outline none rules. + * @property {boolean} [errors] Errors. + * @property {boolean} [box-model] Box model rules. + * @property {boolean} [display-property-grouping] Display property grouping rules. + * @property {boolean} [duplicate-properties] Duplicate properties rules. + * @property {boolean} [known-properties] Known properties rules. + * @property {boolean} [outline-none] Outline none rules. */ /** * @typedef {Object} JSHintRules - * @property {number} [esversion] - ECMAScript version. - * @property {boolean} [module] - Whether to use modules. - * @property {boolean} [boss] - Whether to allow assignments in control expressions. - * @property {boolean} [curly] - Whether to require curly braces. - * @property {boolean} [eqeqeq] - Whether to require === and !==. - * @property {boolean} [eqnull] - Whether to allow == null. - * @property {boolean} [expr] - Whether to allow expressions. - * @property {boolean} [immed] - Whether to require immediate function invocation. - * @property {boolean} [noarg] - Whether to prohibit arguments.caller/callee. - * @property {boolean} [nonbsp] - Whether to prohibit non-breaking spaces. - * @property {string} [quotmark] - Quote mark preference. - * @property {boolean} [undef] - Whether to prohibit undefined variables. - * @property {boolean} [unused] - Whether to prohibit unused variables. - * @property {boolean} [browser] - Whether to enable browser globals. - * @property {Record} [globals] - Global variables. + * @property {number} [esversion] ECMAScript version. + * @property {boolean} [module] Whether to use modules. + * @property {boolean} [boss] Whether to allow assignments in control expressions. + * @property {boolean} [curly] Whether to require curly braces. + * @property {boolean} [eqeqeq] Whether to require === and !==. + * @property {boolean} [eqnull] Whether to allow == null. + * @property {boolean} [expr] Whether to allow expressions. + * @property {boolean} [immed] Whether to require immediate function invocation. + * @property {boolean} [noarg] Whether to prohibit arguments.caller/callee. + * @property {boolean} [nonbsp] Whether to prohibit non-breaking spaces. + * @property {string} [quotmark] Quote mark preference. + * @property {boolean} [undef] Whether to prohibit undefined variables. + * @property {boolean} [unused] Whether to prohibit unused variables. + * @property {boolean} [browser] Whether to enable browser globals. + * @property {Record} [globals] Global variables. */ /** * @typedef {Object} HTMLHintRules - * @property {boolean} [tagname-lowercase] - Tag name lowercase rules. - * @property {boolean} [attr-lowercase] - Attribute lowercase rules. - * @property {boolean} [attr-value-double-quotes] - Attribute value double quotes rules. - * @property {boolean} [doctype-first] - Doctype first rules. - * @property {boolean} [tag-pair] - Tag pair rules. - * @property {boolean} [spec-char-escape] - Spec char escape rules. - * @property {boolean} [id-unique] - ID unique rules. - * @property {boolean} [src-not-empty] - Src not empty rules. - * @property {boolean} [attr-no-duplication] - Attribute no duplication rules. - * @property {boolean} [alt-require] - Alt require rules. - * @property {string} [space-tab-mixed-disabled] - Space tab mixed disabled rules. - * @property {boolean} [attr-unsafe-chars] - Attribute unsafe chars rules. - * @property {JSHintRules} [jshint] - JSHint rules. - * @property {CSSLintRules} [csslint] - CSSLint rules. + * @property {boolean} [tagname-lowercase] Tag name lowercase rules. + * @property {boolean} [attr-lowercase] Attribute lowercase rules. + * @property {boolean} [attr-value-double-quotes] Attribute value double quotes rules. + * @property {boolean} [doctype-first] Doctype first rules. + * @property {boolean} [tag-pair] Tag pair rules. + * @property {boolean} [spec-char-escape] Spec char escape rules. + * @property {boolean} [id-unique] ID unique rules. + * @property {boolean} [src-not-empty] Src not empty rules. + * @property {boolean} [attr-no-duplication] Attribute no duplication rules. + * @property {boolean} [alt-require] Alt require rules. + * @property {string} [space-tab-mixed-disabled] Space tab mixed disabled rules. + * @property {boolean} [attr-unsafe-chars] Attribute unsafe chars rules. + * @property {JSHintRules} [jshint] JSHint rules. + * @property {CSSLintRules} [csslint] CSSLint rules. */ /** @@ -109,15 +109,15 @@ if ( 'undefined' === typeof window.wp.codeEditor ) { * * @typedef {Object} CodeEditorSettings * - * @property {CodeMirrorSettings} [codemirror] - CodeMirror settings. - * @property {CSSLintRules} [csslint] - CSSLint rules. - * @property {JSHintRules} [jshint] - JSHint rules. - * @property {HTMLHintRules} [htmlhint] - HTMLHint rules. + * @property {CodeMirrorSettings} [codemirror] CodeMirror settings. + * @property {CSSLintRules} [csslint] CSSLint rules. + * @property {JSHintRules} [jshint] JSHint rules. + * @property {HTMLHintRules} [htmlhint] HTMLHint rules. * - * @property {(codemirror: CodeMirrorEditor, event: KeyboardEvent|JQuery.KeyDownEvent) => void} [onTabNext] - Callback to handle tabbing to the next tabbable element. - * @property {(codemirror: CodeMirrorEditor, event: KeyboardEvent|JQuery.KeyDownEvent) => void} [onTabPrevious] - Callback to handle tabbing to the previous tabbable element. - * @property {(errorAnnotations: LintAnnotation[], annotations: LintAnnotation[], annotationsSorted: LintAnnotation[], cm: CodeMirrorEditor) => void} [onChangeLintingErrors] - Callback for when the linting errors have changed. - * @property {(errorAnnotations: LintAnnotation[], editor: CodeMirrorEditor) => void} [onUpdateErrorNotice] - Callback for when error notice should be displayed. + * @property {(codemirror: CodeMirrorEditor, event: KeyboardEvent|JQuery.KeyDownEvent) => void} [onTabNext] Callback to handle tabbing to the next tabbable element. + * @property {(codemirror: CodeMirrorEditor, event: KeyboardEvent|JQuery.KeyDownEvent) => void} [onTabPrevious] Callback to handle tabbing to the previous tabbable element. + * @property {(errorAnnotations: LintAnnotation[], annotations: LintAnnotation[], annotationsSorted: LintAnnotation[], cm: CodeMirrorEditor) => void} [onChangeLintingErrors] Callback for when the linting errors have changed. + * @property {(errorAnnotations: LintAnnotation[], editor: CodeMirrorEditor) => void} [onUpdateErrorNotice] Callback for when error notice should be displayed. */ /** @@ -126,15 +126,15 @@ if ( 'undefined' === typeof window.wp.codeEditor ) { /** * @typedef {Object} CodeEditorInstance - * @property {CodeEditorSettings} settings - The code editor settings. - * @property {CodeMirrorEditor} codemirror - The CodeMirror instance. - * @property {() => void} updateErrorNotice - Force update the error notice. + * @property {CodeEditorSettings} settings The code editor settings. + * @property {CodeMirrorEditor} codemirror The CodeMirror instance. + * @property {() => void} updateErrorNotice Force update the error notice. */ /** * @typedef {Object} WpCodeEditor - * @property {CodeEditorSettings} defaultSettings - Default settings. - * @property {(textarea: string|JQuery|Element, settings?: CodeEditorSettings) => CodeEditorInstance} initialize - Initialize. + * @property {CodeEditorSettings} defaultSettings Default settings. + * @property {(textarea: string|JQuery|Element, settings?: CodeEditorSettings) => CodeEditorInstance} initialize Initialize. */ /** @@ -166,7 +166,7 @@ if ( 'undefined' === typeof window.wp.codeEditor ) { /** * Configures linting. * - * @param {CodeEditorSettings} settings - Code editor settings. + * @param {CodeEditorSettings} settings Code editor settings. * * @return {LintingController} Linting controller. */ @@ -180,7 +180,7 @@ if ( 'undefined' === typeof window.wp.codeEditor ) { /** * Call the onUpdateErrorNotice if there are new errors to show. * - * @param {import('codemirror').Editor} editor - Editor. + * @param {import('codemirror').Editor} editor Editor. * @return {void} */ function updateErrorNotice( editor ) { @@ -237,9 +237,9 @@ if ( 'undefined' === typeof window.wp.codeEditor ) { /** * Wraps the onUpdateLinting event to filter errors, detect state changes, and manage error notice visibility. * - * @param {LintAnnotation[]} annotations - Annotations. - * @param {LintAnnotation[]} annotationsSorted - Sorted annotations. - * @param {CodeMirrorEditor} cm - Editor. + * @param {LintAnnotation[]} annotations Annotations. + * @param {LintAnnotation[]} annotationsSorted Sorted annotations. + * @param {CodeMirrorEditor} cm Editor. */ return function( annotations, annotationsSorted, cm ) { const errorAnnotations = annotations.filter( function( annotation ) { @@ -281,7 +281,7 @@ if ( 'undefined' === typeof window.wp.codeEditor ) { /** * Initializes the CodeMirror editor. * - * @param {CodeMirrorEditor} editor - Editor instance. + * @param {CodeMirrorEditor} editor Editor instance. * @return {void} */ init: function( editor ) { @@ -349,7 +349,7 @@ if ( 'undefined' === typeof window.wp.codeEditor ) { } ); }, /** - * @param {CodeMirrorEditor} editor - Editor instance. + * @param {CodeMirrorEditor} editor Editor instance. * @return {void} */ updateErrorNotice, @@ -359,8 +359,8 @@ if ( 'undefined' === typeof window.wp.codeEditor ) { /** * Configure tabbing. * - * @param {CodeMirrorEditor} codemirror - Editor. - * @param {CodeEditorSettings} settings - Code editor settings. + * @param {CodeMirrorEditor} codemirror Editor. + * @param {CodeEditorSettings} settings Code editor settings. * * @return {void} */ @@ -399,9 +399,9 @@ if ( 'undefined' === typeof window.wp.codeEditor ) { /** * @typedef {Object} LintingController - * @property {() => CombinedLintOptions|false} getLintOptions - Get lint options. - * @property {(editor: CodeMirrorEditor) => void} init - Initialize. - * @property {(editor: import('codemirror').Editor) => void} updateErrorNotice - Update error notice. + * @property {() => CombinedLintOptions|false} getLintOptions Get lint options. + * @property {(editor: CodeMirrorEditor) => void} init Initialize. + * @property {(editor: import('codemirror').Editor) => void} updateErrorNotice Update error notice. */ /** @@ -409,8 +409,8 @@ if ( 'undefined' === typeof window.wp.codeEditor ) { * * @since 4.9.0 * - * @param {string|JQuery|HTMLElement} textarea - The HTML id, jQuery object, or DOM Element for the textarea that is used for the editor. - * @param {CodeEditorSettings} [settings] - Settings to override defaults. + * @param {string|JQuery|HTMLElement} textarea The HTML id, jQuery object, or DOM Element for the textarea that is used for the editor. + * @param {CodeEditorSettings} [settings] Settings to override defaults. * * @return {CodeEditorInstance} Instance. */ diff --git a/src/js/_enqueues/wp/custom-header.js b/src/js/_enqueues/wp/custom-header.js index 7d4fa98d7cc53..fccab2565b164 100644 --- a/src/js/_enqueues/wp/custom-header.js +++ b/src/js/_enqueues/wp/custom-header.js @@ -19,7 +19,7 @@ * Trigger an event. * * @param {Element} target HTML element to dispatch the event on. - * @param {string} name Event name. + * @param {string} name Event name. */ function trigger( target, name ) { var evt; diff --git a/src/js/_enqueues/wp/customize/base.js b/src/js/_enqueues/wp/customize/base.js index 2b694b9a021c1..44e23ae35740d 100644 --- a/src/js/_enqueues/wp/customize/base.js +++ b/src/js/_enqueues/wp/customize/base.js @@ -568,7 +568,7 @@ window.wp = window.wp || {}; * when( ids*, [callback] ); * * For example: - * when( id1, id2, id3, function( value1, value2, value3 ) {} ); + * when( id1, id2, id3, function( value1, value2, value3 ) {} ); * * @param {...(string|Function)} ids Zero or more IDs of items to wait for, optionally followed by * a callback function to invoke once they are all available. diff --git a/src/js/_enqueues/wp/customize/controls.js b/src/js/_enqueues/wp/customize/controls.js index 94693163c0240..64bfd3fe754be 100644 --- a/src/js/_enqueues/wp/customize/controls.js +++ b/src/js/_enqueues/wp/customize/controls.js @@ -3101,7 +3101,7 @@ api.ThemesPanel = api.Panel.extend(/** @lends wp.customize.ThemesPanel.prototype */{ /** - * Class wp.customize.ThemesPanel. + * Class wp.customize.ThemesPanel. * * Custom section for themes that displays without the customize preview. * diff --git a/src/js/_enqueues/wp/customize/loader.js b/src/js/_enqueues/wp/customize/loader.js index 152d5d48dc780..0f053f4c69505 100644 --- a/src/js/_enqueues/wp/customize/loader.js +++ b/src/js/_enqueues/wp/customize/loader.js @@ -33,7 +33,7 @@ window.wp = window.wp || {}; * By default, any element in the body with the load-customize class will open * an iframe overlay with the URL specified. * - * e.g. Open Customizer + * e.g. Open Customizer * * @memberOf wp.customize * diff --git a/src/js/_enqueues/wp/dashboard.js b/src/js/_enqueues/wp/dashboard.js index 595133d790782..1fbfdec57a508 100644 --- a/src/js/_enqueues/wp/dashboard.js +++ b/src/js/_enqueues/wp/dashboard.js @@ -67,7 +67,7 @@ jQuery( function($) { * @type {string[]} * * @global - */ + */ window.ajaxWidgets = ['dashboard_primary']; /** @@ -85,7 +85,7 @@ jQuery( function($) { /** * Fetch the latest representation of the widget via Ajax and show it. * - * @param {number} i Number of half-seconds to use as the timeout. + * @param {number} i Number of half-seconds to use as the timeout. * @param {string} id ID of the element which is going to be checked for changes. * * @return {void} @@ -163,7 +163,7 @@ jQuery( function($) { * Highlights the latest post for one second. * * @return {void} - */ + */ function highlightLatestPost () { var latestPost = $( '.drafts ul li' ) .first(), errorNotice = $( '#quick-press .notice-error' ); @@ -835,7 +835,7 @@ jQuery( function( $ ) { * @deprecated 5.6.0 * * @type {Object} -*/ + */ window.communityEventsData.l10n = window.communityEventsData.l10n || { enter_closest_city: '', error_occurred_please_try_again: '', diff --git a/src/js/_enqueues/wp/editor/base.js b/src/js/_enqueues/wp/editor/base.js index 0c3485ca7d661..d7618acdafe3d 100644 --- a/src/js/_enqueues/wp/editor/base.js +++ b/src/js/_enqueues/wp/editor/base.js @@ -78,7 +78,7 @@ window.wp = window.wp || {}; * * @memberof switchEditors * - * @param {string} id The id of the editor you want to change the editor mode for. Default: `content`. + * @param {string} id The id of the editor you want to change the editor mode for. Default: `content`. * @param {string} mode The mode you want to switch to. Default: `toggle`. * @return {void} */ @@ -201,7 +201,7 @@ window.wp = window.wp || {}; * the tag type, if it is a closing tag and check if the HTML tag is inside a shortcode tag, * e.g. `[caption]..`. * - * @param {string} content The test content where the cursor is. + * @param {string} content The test content where the cursor is. * @param {number} cursorPosition The cursor position inside the content. * * @return {(null|Object)} Null if cursor is not in a tag, Object if the cursor is inside a tag. @@ -246,8 +246,8 @@ window.wp = window.wp || {}; * Moving the selection to before or after the short code is better, since it allows to select * something, instead of just losing focus and going to the start of the content. * - * @param {string} content The text content to check against. - * @param {number} cursorPosition The cursor position to check. + * @param {string} content The text content to check against. + * @param {number} cursorPosition The cursor position to check. * * @return {void|Object} Undefined if the cursor is not wrapped in a shortcode tag. * Information about the wrapping shortcode tag if it's wrapped in one. @@ -372,7 +372,7 @@ window.wp = window.wp || {}; * * Using DomQuery syntax to create it, since it's used as both text and as a DOM element. * - * @param {Object} domLib DOM library instance. + * @param {Object} domLib DOM library instance. * @param {string} content The content to insert into the cursor marker element. * @return {Object} The cursor marker element. */ @@ -395,7 +395,7 @@ window.wp = window.wp || {}; * * @link getShortcodeWrapperInfo * - * @param {string} content Textarea content that the cursors are in + * @param {string} content Textarea content that the cursors are in * @param {{cursorStart: number, cursorEnd: number}} cursorPositions Cursor start and end positions * * @return {{cursorStart: number, cursorEnd: number}} Adjusted cursor positions with `cursorStart` and `cursorEnd` properties. @@ -585,7 +585,7 @@ window.wp = window.wp || {}; * I order to achieve the proper positioning, the editor media bar and toolbar are subtracted * from the window height, to get the proper viewport window, that the user sees. * - * @param {Object} editor TinyMCE editor instance. + * @param {Object} editor TinyMCE editor instance. * @param {Object} element HTMLElement that should be scrolled into view. */ function scrollVisualModeToStartElement( editor, element ) { @@ -825,7 +825,7 @@ window.wp = window.wp || {}; * For `selection` parameter: * @link findBookmarkedPosition * - * @param {Object} editor TinyMCE's editor instance. + * @param {Object} editor TinyMCE's editor instance. * @param {Object} selection Selection data. */ function selectTextInTextArea( editor, selection ) { @@ -1224,9 +1224,27 @@ window.wp = window.wp || {}; * * @since 4.8.0 * - * @param {string} id The HTML id of the textarea that is used for the editor. - * Has to be jQuery compliant. No brackets, special chars, etc. - * @param {Object} settings Example: + * @param {string} id The HTML id of the textarea that is used for the editor. + * Has to be jQuery compliant. No brackets, special chars, etc. + * @param {Object} settings The settings for initializing the editor. + * + * @example + * ```javascript + * settings = { + * // See https://www.tinymce.com/docs/configure/integration-and-setup/. + * // Alternatively set to `true` to use the defaults. + * tinymce: { + * setup: function( editor ) { + * console.log( 'Editor initialized', editor ); + * } + * } + * + * // Alternatively set to `true` to use the defaults. + * quicktags: { + * buttons: 'strong,em,link' + * } + * } + * * settings = { * // See https://www.tinymce.com/docs/configure/integration-and-setup/. * // Alternatively set to `true` to use the defaults. @@ -1241,6 +1259,7 @@ window.wp = window.wp || {}; * buttons: 'strong,em,link' * } * } + * ``` */ wp.editor.initialize = function( id, settings ) { var init; diff --git a/src/js/_enqueues/wp/editor/dfw.js b/src/js/_enqueues/wp/editor/dfw.js index d6a563e8f7872..ff640ca9dd121 100644 --- a/src/js/_enqueues/wp/editor/dfw.js +++ b/src/js/_enqueues/wp/editor/dfw.js @@ -173,7 +173,7 @@ * * @since 4.0.0 * - * @param {event} event The TinyMCE editor init event. + * @param {event} event The TinyMCE editor init event. * @param {Object} editor The editor to bind the vents on. * * @return {void} @@ -1473,7 +1473,7 @@ * * @since 4.1.0 * - * @param {event} event The TinyMCE editor setup event. + * @param {event} event The TinyMCE editor setup event. * @param {Object} editor The editor to add the button to. * * @return {void} @@ -1522,7 +1522,7 @@ * * @since 4.1.0 * - * @param {event} event The TinyMCE editor init event. + * @param {event} event The TinyMCE editor init event. * @param {Object} editor The editor to bind events on. * * @return {void} @@ -1581,11 +1581,11 @@ } ); /** - * Binds events on quicktags init. + * Binds events on quicktags init. * * @since 4.1.0 * - * @param {event} event The quicktags init event. + * @param {event} event The quicktags init event. * @param {Object} editor The editor to bind events on. * * @return {void} diff --git a/src/js/_enqueues/wp/embed.js b/src/js/_enqueues/wp/embed.js index 5522fb824a38c..1f34177c3362f 100644 --- a/src/js/_enqueues/wp/embed.js +++ b/src/js/_enqueues/wp/embed.js @@ -1,7 +1,7 @@ /** * WordPress inline HTML embed * - * @param {Window} window The global window object. + * @param {Window} window The global window object. * @param {Document} document The global document object. * @since 4.4.0 * @output wp-includes/js/wp-embed.js diff --git a/src/js/_enqueues/wp/emoji.js b/src/js/_enqueues/wp/emoji.js index 1c134e2dfef85..274868f52d859 100644 --- a/src/js/_enqueues/wp/emoji.js +++ b/src/js/_enqueues/wp/emoji.js @@ -2,7 +2,7 @@ * wp-emoji.js is used to replace emoji with images in browsers when the browser * doesn't support emoji natively. * - * @param {Window} window The global window object. + * @param {Window} window The global window object. * @param {Object} settings The settings object. * @output wp-includes/js/wp-emoji.js */ @@ -190,7 +190,7 @@ * * - When passed an element the emoji characters are replaced inline. * - When passed a string the emoji characters are replaced and the result is - * returned. + * returned. * * @since 4.2.0 * diff --git a/src/js/_enqueues/wp/heartbeat.js b/src/js/_enqueues/wp/heartbeat.js index e816959bda1bf..6f89e1db47b6c 100644 --- a/src/js/_enqueues/wp/heartbeat.js +++ b/src/js/_enqueues/wp/heartbeat.js @@ -790,12 +790,17 @@ /** * Enqueues data to send with the next XHR. * - * As the data is send asynchronously, this function doesn't return the XHR + * As the data is sent asynchronously, this function doesn't return the XHR * response. To see the response, use the custom jQuery event 'heartbeat-tick' - * on the document, example: + * on the document. + * + * @example + * ```javascript * $(document).on( 'heartbeat-tick.myname', function( event, data, textStatus, jqXHR ) { * // code * }); + * ``` + * * If the same 'handle' is used more than once, the data is not overwritten when * the third argument is 'true'. Use `wp.heartbeat.isQueued('handle')` to see if * any data is already queued for that handle. diff --git a/src/js/_enqueues/wp/media/audiovideo.js b/src/js/_enqueues/wp/media/audiovideo.js index 485a1699726bf..d330831c490eb 100644 --- a/src/js/_enqueues/wp/media/audiovideo.js +++ b/src/js/_enqueues/wp/media/audiovideo.js @@ -197,8 +197,8 @@ wp.media.audio = { /** * Shortcode modeling for video. * - * `edit()` prepares the shortcode for the media modal. - * `shortcode()` builds the new shortcode after update. + * `edit()` prepares the shortcode for the media modal. + * `shortcode()` builds the new shortcode after update. * * @since 4.2.0 * diff --git a/src/js/_enqueues/wp/media/editor.js b/src/js/_enqueues/wp/media/editor.js index b6357520db557..3c0678c38e6d6 100644 --- a/src/js/_enqueues/wp/media/editor.js +++ b/src/js/_enqueues/wp/media/editor.js @@ -20,11 +20,11 @@ /** * A helper mixin function to avoid truthy and falsey values being - * passed as an input that expects booleans. If key is undefined in the map, - * but has a default value, set it. + * passed as an input that expects booleans. If key is undefined in the map, + * but has a default value, set it. * * @param {Object} attrs Map of props from a shortcode or settings. - * @param {string} key The key within the passed map to check for a value. + * @param {string} key The key within the passed map to check for a value. * @return {mixed|undefined} The original or coerced value of key within attrs. */ wp.media.coerce = function ( attrs, key ) { @@ -111,7 +111,7 @@ /** * Create link markup that is suitable for passing to the editor * - * @param {Object} props Attachment details (align, link, size, etc). + * @param {Object} props Attachment details (align, link, size, etc). * @param {Object} attachment The attachment object, media version of Post. * @return {string} The link markup */ @@ -137,7 +137,7 @@ /** * Create an Audio shortcode string that is suitable for passing to the editor * - * @param {Object} props Attachment details (align, link, size, etc). + * @param {Object} props Attachment details (align, link, size, etc). * @param {Object} attachment The attachment object, media version of Post. * @return {string} The audio shortcode */ @@ -147,7 +147,7 @@ /** * Create a Video shortcode string that is suitable for passing to the editor * - * @param {Object} props Attachment details (align, link, size, etc). + * @param {Object} props Attachment details (align, link, size, etc). * @param {Object} attachment The attachment object, media version of Post. * @return {string} The video shortcode */ @@ -159,8 +159,8 @@ * * @access private * - * @param {string} type The shortcode tag name: 'audio' or 'video'. - * @param {Object} props Attachment details (align, link, size, etc). + * @param {string} type The shortcode tag name: 'audio' or 'video'. + * @param {Object} props Attachment details (align, link, size, etc). * @param {Object} attachment The attachment object, media version of Post. * @return {string} The media shortcode */ @@ -206,9 +206,9 @@ }, /** * Create image markup, optionally with a link and/or wrapped in a caption shortcode, - * that is suitable for passing to the editor + * that is suitable for passing to the editor * - * @param {Object} props Attachment details (align, link, size, etc). + * @param {Object} props Attachment details (align, link, size, etc). * @param {Object} attachment The attachment object, media version of Post. * @return {string} The image markup. */ @@ -418,9 +418,9 @@ * Triggered when clicking 'Insert {label}' or 'Update {label}' * * @param {wp.media.model.Attachments} attachments A Backbone.Collection containing - * the media items belonging to a collection. - * The query[ this.tag ] property is a Backbone.Model - * containing the 'props' for the collection. + * the media items belonging to a collection. + * The query[ this.tag ] property is a Backbone.Model + * containing the 'props' for the collection. * @return {wp.shortcode} A wp.shortcode instance representing the collection. */ shortcode: function( attachments ) { @@ -485,10 +485,10 @@ }, /** * Triggered when double-clicking a collection shortcode placeholder - * in the editor + * in the editor * * @param {string} content Content that is searched for possible - * shortcode markup matching the passed tag name, + * shortcode markup matching the passed tag name, * * @this wp.media.{prop} * @@ -689,7 +689,7 @@ }, /** * 'select' callback for Featured Image workflow, triggered when - * the 'Set Featured Image' button is clicked in the media modal. + * the 'Set Featured Image' button is clicked in the media modal. * * @this wp.media.controller.FeaturedImage */ @@ -784,7 +784,7 @@ /** * Setup 'workflow' and add to the 'workflows' cache. 'open' can - * subsequently be called upon it. + * subsequently be called upon it. * * @param {string} id A slug used to identify the workflow. * @param {Object} [options={}] The options for the media workflow. @@ -943,9 +943,9 @@ send: { /** * Called when sending an attachment to the editor - * from the medial modal. + * from the medial modal. * - * @param {Object} props Attachment details (align, link, size, etc). + * @param {Object} props Attachment details (align, link, size, etc). * @param {Object} attachment The attachment object, media version of Post. * @return {Promise} A promise that resolves when the attachment has been sent to the editor. */ diff --git a/src/js/_enqueues/wp/password-strength-meter.js b/src/js/_enqueues/wp/password-strength-meter.js index 6aba8749adffa..3ed6d48d5ef25 100644 --- a/src/js/_enqueues/wp/password-strength-meter.js +++ b/src/js/_enqueues/wp/password-strength-meter.js @@ -26,10 +26,10 @@ window.wp = window.wp || {}; * * @since 3.7.0 * - * @param {string} password1 The subject password. + * @param {string} password1 The subject password. * @param {Array} disallowedList An array of words that will lower the entropy of - * the password. - * @param {string} password2 The password confirmation. + * the password. + * @param {string} password2 The password confirmation. * * @return {number} The password strength score. */ diff --git a/src/js/_enqueues/wp/sanitize.js b/src/js/_enqueues/wp/sanitize.js index c5c97f6c37564..f67a8fd25a97f 100644 --- a/src/js/_enqueues/wp/sanitize.js +++ b/src/js/_enqueues/wp/sanitize.js @@ -19,7 +19,7 @@ /** * Strip HTML tags. * - * @param {string} text - Text to strip the HTML tags from. + * @param {string} text Text to strip the HTML tags from. * * @return {string} Stripped text. */ @@ -52,7 +52,7 @@ /** * Strip HTML tags and convert HTML entities. * - * @param {string} text - Text to strip tags and convert HTML entities. + * @param {string} text Text to strip tags and convert HTML entities. * * @return {string} Sanitized text. */ diff --git a/src/js/_enqueues/wp/theme-plugin-editor.js b/src/js/_enqueues/wp/theme-plugin-editor.js index 74e0634f94e45..72a4471a93994 100644 --- a/src/js/_enqueues/wp/theme-plugin-editor.js +++ b/src/js/_enqueues/wp/theme-plugin-editor.js @@ -29,9 +29,9 @@ wp.themePluginEditor = (function( $ ) { * * @since 4.9.0 * - * @param {jQuery} form - Form element. - * @param {Object} settings - Settings. - * @param {Object|boolean} settings.codeEditor - Code editor settings (or `false` if syntax highlighting is disabled). + * @param {jQuery} form Form element. + * @param {Object} settings Settings. + * @param {Object|boolean} settings.codeEditor Code editor settings (or `false` if syntax highlighting is disabled). * @return {void} */ component.init = function init( form, settings ) { @@ -187,7 +187,7 @@ wp.themePluginEditor = (function( $ ) { * Submit file via Ajax. * * @since 4.9.0 - * @param {jQuery.Event} event - Event. + * @param {jQuery.Event} event Event. * @return {void} */ component.submit = function( event ) { @@ -273,12 +273,12 @@ wp.themePluginEditor = (function( $ ) { * * @since 4.9.0 * - * @param {Object} notice - Notice. - * @param {string} notice.code - Code. - * @param {string} notice.type - Type. - * @param {string} notice.message - Message. - * @param {boolean} [notice.dismissible=false] - Dismissible. - * @param {Function} [notice.onDismiss] - Callback for when a user dismisses the notice. + * @param {Object} notice Notice. + * @param {string} notice.code Code. + * @param {string} notice.type Type. + * @param {string} notice.message Message. + * @param {boolean} [notice.dismissible=false] Dismissible. + * @param {Function} [notice.onDismiss] Callback for when a user dismisses the notice. * @return {jQuery} Notice element. */ component.addNotice = function( notice ) { @@ -314,7 +314,7 @@ wp.themePluginEditor = (function( $ ) { * * @since 4.9.0 * - * @param {string} code - Notice code. + * @param {string} code Notice code. * @return {boolean} Whether a notice was removed. */ component.removeNotice = function( code ) { @@ -366,7 +366,7 @@ wp.themePluginEditor = (function( $ ) { * * @since 4.9.0 * - * @param {Array} errors - List of linting errors. + * @param {Array} errors List of linting errors. * @return {void} */ codeEditorSettings.onChangeLintingErrors = function( errors ) { @@ -383,7 +383,7 @@ wp.themePluginEditor = (function( $ ) { * * @since 4.9.0 * - * @param {Array} errorAnnotations - Error annotations. + * @param {Array} errorAnnotations Error annotations. * @return {void} */ codeEditorSettings.onUpdateErrorNotice = function onUpdateErrorNotice( errorAnnotations ) { @@ -491,26 +491,24 @@ wp.themePluginEditor = (function( $ ) { */ var TreeitemLink = (function () { /** - * This content is licensed according to the W3C Software License at - * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document + * This content is licensed according to the W3C Software License at + * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document * - * File: TreeitemLink.js + * File: TreeitemLink.js * - * Desc: Treeitem widget that implements ARIA Authoring Practices - * for a tree being used as a file viewer + * Desc: Treeitem widget that implements ARIA Authoring Practices + * for a tree being used as a file viewer * - * Author: Jon Gunderson, Ku Ja Eun and Nicholas Hoyt + * Author: Jon Gunderson, Ku Ja Eun and Nicholas Hoyt */ /** - * @class + * @class * - * @description - * Treeitem object for representing the state and user interactions for a - * treeItem widget + * Treeitem object for representing the state and user interactions for a + * treeItem widget * - * @param node - * An element with the role=tree attribute + * @param node An element with the role=tree attribute */ var TreeitemLink = function (node, treeObj, group) { diff --git a/src/js/_enqueues/wp/theme.js b/src/js/_enqueues/wp/theme.js index 2249495ea4d1b..396fd4e3c9c41 100644 --- a/src/js/_enqueues/wp/theme.js +++ b/src/js/_enqueues/wp/theme.js @@ -1485,8 +1485,8 @@ themes.view.Search = wp.Backbone.View.extend({ * * @since 4.9.0 * - * @param {string} url - URL to navigate to. - * @param {Object} state - State. + * @param {string} url URL to navigate to. + * @param {Object} state State. * @return {void} */ function navigateRouter( url, state ) { diff --git a/src/js/_enqueues/wp/updates.js b/src/js/_enqueues/wp/updates.js index 7c971f4bb7d80..635a32975db48 100644 --- a/src/js/_enqueues/wp/updates.js +++ b/src/js/_enqueues/wp/updates.js @@ -1115,10 +1115,10 @@ * * @since 6.5.0 * - * @param {Object} response Response from the server. - * @param {string} response.slug Slug of the activated plugin. - * @param {string} response.pluginName Name of the activated plugin. - * @param {string} response.plugin The plugin file, relative to the plugins directory. + * @param {Object} response Response from the server. + * @param {string} response.slug Slug of the activated plugin. + * @param {string} response.pluginName Name of the activated plugin. + * @param {string} response.plugin The plugin file, relative to the plugins directory. */ wp.updates.activatePluginSuccess = function( response ) { var $message = $( '.plugin-card-' + response.slug + ', #plugin-information-footer' ).find( '.activating-message' ), diff --git a/src/js/_enqueues/wp/utils/word-count.js b/src/js/_enqueues/wp/utils/word-count.js index 066fc5817b491..4c336582ecf63 100644 --- a/src/js/_enqueues/wp/utils/word-count.js +++ b/src/js/_enqueues/wp/utils/word-count.js @@ -148,8 +148,8 @@ * * @memberof wp.utils.wordcounter * - * @param {string} text Text to count elements in. - * @param {string} type Optional. Specify type to use. + * @param {string} text Text to count elements in. + * @param {string} type Optional. Specify type to use. * * @return {number} The number of items counted. */ diff --git a/src/js/_enqueues/wp/widgets/custom-html.js b/src/js/_enqueues/wp/widgets/custom-html.js index 984233ecddfcb..73faf12af61da 100644 --- a/src/js/_enqueues/wp/widgets/custom-html.js +++ b/src/js/_enqueues/wp/widgets/custom-html.js @@ -42,9 +42,9 @@ wp.customHtmlWidgets = ( function( $ ) { * @augments Backbone.View * @abstract * - * @param {Object} options - Options. - * @param {jQuery} options.el - Control field container element. - * @param {jQuery} options.syncContainer - Container element where fields are synced for the server. + * @param {Object} options Options. + * @param {jQuery} options.el Control field container element. + * @param {jQuery} options.syncContainer Container element where fields are synced for the server. * * @return {void} */ @@ -124,7 +124,7 @@ wp.customHtmlWidgets = ( function( $ ) { /** * Show linting error notice. * - * @param {Array} errorAnnotations - Error annotations. + * @param {Array} errorAnnotations Error annotations. * @return {void} */ updateErrorNotice: function( errorAnnotations ) { @@ -205,7 +205,7 @@ wp.customHtmlWidgets = ( function( $ ) { * * @ignore * - * @param {Array} errorAnnotations - Error notifications. + * @param {Array} errorAnnotations Error notifications. * @return {void} */ onChangeLintingErrors: function onChangeLintingErrors( errorAnnotations ) { @@ -217,7 +217,7 @@ wp.customHtmlWidgets = ( function( $ ) { * * @ignore * - * @param {Array} errorAnnotations - Error annotations. + * @param {Array} errorAnnotations Error annotations. * @return {void} */ onUpdateErrorNotice: function onUpdateErrorNotice( errorAnnotations ) { @@ -287,8 +287,8 @@ wp.customHtmlWidgets = ( function( $ ) { * * @alias wp.customHtmlWidgets.handleWidgetAdded * - * @param {jQuery.Event} event - Event. - * @param {jQuery} widgetContainer - Widget container element. + * @param {jQuery.Event} event Event. + * @param {jQuery} widgetContainer Widget container element. * * @return {void} */ @@ -384,8 +384,8 @@ wp.customHtmlWidgets = ( function( $ ) { * * @alias wp.customHtmlWidgets.handleWidgetUpdated * - * @param {jQuery.Event} event - Event. - * @param {jQuery} widgetContainer - Widget container element. + * @param {jQuery.Event} event Event. + * @param {jQuery} widgetContainer Widget container element. * @return {void} */ component.handleWidgetUpdated = function handleWidgetUpdated( event, widgetContainer ) { @@ -415,7 +415,7 @@ wp.customHtmlWidgets = ( function( $ ) { * * @alias wp.customHtmlWidgets.init * - * @param {Object} settings - Options for code editor, exported from PHP. + * @param {Object} settings Options for code editor, exported from PHP. * * @return {void} */ diff --git a/src/js/_enqueues/wp/widgets/media-audio.js b/src/js/_enqueues/wp/widgets/media-audio.js index a57925364da70..ea85263298ed4 100644 --- a/src/js/_enqueues/wp/widgets/media-audio.js +++ b/src/js/_enqueues/wp/widgets/media-audio.js @@ -69,7 +69,7 @@ /** * Map model props to media frame props. * - * @param {Object} modelProps - Model props. + * @param {Object} modelProps Model props. * @return {Object} Media frame props. */ mapModelToMediaFrameProps: function mapModelToMediaFrameProps( modelProps ) { diff --git a/src/js/_enqueues/wp/widgets/media-gallery.js b/src/js/_enqueues/wp/widgets/media-gallery.js index 497fecd0fbd42..fe9f93cb381db 100644 --- a/src/js/_enqueues/wp/widgets/media-gallery.js +++ b/src/js/_enqueues/wp/widgets/media-gallery.js @@ -84,10 +84,10 @@ * @augments wp.mediaWidgets.MediaWidgetControl * * @since 4.9.0 - * @param {Object} options - Options. - * @param {Backbone.Model} options.model - Model. - * @param {jQuery} options.el - Control field container element. - * @param {jQuery} options.syncContainer - Container element where fields are synced for the server. + * @param {Object} options Options. + * @param {Backbone.Model} options.model Model. + * @param {jQuery} options.el Control field container element. + * @param {jQuery} options.syncContainer Container element where fields are synced for the server. * @return {void} */ initialize: function initialize( options ) { @@ -320,7 +320,7 @@ * Clear the selected attachment when it is deleted in the media select frame. * * @since 4.9.0 - * @param {wp.media.models.Attachment} attachment - Attachment. + * @param {wp.media.models.Attachment} attachment Attachment. * @return {void} */ handleAttachmentDestroy: function handleAttachmentDestroy( attachment ) { diff --git a/src/js/_enqueues/wp/widgets/media-image.js b/src/js/_enqueues/wp/widgets/media-image.js index c16600c022c2f..ff0b996d275ad 100644 --- a/src/js/_enqueues/wp/widgets/media-image.js +++ b/src/js/_enqueues/wp/widgets/media-image.js @@ -137,7 +137,7 @@ * * Prevent the image_title attribute from being initially set when adding an image from the media library. * - * @param {wp.media.view.MediaFrame.Select} mediaFrame - Select frame. + * @param {wp.media.view.MediaFrame.Select} mediaFrame Select frame. * @return {Object} Props. */ getModelPropsFromMediaFrame: function getModelPropsFromMediaFrame( mediaFrame ) { diff --git a/src/js/_enqueues/wp/widgets/media-video.js b/src/js/_enqueues/wp/widgets/media-video.js index 56a8ff1f3d5a4..180797f0ae291 100644 --- a/src/js/_enqueues/wp/widgets/media-video.js +++ b/src/js/_enqueues/wp/widgets/media-video.js @@ -87,7 +87,7 @@ /** * Map model props to media frame props. * - * @param {Object} modelProps - Model props. + * @param {Object} modelProps Model props. * @return {Object} Media frame props. */ mapModelToMediaFrameProps: function mapModelToMediaFrameProps( modelProps ) { diff --git a/src/js/_enqueues/wp/widgets/media.js b/src/js/_enqueues/wp/widgets/media.js index 66ec8e4306554..5d339308c5881 100644 --- a/src/js/_enqueues/wp/widgets/media.js +++ b/src/js/_enqueues/wp/widgets/media.js @@ -45,7 +45,7 @@ wp.mediaWidgets = ( function( $ ) { * @constructs wp.mediaWidgets.PersistentDisplaySettingsLibrary * @augments wp.media.controller.Library * - * @param {Object} options - Options. + * @param {Object} options Options. * * @return {void} */ @@ -57,7 +57,7 @@ wp.mediaWidgets = ( function( $ ) { /** * Sync changes to the current display settings back into the current customized. * - * @param {Backbone.Model} displaySettings - Modified display settings. + * @param {Backbone.Model} displaySettings Modified display settings. * @return {void} */ handleDisplaySettingChange: function handleDisplaySettingChange( displaySettings ) { @@ -72,7 +72,7 @@ wp.mediaWidgets = ( function( $ ) { * will sync back into the model storing the session's customized display * settings. * - * @param {Backbone.Model} model - Display settings model. + * @param {Backbone.Model} model Display settings model. * @return {Backbone.Model} Display settings model. */ display: function getDisplaySettingsModel( model ) { @@ -102,7 +102,7 @@ wp.mediaWidgets = ( function( $ ) { * * @since 4.9.0 * - * @param {Object} options - Options. + * @param {Object} options Options. * @return {void} */ initialize: function( options ) { @@ -137,7 +137,7 @@ wp.mediaWidgets = ( function( $ ) { /** * Set the disabled state on the Add to Widget button. * - * @param {boolean} disabled - Disabled. + * @param {boolean} disabled Disabled. * @return {void} */ setAddToWidgetButtonDisabled: function setAddToWidgetButtonDisabled( disabled ) { @@ -147,7 +147,7 @@ wp.mediaWidgets = ( function( $ ) { /** * Set or clear an error notice. * - * @param {string} notice - Notice. + * @param {string} notice Notice. * @return {void} */ setErrorNotice: function setErrorNotice( notice ) { @@ -358,7 +358,7 @@ wp.mediaWidgets = ( function( $ ) { * * Forked override of {wp.media.view.MediaFrame.Post#mainInsertToolbar()} to override text. * - * @param {wp.Backbone.View} view - Toolbar view. + * @param {wp.Backbone.View} view Toolbar view. * @this {wp.media.controller.Library} * @return {void} */ @@ -393,7 +393,7 @@ wp.mediaWidgets = ( function( $ ) { * * Forked override of {wp.media.view.MediaFrame.Post#mainEmbedToolbar()} to override text. * - * @param {wp.Backbone.View} toolbar - Toolbar view. + * @param {wp.Backbone.View} toolbar Toolbar view. * @this {wp.media.controller.Library} * @return {void} */ @@ -486,10 +486,10 @@ wp.mediaWidgets = ( function( $ ) { * @augments Backbone.View * @abstract * - * @param {Object} options - Options. - * @param {Backbone.Model} options.model - Model. - * @param {jQuery} options.el - Control field container element. - * @param {jQuery} options.syncContainer - Container element where fields are synced for the server. + * @param {Object} options Options. + * @param {Backbone.Model} options.model Model. + * @param {jQuery} options.el Control field container element. + * @param {jQuery} options.syncContainer Container element where fields are synced for the server. * * @return {void} */ @@ -721,7 +721,7 @@ wp.mediaWidgets = ( function( $ ) { /** * Handle click on link to Media Library to open modal, such as the link that appears when in the missing attachment error notice. * - * @param {jQuery.Event} event - Event. + * @param {jQuery.Event} event Event. * @return {void} */ handleMediaLibraryLinkClick: function handleMediaLibraryLinkClick( event ) { @@ -819,7 +819,7 @@ wp.mediaWidgets = ( function( $ ) { /** * Get the instance props from the media selection frame. * - * @param {wp.media.view.MediaFrame.Select} mediaFrame - Select frame. + * @param {wp.media.view.MediaFrame.Select} mediaFrame Select frame. * @return {Object} Props. */ getModelPropsFromMediaFrame: function getModelPropsFromMediaFrame( mediaFrame ) { @@ -868,7 +868,7 @@ wp.mediaWidgets = ( function( $ ) { /** * Map media frame props to model props. * - * @param {Object} mediaFrameProps - Media frame props. + * @param {Object} mediaFrameProps Media frame props. * @return {Object} Model props. */ mapMediaToModelProps: function mapMediaToModelProps( mediaFrameProps ) { @@ -919,7 +919,7 @@ wp.mediaWidgets = ( function( $ ) { /** * Map model props to media frame props. * - * @param {Object} modelProps - Model props. + * @param {Object} modelProps Model props. * @return {Object} Media frame props. */ mapModelToMediaFrameProps: function mapModelToMediaFrameProps( modelProps ) { @@ -1028,9 +1028,9 @@ wp.mediaWidgets = ( function( $ ) { * cast the attribute values from the hidden inputs' string values into * the appropriate data types (integers or booleans). * - * @param {string|Object} key - Attribute name or attribute pairs. - * @param {mixed|Object} [val] - Attribute value or options object. - * @param {Object} [options] - Options when attribute name and value are passed separately. + * @param {string|Object} key Attribute name or attribute pairs. + * @param {mixed|Object} [val] Attribute value or options object. + * @param {Object} [options] Options when attribute name and value are passed separately. * @return {wp.mediaWidgets.MediaWidgetModel} This model. */ set: function set( key, val, options ) { @@ -1119,8 +1119,8 @@ wp.mediaWidgets = ( function( $ ) { * * @memberOf wp.mediaWidgets * - * @param {jQuery.Event} event - Event. - * @param {jQuery} widgetContainer - Widget container element. + * @param {jQuery.Event} event Event. + * @param {jQuery} widgetContainer Widget container element. * * @return {void} */ @@ -1256,8 +1256,8 @@ wp.mediaWidgets = ( function( $ ) { * * @memberOf wp.mediaWidgets * - * @param {jQuery.Event} event - Event. - * @param {jQuery} widgetContainer - Widget container element. + * @param {jQuery.Event} event Event. + * @param {jQuery} widgetContainer Widget container element. * * @return {void} */ diff --git a/src/js/_enqueues/wp/widgets/text.js b/src/js/_enqueues/wp/widgets/text.js index df09ab40974ef..4b7af2e0d4a80 100644 --- a/src/js/_enqueues/wp/widgets/text.js +++ b/src/js/_enqueues/wp/widgets/text.js @@ -34,9 +34,9 @@ wp.textWidgets = ( function( $ ) { * @augments Backbone.View * @abstract * - * @param {Object} options - Options. - * @param {jQuery} options.el - Control field container element. - * @param {jQuery} options.syncContainer - Container element where fields are synced for the server. + * @param {Object} options Options. + * @param {jQuery} options.el Control field container element. + * @param {jQuery} options.syncContainer Container element where fields are synced for the server. * * @return {void} */ @@ -376,8 +376,8 @@ wp.textWidgets = ( function( $ ) { * * @memberOf wp.textWidgets * - * @param {jQuery.Event} event - Event. - * @param {jQuery} widgetContainer - Widget container element. + * @param {jQuery.Event} event Event. + * @param {jQuery} widgetContainer Widget container element. * * @return {void} */ @@ -484,8 +484,8 @@ wp.textWidgets = ( function( $ ) { * * @memberOf wp.textWidgets * - * @param {jQuery.Event} event - Event. - * @param {jQuery} widgetContainer - Widget container element. + * @param {jQuery.Event} event Event. + * @param {jQuery} widgetContainer Widget container element. * @return {void} */ component.handleWidgetUpdated = function handleWidgetUpdated( event, widgetContainer ) { diff --git a/src/js/media/controllers/state.js b/src/js/media/controllers/state.js index 12c07816251bc..1bacae9c0e734 100644 --- a/src/js/media/controllers/state.js +++ b/src/js/media/controllers/state.js @@ -6,11 +6,11 @@ * * A state has an event-driven lifecycle: * - * 'ready' triggers when a state is added to a state machine's collection. - * 'activate' triggers when a state is activated by a state machine. - * 'deactivate' triggers when a state is deactivated by a state machine. - * 'reset' is not triggered automatically. It should be invoked by the - * proper controller to reset the state to its default. + * 'ready' triggers when a state is added to a state machine's collection. + * 'activate' triggers when a state is activated by a state machine. + * 'deactivate' triggers when a state is deactivated by a state machine. + * 'reset' is not triggered automatically. It should be invoked by the + * proper controller to reset the state to its default. * * @memberOf wp.media.controller * @@ -85,7 +85,7 @@ var State = Backbone.Model.extend(/** @lends wp.media.controller.State.prototype * * @since 3.5.0 * @access private - */ + */ _preActivate: function() { this.active = true; }, diff --git a/src/js/media/models/attachment.js b/src/js/media/models/attachment.js index a116edf4add40..5c18eec27bf11 100644 --- a/src/js/media/models/attachment.js +++ b/src/js/media/models/attachment.js @@ -115,7 +115,7 @@ Attachment = Backbone.Model.extend(/** @lends wp.media.model.Attachment.prototyp /** * Saves attachment details using the `save-attachment-compat` action. * - * @param {Object} data The properties to be saved. + * @param {Object} data The properties to be saved. * @param {Object} options Sync options. e.g. patch, wait, success, error. * * @this Backbone.Model diff --git a/src/js/media/models/attachments.js b/src/js/media/models/attachments.js index fc6d79632d745..98d60e34726f5 100644 --- a/src/js/media/models/attachments.js +++ b/src/js/media/models/attachments.js @@ -18,8 +18,8 @@ * @param {string} [options.props.order] Initial order (ASC or DESC) for the collection. * @param {string} [options.props.orderby] Initial attribute key to order the collection by. * @param {string} [options.props.query] Whether the collection is linked to an attachments query. - * @param {string} [options.observe] An attachments collection to observe and mirror. - * @param {string} [options.filters] Filters to apply to the collection. + * @param {string} [options.observe] An attachments collection to observe and mirror. + * @param {string} [options.filters] Filters to apply to the collection. * */ var Attachments = Backbone.Collection.extend(/** @lends wp.media.model.Attachments.prototype */{ diff --git a/src/js/media/models/post-media.js b/src/js/media/models/post-media.js index fd642a724f6e1..56d76bbd24d0e 100644 --- a/src/js/media/models/post-media.js +++ b/src/js/media/models/post-media.js @@ -2,7 +2,7 @@ * wp.media.model.PostMedia * * Shared model class for audio and video. Updates the model after - * "Add Audio|Video Source" and "Replace Audio|Video" states return + * "Add Audio|Video Source" and "Replace Audio|Video" states return * * @memberOf wp.media.model * diff --git a/src/js/media/models/query.js b/src/js/media/models/query.js index dbcdb87d77466..74559c8320b3e 100644 --- a/src/js/media/models/query.js +++ b/src/js/media/models/query.js @@ -7,7 +7,7 @@ var Attachments = wp.media.model.Attachments, * A collection of attachments that match the supplied query arguments. * * Note: Do NOT change this.args after the query has been initialized. - * Things will break. + * Things will break. * * @memberOf wp.media.model * diff --git a/src/js/media/views/attachments/browser.js b/src/js/media/views/attachments/browser.js index 3726d39e2f145..8d7d4dca51b76 100644 --- a/src/js/media/views/attachments/browser.js +++ b/src/js/media/views/attachments/browser.js @@ -187,8 +187,8 @@ AttachmentsBrowser = View.extend(/** @lends wp.media.view.AttachmentsBrowser.pro } /** - * @member {wp.media.view.Toolbar} - */ + * @member {wp.media.view.Toolbar} + */ this.toolbar = new wp.media.view.Toolbar( toolbarOptions ); this.views.add( this.toolbar ); diff --git a/src/js/media/views/focus-manager.js b/src/js/media/views/focus-manager.js index 36ef6a851b0da..749d283c7245d 100644 --- a/src/js/media/views/focus-manager.js +++ b/src/js/media/views/focus-manager.js @@ -31,14 +31,14 @@ var FocusManager = wp.media.View.extend(/** @lends wp.media.view.FocusManager.pr }, /** - * Determines which focus management mode to use. - * - * @since 5.3.0 - * - * @param {Object} event jQuery event object. - * - * @return {void} - */ + * Determines which focus management mode to use. + * + * @since 5.3.0 + * + * @param {Object} event jQuery event object. + * + * @return {void} + */ focusManagementMode: function( event ) { if ( this.mode === 'constrainTabbing' ) { this.constrainTabbing( event ); diff --git a/tools/gutenberg/copy.js b/tools/gutenberg/copy.js index 3da78e4b14611..367da7ba53127 100644 --- a/tools/gutenberg/copy.js +++ b/tools/gutenberg/copy.js @@ -34,10 +34,10 @@ const wpIncludesDir = path.join( rootDir, 'src', 'wp-includes' ); * * @typedef ScriptsConfig * @type {object} - * @property {string} source - Gutenberg-relative source directory (e.g. `'scripts'`). - * @property {string} destination - Subpath under `wp-includes/` where packages land (e.g. `'js/dist'`). - * @property {boolean} copyDirectories - Whether to copy whole directories (with optional renames) as-is. - * @property {Record} directoryRenames - Map of source directory name → destination directory name. + * @property {string} source Gutenberg-relative source directory (e.g. `'scripts'`). + * @property {string} destination Subpath under `wp-includes/` where packages land (e.g. `'js/dist'`). + * @property {boolean} copyDirectories Whether to copy whole directories (with optional renames) as-is. + * @property {Record} directoryRenames Map of source directory name → destination directory name. */ /** @@ -45,10 +45,10 @@ const wpIncludesDir = path.join( rootDir, 'src', 'wp-includes' ); * * @typedef BlockConfigSource * @type {object} - * @property {string} name - Human-readable label (e.g. `'block-library'`, `'widgets'`). - * @property {string} scripts - Gutenberg-relative path to the block scripts directory. - * @property {string} styles - Gutenberg-relative path to the block styles directory. - * @property {string} php - Gutenberg-relative path to the block PHP directory. + * @property {string} name Human-readable label (e.g. `'block-library'`, `'widgets'`). + * @property {string} scripts Gutenberg-relative path to the block scripts directory. + * @property {string} styles Gutenberg-relative path to the block styles directory. + * @property {string} php Gutenberg-relative path to the block PHP directory. */ /** @@ -56,8 +56,8 @@ const wpIncludesDir = path.join( rootDir, 'src', 'wp-includes' ); * * @typedef BlockConfig * @type {object} - * @property {string} destination - Subpath under `wp-includes/` where blocks land (e.g. `'blocks'`). - * @property {BlockConfigSource[]} sources - One entry per block family. + * @property {string} destination Subpath under `wp-includes/` where blocks land (e.g. `'blocks'`). + * @property {BlockConfigSource[]} sources One entry per block family. */ /** @@ -118,7 +118,7 @@ function readReturnedValueFromPHPFile( phpFilepath ) { /** * Check if a block is experimental by reading its block.json. * - * @param {string} blockJsonPath - Path to block.json file. + * @param {string} blockJsonPath Path to block.json file. * @return {boolean} True if block is experimental. */ function isExperimentalBlock( blockJsonPath ) { @@ -140,7 +140,7 @@ function isExperimentalBlock( blockJsonPath ) { * * Blocks marked as `"__experimental": true` in a `block.json` file are excluded. * - * @param {string} scriptsSrc - Path to the Gutenberg scripts source (e.g. `scripts/block-library`). + * @param {string} scriptsSrc Path to the Gutenberg scripts source (e.g. `scripts/block-library`). * @return {string[]} Stable block directory names. */ function getStableBlocks( scriptsSrc ) { @@ -159,7 +159,7 @@ function getStableBlocks( scriptsSrc ) { /** * Copy JavaScript files. * - * @param {ScriptsConfig} config - Scripts configuration from `COPY_CONFIG.scripts`. + * @param {ScriptsConfig} config Scripts configuration from `COPY_CONFIG.scripts`. */ function copyScripts( config ) { const scriptsSrc = path.join( gutenbergBuildDir, config.source ); @@ -248,7 +248,7 @@ function copyScripts( config ) { /** * Copy `block.json` files for every stable block. * - * @param {BlockConfig} config - Block configuration from `COPY_CONFIG.blocks`. + * @param {BlockConfig} config Block configuration from `COPY_CONFIG.blocks`. */ function copyBlockJson( config ) { const blocksDest = path.join( wpIncludesDir, config.destination ); @@ -283,7 +283,7 @@ function copyBlockJson( config ) { * Handles both the top-level `.php` dynamic block files and any nested * `*.php` helpers under `/` (e.g. `navigation-link/shared/render-submenu-icon.php`). * - * @param {BlockConfig} config - Block configuration from `COPY_CONFIG.blocks`. + * @param {BlockConfig} config Block configuration from `COPY_CONFIG.blocks`. */ function copyBlockPhp( config ) { const blocksDest = path.join( wpIncludesDir, config.destination ); @@ -338,7 +338,7 @@ function copyBlockPhp( config ) { /** * Copy per-block CSS files for every stable block. * - * @param {BlockConfig} config - Block configuration from `COPY_CONFIG.blocks`. + * @param {BlockConfig} config Block configuration from `COPY_CONFIG.blocks`. */ function copyBlockStyles( config ) { const blocksDest = path.join( wpIncludesDir, config.destination ); @@ -391,8 +391,8 @@ function generateScriptModulesPackages() { /** * Recursively process directory to find .asset.php files. * - * @param {string} dir - Directory to process. - * @param {string} baseDir - Base directory for relative paths. + * @param {string} dir Directory to process. + * @param {string} baseDir Base directory for relative paths. */ function processDirectory( dir, baseDir ) { if ( ! fs.existsSync( dir ) ) { From 73ea9ac3c79e058c869bb85aa0ae0ef95bf38b42 Mon Sep 17 00:00:00 2001 From: Aki Hamano Date: Fri, 11 Sep 2026 11:05:35 +0000 Subject: [PATCH 484/634] Code Modernization: Use null coalescing operator in `WP_Block_Parser` Two methods used a ternary that treats a falsy value as not provided even though the parameters accept `0` as valid input, so this switches to the null coalescing operator, which tests only for `null`. Developed in: https://github.com/WordPress/wordpress-develop/pull/13484 Props mukesh27, wildworks. See #65818. git-svn-id: https://develop.svn.wordpress.org/trunk@63601 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/class-wp-block-parser.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/class-wp-block-parser.php b/src/wp-includes/class-wp-block-parser.php index c7e087ece8711..3b50c8e30cfe4 100644 --- a/src/wp-includes/class-wp-block-parser.php +++ b/src/wp-includes/class-wp-block-parser.php @@ -324,7 +324,7 @@ public function freeform( $inner_html ) { * @param null|int $length How many bytes of document text to output. */ public function add_freeform( $length = null ) { - $length = $length ? $length : strlen( $this->document ) - $this->offset; + $length = $length ?? strlen( $this->document ) - $this->offset; if ( 0 === $length ) { return; @@ -356,7 +356,7 @@ public function add_inner_block( WP_Block_Parser_Block $block, $token_start, $to } $parent->block->innerContent[] = null; - $parent->prev_offset = $last_offset ? $last_offset : $token_start + $token_length; + $parent->prev_offset = $last_offset ?? $token_start + $token_length; } /** From c176fdbd3a0a7b3615c7ebce54ae7179c3a99e6a Mon Sep 17 00:00:00 2001 From: Jorge Costa Date: Fri, 11 Sep 2026 16:13:44 +0000 Subject: [PATCH 485/634] Block Editor: Output `flex-direction: row` when a viewport override switches a flex layout to horizontal. `row` is the flex default, so the base layout never declares it. When a Tablet or Mobile override switched a vertical (Stack) layout to horizontal, the base `flex-direction: column` kept applying and the block stayed vertical. Backports https://github.com/WordPress/gutenberg/pull/82364. Developed in https://github.com/WordPress/wordpress-develop/pull/13370. Props jorgefilipecosta, talldanwp, firdaus666. Fixes #66096. git-svn-id: https://develop.svn.wordpress.org/trunk@63602 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/block-supports/layout.php | 11 ++++ tests/phpunit/tests/block-supports/layout.php | 61 +++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/src/wp-includes/block-supports/layout.php b/src/wp-includes/block-supports/layout.php index 24431a05bb74a..b7c0503d3b5da 100644 --- a/src/wp-includes/block-supports/layout.php +++ b/src/wp-includes/block-supports/layout.php @@ -792,6 +792,17 @@ function wp_get_layout_style( $selector, $layout, $has_block_gap_support = false $flex_vertical_alignment = $layout_for_styles['verticalAlignment'] ?? null; if ( 'horizontal' === $layout_orientation ) { + /* + * `row` is the flex default, so the base layout never declares it. A viewport + * override that switches a vertical base layout to horizontal has to declare + * it explicitly, otherwise the base `flex-direction: column` keeps applying. + */ + if ( null !== $viewport_overrides && $has_viewport_property_override( 'orientation' ) ) { + $layout_styles[] = array( + 'selector' => $selector, + 'declarations' => array( 'flex-direction' => 'row' ), + ); + } /* * Add this style only if is not empty for backwards compatibility, * since we intend to convert blocks that had flex layout implemented diff --git a/tests/phpunit/tests/block-supports/layout.php b/tests/phpunit/tests/block-supports/layout.php index cda17660d67aa..2a8c7fc88cd6b 100644 --- a/tests/phpunit/tests/block-supports/layout.php +++ b/tests/phpunit/tests/block-supports/layout.php @@ -1233,6 +1233,67 @@ public function test_wp_get_layout_style_with_non_string_flex_alignment() { $this->assertIsString( $layout_styles, 'Flex layout should not fatal when alignment values are not strings.' ); } + /** + * Tests that a viewport override switching a vertical flex layout to horizontal + * outputs an explicit `flex-direction: row`, so the base `flex-direction: column` + * no longer applies on that viewport. + * + * @covers ::wp_get_layout_style + */ + public function test_wp_get_layout_style_outputs_flex_direction_row_for_horizontal_viewport_override() { + $layout_styles = wp_get_layout_style( + '.wp-layout', + array( + 'type' => 'flex', + 'orientation' => 'vertical', + 'flexWrap' => 'nowrap', + 'justifyContent' => 'center', + ), + false, + null, + false, + '0.5em', + null, + array( + 'viewport_overrides' => array( + 'orientation' => 'horizontal', + 'justifyContent' => 'left', + ), + ) + ); + + $this->assertSame( '.wp-layout{flex-direction:row;justify-content:flex-start;}', $layout_styles ); + } + + /** + * Tests that a viewport override which does not change a horizontal orientation + * keeps relying on the flex default and does not output `flex-direction`. + * + * @covers ::wp_get_layout_style + */ + public function test_wp_get_layout_style_keeps_flex_direction_implicit_without_orientation_override() { + $layout_styles = wp_get_layout_style( + '.wp-layout', + array( + 'type' => 'flex', + 'orientation' => 'horizontal', + 'justifyContent' => 'left', + ), + false, + null, + false, + '0.5em', + null, + array( + 'viewport_overrides' => array( + 'justifyContent' => 'right', + ), + ) + ); + + $this->assertSame( '.wp-layout{justify-content:flex-end;}', $layout_styles ); + } + /** * Tests that a responsive grid child with a non-string parent minimumColumnWidth * does not cause a fatal error in the explode() call. From 01248eefccfa2a60f23417e0e2f9046a18b6ed19 Mon Sep 17 00:00:00 2001 From: Jonny Harris Date: Fri, 11 Sep 2026 16:50:51 +0000 Subject: [PATCH 486/634] Meta: Support site meta subtype in get_object_subtype(). Add a 'blog' case to get_object_subtype() so register_meta() can resolve subtypes for site meta, matching the support already in place for posts, terms, comments, and users. Introduce register_site_meta() and unregister_site_meta() wrapper functions for registering and unregistering meta for sites, consistent with the existing site meta wrapper functions. Props sainathpoojary, spacedmonkey, flixos90, johnbillion. Fixes #44387. git-svn-id: https://develop.svn.wordpress.org/trunk@63603 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/meta.php | 14 ++++ src/wp-includes/ms-site.php | 26 +++++++ tests/phpunit/tests/meta/registerMeta.php | 94 +++++++++++++++++++++++ 3 files changed, 134 insertions(+) diff --git a/src/wp-includes/meta.php b/src/wp-includes/meta.php index 577785c2163a0..7bce5f40c059b 100644 --- a/src/wp-includes/meta.php +++ b/src/wp-includes/meta.php @@ -1789,6 +1789,7 @@ function _wp_register_meta_args_allowed_list( $args, $default_args ) { * Returns the object subtype for a given object ID of a specific type. * * @since 4.9.8 + * @since 7.2.0 Added support for 'blog' object type in multisite. * * @param string $object_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term', * 'user', or any other object type with an associated meta table. @@ -1834,6 +1835,19 @@ function get_object_subtype( $object_type, $object_id ) { $object_subtype = 'user'; break; + + case 'blog': + if ( ! is_multisite() || $object_id <= 0 ) { + break; + } + + $site = get_site( $object_id ); + if ( ! $site ) { + break; + } + + $object_subtype = 'blog'; + break; } /** diff --git a/src/wp-includes/ms-site.php b/src/wp-includes/ms-site.php index 6399dab72e881..65f5259fe12d0 100644 --- a/src/wp-includes/ms-site.php +++ b/src/wp-includes/ms-site.php @@ -1129,6 +1129,32 @@ function delete_site_meta_by_key( $meta_key ) { return delete_metadata( 'blog', null, $meta_key, '', true ); } +/** + * Registers a meta key for sites. + * + * @since 7.2.0 + * + * @param string $meta_key The meta key to register. + * @param array $args Data used to describe the meta key when registered. See + * {@see register_meta()} for a list of supported arguments. + * @return bool True if the meta key was successfully registered, false if not. + */ +function register_site_meta( $meta_key, array $args ) { + return register_meta( 'blog', $meta_key, $args ); +} + +/** + * Unregisters a meta key for sites. + * + * @since 7.2.0 + * + * @param string $meta_key The meta key to unregister. + * @return bool True on success, false if the meta key was not previously registered. + */ +function unregister_site_meta( $meta_key ) { + return unregister_meta_key( 'blog', $meta_key ); +} + /** * Updates the count of sites for a network based on a changed site. * diff --git a/tests/phpunit/tests/meta/registerMeta.php b/tests/phpunit/tests/meta/registerMeta.php index 30b6920bdea0d..4ffe6d751d99b 100644 --- a/tests/phpunit/tests/meta/registerMeta.php +++ b/tests/phpunit/tests/meta/registerMeta.php @@ -8,12 +8,17 @@ class Tests_Meta_Register_Meta extends WP_UnitTestCase { protected static $term_id; protected static $comment_id; protected static $user_id; + protected static $blog_id; public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) { self::$post_id = $factory->post->create( array( 'post_type' => 'page' ) ); self::$term_id = $factory->term->create( array( 'taxonomy' => 'category' ) ); self::$comment_id = $factory->comment->create(); self::$user_id = $factory->user->create(); + + if ( is_multisite() ) { + self::$blog_id = $factory->blog->create(); + } } public static function wpTearDownAfterClass() { @@ -21,6 +26,11 @@ public static function wpTearDownAfterClass() { wp_delete_term( self::$term_id, 'category' ); wp_delete_comment( self::$comment_id, true ); self::delete_user( self::$user_id ); + + if ( is_multisite() ) { + wp_delete_site( self::$blog_id ); + wp_update_network_site_counts(); + } } public function _old_sanitize_meta_cb( $meta_value, $meta_key, $meta_type ) { @@ -1105,6 +1115,60 @@ public function data_get_types_and_subtypes() { ); } + /** + * @ticket 44387 + * @group ms-required + */ + public function test_get_object_subtype_for_blog_returns_blog_when_site_exists() { + $this->assertSame( 'blog', get_object_subtype( 'blog', self::$blog_id ) ); + } + + /** + * @ticket 44387 + * @group ms-required + */ + public function test_get_object_subtype_for_blog_returns_empty_string_for_invalid_site() { + $this->assertSame( '', get_object_subtype( 'blog', 0 ) ); + $this->assertSame( '', get_object_subtype( 'blog', 999999 ) ); + } + + /** + * @ticket 44387 + * @group ms-excluded + */ + public function test_get_object_subtype_for_blog_returns_empty_string_no_multisite() { + $this->assertSame( '', get_object_subtype( 'blog', 0 ) ); + } + + /** + * @ticket 44387 + * @group ms-required + */ + public function test_get_object_subtype_for_blog_with_registered_meta() { + if ( ! is_site_meta_supported() ) { + $this->markTestSkipped( 'Test only runs with the blogmeta database table installed.' ); + } + + $this->assertSame( 'blog', get_object_subtype( 'blog', self::$blog_id ) ); + + register_meta( + 'blog', + 'site_rating', + array( + 'single' => true, + 'object_subtype' => 'blog', + ) + ); + add_site_meta( self::$blog_id, 'site_rating', '5' ); + + $meta = get_registered_metadata( 'blog', self::$blog_id, 'site_rating' ); + + unregister_meta_key( 'blog', 'site_rating', 'blog' ); + delete_site_meta( self::$blog_id, 'site_rating' ); + + $this->assertSame( '5', $meta ); + } + /** * Test that attempting to register meta with revisions_enabled set to true on a * post type that does not have revisions enabled fails and throws a `doing_it_wrong` notice. @@ -1135,4 +1199,34 @@ public function test_register_meta_with_revisions_enabled_on_post_type_without_r $this->assertFalse( $register ); } + + /** + * @ticket 44387 + * @group ms-required + */ + public function test_register_site_meta_returns_true_on_success() { + if ( ! is_site_meta_supported() ) { + $this->markTestSkipped( 'Test only runs with the blogmeta database table installed.' ); + } + + $result = register_site_meta( 'test_site_meta_key', array( 'single' => true ) ); + unregister_site_meta( 'test_site_meta_key' ); + + $this->assertTrue( $result ); + } + + /** + * @ticket 44387 + * @group ms-required + */ + public function test_unregister_site_meta_returns_true_on_success() { + if ( ! is_site_meta_supported() ) { + $this->markTestSkipped( 'Test only runs with the blogmeta database table installed.' ); + } + + register_site_meta( 'test_site_meta_key', array( 'single' => true ) ); + $result = unregister_site_meta( 'test_site_meta_key' ); + + $this->assertTrue( $result ); + } } From 1dfb754c2b80a32456b91bf3604ff7a003a73286 Mon Sep 17 00:00:00 2001 From: Lance Willett Date: Fri, 11 Sep 2026 20:59:28 +0000 Subject: [PATCH 487/634] Tests: Use `assertSame()` in `WP_Customize_Nav_Menu_Item_Setting` tests. This ensures that not only the return values match the expected results, but also that their type is the same. Where a loose comparison is intentional, inline comments now explain why: post meta returns IDs as strings, and some objects are compared by value. Developed in: https://github.com/WordPress/wordpress-develop/pull/13451 Props r1k0, mukesh27. See #64895. git-svn-id: https://develop.svn.wordpress.org/trunk@63604 602fd350-edb4-49c9-b593-d223f7449a82 --- .../tests/customize/nav-menu-item-setting.php | 23 +++++++++++++++++-- .../tests/customize/nav-menu-setting.php | 4 ++++ tests/phpunit/tests/customize/widgets.php | 2 ++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/tests/customize/nav-menu-item-setting.php b/tests/phpunit/tests/customize/nav-menu-item-setting.php index 0c832f3c6887c..124015557be92 100644 --- a/tests/phpunit/tests/customize/nav-menu-item-setting.php +++ b/tests/phpunit/tests/customize/nav-menu-item-setting.php @@ -190,7 +190,7 @@ public function test_value_type_post_type() { $value = $setting->value(); $this->assertSame( $menu_item->title, $value['title'] ); $this->assertSame( $menu_item->type, $value['type'] ); - $this->assertEquals( $menu_item->object_id, $value['object_id'] ); + $this->assertSame( (int) $menu_item->object_id, $value['object_id'] ); $this->assertSame( $menu_id, $value['nav_menu_term_id'] ); $this->assertSame( 'Hello World', $value['original_title'] ); @@ -273,7 +273,7 @@ public function test_value_type_taxonomy() { $value = $setting->value(); $this->assertSame( $menu_item->title, $value['title'] ); $this->assertSame( $menu_item->type, $value['type'] ); - $this->assertEquals( $menu_item->object_id, $value['object_id'] ); + $this->assertSame( (int) $menu_item->object_id, $value['object_id'] ); $this->assertSame( $menu_id, $value['nav_menu_term_id'] ); $this->assertSame( 'Salutations', $value['original_title'] ); } @@ -632,8 +632,17 @@ public function test_sanitize() { $post = get_post( $nav_menu_item_id ); $nav_menu_item = wp_setup_nav_menu_item( clone $post ); + /* + * Keep assertEquals() because sanitize() returns object_id as an integer + * while wp_setup_nav_menu_item() retrieves it as a string from post meta. + */ $this->assertEquals( $expected_sanitized['object_id'], $nav_menu_item->object_id ); $this->assertSame( $expected_sanitized['object'], $nav_menu_item->object ); + + /* + * Keep assertEquals() because sanitize() returns menu_item_parent as an integer, + * while wp_setup_nav_menu_item() retrieves it as a string from post meta. + */ $this->assertEquals( $expected_sanitized['menu_item_parent'], $nav_menu_item->menu_item_parent ); $this->assertSame( $expected_sanitized['position'], $post->menu_order ); $this->assertSame( $expected_sanitized['type'], $nav_menu_item->type ); @@ -697,6 +706,11 @@ public function test_save_updated() { $updated_item = $menu_items[ $i ]; $post_value['post_status'] = $post_value['status']; unset( $post_value['status'] ); + + /* + * Keep assertEquals() because object_id is an integer in $post_value + * but is returned as a string from post meta by wp_setup_nav_menu_item(). + */ foreach ( $post_value as $key => $value ) { $this->assertEquals( $value, $updated_item->$key, "Key $key mismatch" ); } @@ -770,6 +784,11 @@ public function test_save_inserted() { unset( $post_value['status'] ); $post_value['menu_order'] = $post_value['position']; unset( $post_value['position'] ); + + /* + * Keep assertEquals() because object_id is an integer in $post_value + * but is returned as a string from post meta by wp_setup_nav_menu_item(). + */ foreach ( $post_value as $key => $value ) { $this->assertEquals( $value, $last_item->$key, "Mismatch for $key property." ); } diff --git a/tests/phpunit/tests/customize/nav-menu-setting.php b/tests/phpunit/tests/customize/nav-menu-setting.php index 1348c86395a92..b7f9f9b057f4b 100644 --- a/tests/phpunit/tests/customize/nav-menu-setting.php +++ b/tests/phpunit/tests/customize/nav-menu-setting.php @@ -232,6 +232,8 @@ public function test_preview_updated() { $this->assertSameSets( $value, wp_array_slice_assoc( $term, array_keys( $value ) ) ); $menu_object = wp_get_nav_menu_object( $menu_id ); + + // Keep assertEquals() because the objects are intentionally compared by value. $this->assertEquals( (object) $term, $menu_object ); $this->assertSame( $post_value['name'], $menu_object->name ); @@ -277,6 +279,8 @@ public function test_preview_inserted() { $this->assertSame( $menu_id, $term['term_taxonomy_id'] ); $menu_object = wp_get_nav_menu_object( $menu_id ); + + // Keep assertEquals() because the objects are intentionally compared by value. $this->assertEquals( (object) $term, $menu_object ); $this->assertSame( $post_value['name'], $menu_object->name ); diff --git a/tests/phpunit/tests/customize/widgets.php b/tests/phpunit/tests/customize/widgets.php index c2ed6dbc661e2..b28246ac35a3f 100644 --- a/tests/phpunit/tests/customize/widgets.php +++ b/tests/phpunit/tests/customize/widgets.php @@ -515,6 +515,8 @@ public function test_sanitize_widget_instance_raw_instance() { $this->assertSame( '', $sanitized_for_js['title'] ); $this->assertTrue( $sanitized_for_js['is_widget_customizer_js_value'] ); $this->assertArrayHasKey( 'instance_hash_key', $sanitized_for_js ); + + // Keep assertEquals() because the objects are intentionally compared by value. $this->assertEquals( (object) $block_instance, $sanitized_for_js['raw_instance'] ); $unsanitized_from_js = $this->manager->widgets->sanitize_widget_instance( $sanitized_for_js ); From 98a8a2f0aba9011b0b9e8be2afc0bca5255bdc38 Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Fri, 11 Sep 2026 23:14:49 +0000 Subject: [PATCH 488/634] Docs: Remove Screencast from the list of supported oEmbed providers. This is just a documentation change, as support for screencast.com has already been removed as of WordPress 6.8.2. This commit updates the list of supported providers in the `oembed_providers` filter DocBlock to reflect that change. Developed in https://github.com/WordPress/wordpress-develop/pull/13479. Follow-up to r60345. Props maheshpawar2012, westonruter, SergeyBiryukov. Fixes #66090. git-svn-id: https://develop.svn.wordpress.org/trunk@63605 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/class-wp-oembed.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/wp-includes/class-wp-oembed.php b/src/wp-includes/class-wp-oembed.php index fa307092d409c..9d55a7adb1d05 100644 --- a/src/wp-includes/class-wp-oembed.php +++ b/src/wp-includes/class-wp-oembed.php @@ -175,7 +175,6 @@ public function __construct() { * | Twitter | twitter.com/user | 4.7.0 | * | Twitter | twitter.com/likes | 4.7.0 | * | Twitter | twitter.com/lists | 4.7.0 | - * | Screencast | screencast.com | 4.8.0 | * | Amazon | amazon.com (com.mx, com.br, ca) | 4.9.0 | * | Amazon | amazon.de (fr, it, es, in, nl, ru, co.uk) | 4.9.0 | * | Amazon | amazon.co.jp (com.au) | 4.9.0 | From 5c4fd7dc0db6b33cf1808bed18b2170ee378d9a0 Mon Sep 17 00:00:00 2001 From: Lance Willett Date: Sat, 12 Sep 2026 23:25:20 +0000 Subject: [PATCH 489/634] Tests: Use strict assertions in XML-RPC tests. Use type-strict comparisons for XML-RPC results and persisted values, matching the documented string ID contracts. Add explicit string checks where negative comparisons and numeric-format assertions do not enforce types. Correct the profile email test to inspect user_email, so it detects an unintended email change. Retain the loose term-array comparison because the internal and XML-RPC representations use different ID types. Developed in: https://github.com/WordPress/wordpress-develop/pull/13503 Props haritpanchal. See #64895. git-svn-id: https://develop.svn.wordpress.org/trunk@63606 602fd350-edb4-49c9-b593-d223f7449a82 --- tests/phpunit/tests/xmlrpc/mw/editPost.php | 12 ++++++------ tests/phpunit/tests/xmlrpc/mw/newPost.php | 7 ++++--- tests/phpunit/tests/xmlrpc/wp/editPost.php | 14 +++++++------- tests/phpunit/tests/xmlrpc/wp/editProfile.php | 2 +- tests/phpunit/tests/xmlrpc/wp/editTerm.php | 2 +- tests/phpunit/tests/xmlrpc/wp/getComment.php | 10 +++++----- tests/phpunit/tests/xmlrpc/wp/getComments.php | 2 +- tests/phpunit/tests/xmlrpc/wp/getPost.php | 6 +++--- tests/phpunit/tests/xmlrpc/wp/getPosts.php | 2 +- tests/phpunit/tests/xmlrpc/wp/getProfile.php | 6 +++--- tests/phpunit/tests/xmlrpc/wp/getTerm.php | 11 ++++++++++- tests/phpunit/tests/xmlrpc/wp/getTerms.php | 4 ++-- tests/phpunit/tests/xmlrpc/wp/getUser.php | 10 +++++----- tests/phpunit/tests/xmlrpc/wp/getUsers.php | 2 +- tests/phpunit/tests/xmlrpc/wp/newPost.php | 7 ++++--- 15 files changed, 54 insertions(+), 43 deletions(-) diff --git a/tests/phpunit/tests/xmlrpc/mw/editPost.php b/tests/phpunit/tests/xmlrpc/mw/editPost.php index eb996787acc09..23515233325ff 100644 --- a/tests/phpunit/tests/xmlrpc/mw/editPost.php +++ b/tests/phpunit/tests/xmlrpc/mw/editPost.php @@ -88,7 +88,7 @@ public function test_capable_reassign_author() { $this->assertTrue( $result ); $out = get_post( $post_id ); - $this->assertEquals( $author_id, $out->post_author ); + $this->assertSame( (string) $author_id, $out->post_author ); } public function test_incapable_reassign_author() { @@ -107,7 +107,7 @@ public function test_incapable_reassign_author() { $this->assertSame( 401, $result->code ); $out = get_post( $post_id ); - $this->assertEquals( $contributor_id, $out->post_author ); + $this->assertSame( (string) $contributor_id, $out->post_author ); } /** @@ -129,7 +129,7 @@ public function test_capable_reassign_author_to_self() { $this->assertTrue( $result ); $out = get_post( $post_id ); - $this->assertEquals( $editor_id, $out->post_author ); + $this->assertSame( (string) $editor_id, $out->post_author ); } /** @@ -156,13 +156,13 @@ public function test_post_thumbnail() { $post2 = array( 'wp_post_thumbnail' => $attachment_id ); $result = $this->myxmlrpcserver->mw_editPost( array( $post_id, 'author', 'author', $post2 ) ); $this->assertNotIXRError( $result ); - $this->assertEquals( $attachment_id, get_post_meta( $post_id, '_thumbnail_id', true ) ); + $this->assertSame( (string) $attachment_id, get_post_meta( $post_id, '_thumbnail_id', true ) ); // Edit the post without supplying a post_thumbnail and check that it didn't change. $post3 = array( 'post_content' => 'Updated post' ); $result = $this->myxmlrpcserver->mw_editPost( array( $post_id, 'author', 'author', $post3 ) ); $this->assertNotIXRError( $result ); - $this->assertEquals( $attachment_id, get_post_meta( $post_id, '_thumbnail_id', true ) ); + $this->assertSame( (string) $attachment_id, get_post_meta( $post_id, '_thumbnail_id', true ) ); // Create another attachment. $attachment2_id = self::factory()->attachment->create_upload_object( $filename, $post_id ); @@ -171,7 +171,7 @@ public function test_post_thumbnail() { $post4 = array( 'wp_post_thumbnail' => $attachment2_id ); $result = $this->myxmlrpcserver->mw_editPost( array( $post_id, 'author', 'author', $post4 ) ); $this->assertNotIXRError( $result ); - $this->assertEquals( $attachment2_id, get_post_meta( $post_id, '_thumbnail_id', true ) ); + $this->assertSame( (string) $attachment2_id, get_post_meta( $post_id, '_thumbnail_id', true ) ); // Unset the post's post_thumbnail. $post5 = array( 'wp_post_thumbnail' => '' ); diff --git a/tests/phpunit/tests/xmlrpc/mw/newPost.php b/tests/phpunit/tests/xmlrpc/mw/newPost.php index 3637d28536475..e7c4af0cee01f 100644 --- a/tests/phpunit/tests/xmlrpc/mw/newPost.php +++ b/tests/phpunit/tests/xmlrpc/mw/newPost.php @@ -49,7 +49,8 @@ public function test_ignore_id() { ); $result = $this->myxmlrpcserver->mw_newPost( array( 1, 'author', 'author', $post ) ); $this->assertNotIXRError( $result ); - $this->assertNotEquals( '103948', $result ); + $this->assertIsString( $result ); + $this->assertNotSame( '103948', $result ); } public function test_capable_publish() { @@ -124,7 +125,7 @@ public function test_empty_author() { $this->assertStringMatchesFormat( '%d', $result ); $out = get_post( $result ); - $this->assertEquals( $my_author_id, $out->post_author ); + $this->assertSame( (string) $my_author_id, $out->post_author ); $this->assertSame( 'Test', $out->post_title ); } @@ -146,7 +147,7 @@ public function test_post_thumbnail() { ); $result = $this->myxmlrpcserver->mw_newPost( array( 1, 'author', 'author', $post ) ); $this->assertNotIXRError( $result ); - $this->assertEquals( $attachment_id, get_post_meta( $result, '_thumbnail_id', true ) ); + $this->assertSame( (string) $attachment_id, get_post_meta( $result, '_thumbnail_id', true ) ); remove_theme_support( 'post-thumbnails' ); } diff --git a/tests/phpunit/tests/xmlrpc/wp/editPost.php b/tests/phpunit/tests/xmlrpc/wp/editPost.php index b5f27b85488d8..dacd64573a6d5 100644 --- a/tests/phpunit/tests/xmlrpc/wp/editPost.php +++ b/tests/phpunit/tests/xmlrpc/wp/editPost.php @@ -88,7 +88,7 @@ public function test_capable_reassign_author() { $this->assertTrue( $result ); $out = get_post( $post_id ); - $this->assertEquals( $author_id, $out->post_author ); + $this->assertSame( (string) $author_id, $out->post_author ); } public function test_incapable_reassign_author() { @@ -107,7 +107,7 @@ public function test_incapable_reassign_author() { $this->assertSame( 401, $result->code ); $out = get_post( $post_id ); - $this->assertEquals( $contributor_id, $out->post_author ); + $this->assertSame( (string) $contributor_id, $out->post_author ); } /** @@ -129,7 +129,7 @@ public function test_capable_reassign_author_to_self() { $this->assertTrue( $result ); $out = get_post( $post_id ); - $this->assertEquals( $editor_id, $out->post_author ); + $this->assertSame( (string) $editor_id, $out->post_author ); } /** @@ -156,20 +156,20 @@ public function test_post_thumbnail() { $post2 = array( 'post_thumbnail' => $attachment_id ); $result = $this->myxmlrpcserver->wp_editPost( array( 1, 'author', 'author', $post_id, $post2 ) ); $this->assertNotIXRError( $result ); - $this->assertEquals( $attachment_id, get_post_meta( $post_id, '_thumbnail_id', true ) ); + $this->assertSame( (string) $attachment_id, get_post_meta( $post_id, '_thumbnail_id', true ) ); // Fetch the post to verify that it appears. $result = $this->myxmlrpcserver->wp_getPost( array( 1, 'author', 'author', $post_id ) ); $this->assertNotIXRError( $result ); $this->assertArrayHasKey( 'post_thumbnail', $result ); $this->assertIsArray( $result['post_thumbnail'] ); - $this->assertEquals( $attachment_id, $result['post_thumbnail']['attachment_id'] ); + $this->assertSame( (string) $attachment_id, $result['post_thumbnail']['attachment_id'] ); // Edit the post without supplying a post_thumbnail and check that it didn't change. $post3 = array( 'post_content' => 'Updated post' ); $result = $this->myxmlrpcserver->wp_editPost( array( 1, 'author', 'author', $post_id, $post3 ) ); $this->assertNotIXRError( $result ); - $this->assertEquals( $attachment_id, get_post_meta( $post_id, '_thumbnail_id', true ) ); + $this->assertSame( (string) $attachment_id, get_post_meta( $post_id, '_thumbnail_id', true ) ); // Create another attachment. $attachment2_id = self::factory()->attachment->create_upload_object( $filename, $post_id ); @@ -178,7 +178,7 @@ public function test_post_thumbnail() { $post4 = array( 'post_thumbnail' => $attachment2_id ); $result = $this->myxmlrpcserver->wp_editPost( array( 1, 'author', 'author', $post_id, $post4 ) ); $this->assertNotIXRError( $result ); - $this->assertEquals( $attachment2_id, get_post_meta( $post_id, '_thumbnail_id', true ) ); + $this->assertSame( (string) $attachment2_id, get_post_meta( $post_id, '_thumbnail_id', true ) ); // Unset the post's post_thumbnail. $post5 = array( 'post_thumbnail' => '' ); diff --git a/tests/phpunit/tests/xmlrpc/wp/editProfile.php b/tests/phpunit/tests/xmlrpc/wp/editProfile.php index 2789dbe460095..579f82c33fceb 100644 --- a/tests/phpunit/tests/xmlrpc/wp/editProfile.php +++ b/tests/phpunit/tests/xmlrpc/wp/editProfile.php @@ -64,6 +64,6 @@ public function test_ignore_email_change() { $this->assertTrue( $result ); $user_data = get_userdata( $editor_id ); - $this->assertNotEquals( $new_email, $user_data->email ); + $this->assertNotSame( $new_email, $user_data->user_email ); } } diff --git a/tests/phpunit/tests/xmlrpc/wp/editTerm.php b/tests/phpunit/tests/xmlrpc/wp/editTerm.php index fbc310ac7ea4f..0f6d9cf891e2e 100644 --- a/tests/phpunit/tests/xmlrpc/wp/editTerm.php +++ b/tests/phpunit/tests/xmlrpc/wp/editTerm.php @@ -190,7 +190,7 @@ public function test_parent_null() { $this->assertIsBool( $result ); $term = get_term( self::$child_term, 'category' ); - $this->assertEquals( '0', $term->parent ); + $this->assertSame( 0, $term->parent ); } public function test_parent_invalid() { diff --git a/tests/phpunit/tests/xmlrpc/wp/getComment.php b/tests/phpunit/tests/xmlrpc/wp/getComment.php index 08cd4a5b00174..1eb64c23ec8c6 100644 --- a/tests/phpunit/tests/xmlrpc/wp/getComment.php +++ b/tests/phpunit/tests/xmlrpc/wp/getComment.php @@ -74,10 +74,10 @@ public function test_valid_comment() { $this->assertStringMatchesFormat( '%d', $result['comment_id'] ); $this->assertStringMatchesFormat( '%d', $result['parent'] ); $this->assertStringMatchesFormat( '%d', $result['post_id'] ); - $this->assertEquals( self::$parent_comment_id, $result['comment_id'] ); - $this->assertEquals( 0, $result['parent'] ); + $this->assertSame( (string) self::$parent_comment_id, $result['comment_id'] ); + $this->assertSame( '0', $result['parent'] ); $this->assertSame( self::$parent_comment_data['comment_content'], $result['content'] ); - $this->assertEquals( self::$post_id, $result['post_id'] ); + $this->assertSame( (string) self::$post_id, $result['post_id'] ); $this->assertSame( self::$parent_comment_data['comment_author'], $result['author'] ); $this->assertSame( self::$parent_comment_data['comment_author_url'], $result['author_url'] ); $this->assertSame( self::$parent_comment_data['comment_author_email'], $result['author_email'] ); @@ -89,8 +89,8 @@ public function test_valid_child_comment() { $result = $this->myxmlrpcserver->wp_getComment( array( 1, 'editor', 'editor', self::$child_comment_id ) ); $this->assertNotIXRError( $result ); - $this->assertEquals( self::$child_comment_id, $result['comment_id'] ); - $this->assertEquals( self::$parent_comment_id, $result['parent'] ); + $this->assertSame( (string) self::$child_comment_id, $result['comment_id'] ); + $this->assertSame( (string) self::$parent_comment_id, $result['parent'] ); } public function test_invalid_id() { diff --git a/tests/phpunit/tests/xmlrpc/wp/getComments.php b/tests/phpunit/tests/xmlrpc/wp/getComments.php index 606f9e0e855cf..acd131a1eef10 100644 --- a/tests/phpunit/tests/xmlrpc/wp/getComments.php +++ b/tests/phpunit/tests/xmlrpc/wp/getComments.php @@ -56,7 +56,7 @@ public function test_post_filter() { $this->assertNotEmpty( $results ); foreach ( $results as $result ) { - $this->assertEquals( $this->post_id, $result['post_id'] ); + $this->assertSame( (string) $this->post_id, $result['post_id'] ); } } diff --git a/tests/phpunit/tests/xmlrpc/wp/getPost.php b/tests/phpunit/tests/xmlrpc/wp/getPost.php index 72a0685a8a11a..8f2e28b5fd6ae 100644 --- a/tests/phpunit/tests/xmlrpc/wp/getPost.php +++ b/tests/phpunit/tests/xmlrpc/wp/getPost.php @@ -72,9 +72,9 @@ public function test_valid_post() { $this->assertSame( $this->post_data['post_excerpt'], $result['post_excerpt'] ); $this->assertSame( $this->post_data['post_content'], $result['post_content'] ); $this->assertSame( url_to_postid( $result['link'] ), $this->post_id ); - $this->assertEquals( $this->post_custom_field['id'], $result['custom_fields'][0]['id'] ); + $this->assertSame( (string) $this->post_custom_field['id'], $result['custom_fields'][0]['id'] ); $this->assertSame( $this->post_custom_field['key'], $result['custom_fields'][0]['key'] ); - $this->assertEquals( $this->post_custom_field['value'], $result['custom_fields'][0]['value'] ); + $this->assertSame( (string) $this->post_custom_field['value'], $result['custom_fields'][0]['value'] ); remove_theme_support( 'post-thumbnails' ); } @@ -144,7 +144,7 @@ public function test_valid_page() { $this->assertIsString( $result['post_mime_type'] ); $this->assertSame( 'page', $result['post_type'] ); - $this->assertEquals( $parent_page_id, $result['post_parent'] ); + $this->assertSame( (string) $parent_page_id, $result['post_parent'] ); $this->assertSame( 2, $result['menu_order'] ); } diff --git a/tests/phpunit/tests/xmlrpc/wp/getPosts.php b/tests/phpunit/tests/xmlrpc/wp/getPosts.php index b1ab560886eb9..4ac3c46ab6069 100644 --- a/tests/phpunit/tests/xmlrpc/wp/getPosts.php +++ b/tests/phpunit/tests/xmlrpc/wp/getPosts.php @@ -120,7 +120,7 @@ public function test_filters() { $results3 = $this->myxmlrpcserver->wp_getPosts( array( 1, 'editor', 'editor', $filter3 ) ); $this->assertNotIXRError( $results3 ); $this->assertCount( 1, $results3 ); - $this->assertEquals( $post->ID, $results3[0]['post_id'] ); + $this->assertSame( (string) $post->ID, $results3[0]['post_id'] ); _unregister_post_type( $cpt_name ); } diff --git a/tests/phpunit/tests/xmlrpc/wp/getProfile.php b/tests/phpunit/tests/xmlrpc/wp/getProfile.php index c9325ade3d670..60122d84769db 100644 --- a/tests/phpunit/tests/xmlrpc/wp/getProfile.php +++ b/tests/phpunit/tests/xmlrpc/wp/getProfile.php @@ -17,7 +17,7 @@ public function test_subscriber() { $result = $this->myxmlrpcserver->wp_getProfile( array( 1, 'subscriber', 'subscriber' ) ); $this->assertNotIXRError( $result ); - $this->assertEquals( $subscriber_id, $result['user_id'] ); + $this->assertSame( (string) $subscriber_id, $result['user_id'] ); $this->assertContains( 'subscriber', $result['roles'] ); } @@ -26,7 +26,7 @@ public function test_administrator() { $result = $this->myxmlrpcserver->wp_getProfile( array( 1, 'administrator', 'administrator' ) ); $this->assertNotIXRError( $result ); - $this->assertEquals( $administrator_id, $result['user_id'] ); + $this->assertSame( (string) $administrator_id, $result['user_id'] ); $this->assertContains( 'administrator', $result['roles'] ); } @@ -37,7 +37,7 @@ public function test_arbitrary_fields() { $result = $this->myxmlrpcserver->wp_getProfile( array( 1, 'editor', 'editor', $fields ) ); $this->assertNotIXRError( $result ); - $this->assertEquals( $editor_id, $result['user_id'] ); + $this->assertSame( (string) $editor_id, $result['user_id'] ); $expected_fields = array( 'user_id', 'email', 'bio' ); $keys = array_keys( $result ); diff --git a/tests/phpunit/tests/xmlrpc/wp/getTerm.php b/tests/phpunit/tests/xmlrpc/wp/getTerm.php index 7eb1d3e2e4aff..c6ebe2645e449 100644 --- a/tests/phpunit/tests/xmlrpc/wp/getTerm.php +++ b/tests/phpunit/tests/xmlrpc/wp/getTerm.php @@ -76,7 +76,12 @@ public function test_valid_term() { $result = $this->myxmlrpcserver->wp_getTerm( array( 1, 'editor', 'editor', 'category', self::$term_id ) ); $this->assertNotIXRError( $result ); - $this->assertEquals( $result, $term ); + /* + * This comparison stays loose: wp.getTerm returns the IDs as strings so that they + * cannot exceed what an XML-RPC integer can describe, while get_term() returns them + * as integers. The individual types are asserted below. + */ + $this->assertEquals( $term, $result ); // Check data types. $this->assertIsString( $result['name'] ); @@ -86,6 +91,10 @@ public function test_valid_term() { $this->assertIsInt( $result['count'] ); // We expect all ID's to be strings not integers so we don't return something larger than an XMLRPC integer can describe. + $this->assertIsString( $result['term_id'] ); + $this->assertIsString( $result['term_group'] ); + $this->assertIsString( $result['term_taxonomy_id'] ); + $this->assertIsString( $result['parent'] ); $this->assertStringMatchesFormat( '%d', $result['term_id'] ); $this->assertStringMatchesFormat( '%d', $result['term_group'] ); $this->assertStringMatchesFormat( '%d', $result['term_taxonomy_id'] ); diff --git a/tests/phpunit/tests/xmlrpc/wp/getTerms.php b/tests/phpunit/tests/xmlrpc/wp/getTerms.php index d538a4efd2b8e..729a1e6b4ad2f 100644 --- a/tests/phpunit/tests/xmlrpc/wp/getTerms.php +++ b/tests/phpunit/tests/xmlrpc/wp/getTerms.php @@ -143,7 +143,7 @@ public function test_terms_search() { $this->assertNotIXRError( $results ); $this->assertCount( 1, $results ); $this->assertSame( $name, $results[0]['name'] ); - $this->assertEquals( $name_id, $results[0]['term_id'] ); + $this->assertSame( (string) $name_id, $results[0]['term_id'] ); // Search by partial name. $filter = array( 'search' => substr( $name, 0, 10 ) ); @@ -151,6 +151,6 @@ public function test_terms_search() { $this->assertNotIXRError( $results2 ); $this->assertCount( 1, $results2 ); $this->assertSame( $name, $results2[0]['name'] ); - $this->assertEquals( $name_id, $results2[0]['term_id'] ); + $this->assertSame( (string) $name_id, $results2[0]['term_id'] ); } } diff --git a/tests/phpunit/tests/xmlrpc/wp/getUser.php b/tests/phpunit/tests/xmlrpc/wp/getUser.php index 8cfb34ae3e7eb..ca7a6bb6b1ba9 100644 --- a/tests/phpunit/tests/xmlrpc/wp/getUser.php +++ b/tests/phpunit/tests/xmlrpc/wp/getUser.php @@ -43,7 +43,7 @@ public function test_subscriber_self() { $result = $this->myxmlrpcserver->wp_getUser( array( 1, 'subscriber', 'subscriber', $subscriber_id ) ); $this->assertNotIXRError( $result ); - $this->assertEquals( $subscriber_id, $result['user_id'] ); + $this->assertSame( (string) $subscriber_id, $result['user_id'] ); } public function test_valid_user() { @@ -83,7 +83,7 @@ public function test_valid_user() { $this->assertIsArray( $result['roles'] ); // Check expected values. - $this->assertEquals( $user_id, $result['user_id'] ); + $this->assertSame( (string) $user_id, $result['user_id'] ); $this->assertSame( $user_data['user_login'], $result['username'] ); $this->assertSame( $user_data['first_name'], $result['first_name'] ); $this->assertSame( $user_data['last_name'], $result['last_name'] ); @@ -105,7 +105,7 @@ public function test_no_fields() { $result = $this->myxmlrpcserver->wp_getUser( array( 1, 'administrator', 'administrator', $editor_id, array() ) ); $this->assertNotIXRError( $result ); - $this->assertEquals( $editor_id, $result['user_id'] ); + $this->assertSame( (string) $editor_id, $result['user_id'] ); $expected_fields = array( 'user_id' ); $this->assertSame( $expected_fields, array_keys( $result ) ); @@ -116,7 +116,7 @@ public function test_basic_fields() { $result = $this->myxmlrpcserver->wp_getUser( array( 1, 'administrator', 'administrator', $editor_id, array( 'basic' ) ) ); $this->assertNotIXRError( $result ); - $this->assertEquals( $editor_id, $result['user_id'] ); + $this->assertSame( (string) $editor_id, $result['user_id'] ); $expected_fields = array( 'user_id', 'username', 'email', 'registered', 'display_name', 'nicename' ); $keys = array_keys( $result ); @@ -132,7 +132,7 @@ public function test_arbitrary_fields() { $result = $this->myxmlrpcserver->wp_getUser( array( 1, 'administrator', 'administrator', $editor_id, $fields ) ); $this->assertNotIXRError( $result ); - $this->assertEquals( $editor_id, $result['user_id'] ); + $this->assertSame( (string) $editor_id, $result['user_id'] ); $expected_fields = array( 'user_id', 'email', 'bio' ); $keys = array_keys( $result ); diff --git a/tests/phpunit/tests/xmlrpc/wp/getUsers.php b/tests/phpunit/tests/xmlrpc/wp/getUsers.php index a0eeee4026645..a442ad4969d92 100644 --- a/tests/phpunit/tests/xmlrpc/wp/getUsers.php +++ b/tests/phpunit/tests/xmlrpc/wp/getUsers.php @@ -70,7 +70,7 @@ public function test_role_filter() { $results = $this->myxmlrpcserver->wp_getUsers( array( 1, 'administrator', 'administrator', $filter ) ); $this->assertNotIXRError( $results ); $this->assertCount( 1, $results ); - $this->assertEquals( $editor_id, $results[0]['user_id'] ); + $this->assertSame( (string) $editor_id, $results[0]['user_id'] ); // Test 'authors', which should return all non-subscribers. $filter2 = array( 'who' => 'authors' ); diff --git a/tests/phpunit/tests/xmlrpc/wp/newPost.php b/tests/phpunit/tests/xmlrpc/wp/newPost.php index b98b06c01d55b..c6386a1f23d5b 100644 --- a/tests/phpunit/tests/xmlrpc/wp/newPost.php +++ b/tests/phpunit/tests/xmlrpc/wp/newPost.php @@ -46,7 +46,8 @@ public function test_ignore_id() { ); $result = $this->myxmlrpcserver->wp_newPost( array( 1, 'author', 'author', $post ) ); $this->assertNotIXRError( $result ); - $this->assertNotEquals( '103948', $result ); + $this->assertIsString( $result ); + $this->assertNotSame( '103948', $result ); } public function test_capable_publish() { @@ -141,7 +142,7 @@ public function test_empty_author() { $this->assertStringMatchesFormat( '%d', $result ); $out = get_post( $result ); - $this->assertEquals( $my_author_id, $out->post_author ); + $this->assertSame( (string) $my_author_id, $out->post_author ); $this->assertSame( 'Test', $out->post_title ); } @@ -163,7 +164,7 @@ public function test_post_thumbnail() { ); $result = $this->myxmlrpcserver->wp_newPost( array( 1, 'author', 'author', $post ) ); $this->assertNotIXRError( $result ); - $this->assertEquals( $attachment_id, get_post_meta( $result, '_thumbnail_id', true ) ); + $this->assertSame( (string) $attachment_id, get_post_meta( $result, '_thumbnail_id', true ) ); remove_theme_support( 'post-thumbnails' ); } From 81e3c7f291036dbe3e8a31057e6620180542fe19 Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Sat, 12 Sep 2026 23:54:44 +0000 Subject: [PATCH 490/634] Code Modernization: Use the null coalescing assignment operator for query variable defaults. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the “assign a default only if not already set” guard blocks in `WP_Query`, `WP_Tax_Query`, `WP_Date_Query` and `WP_Metadata_Lazyloader` with the null coalescing assignment operator (`??=`). Follow-up to r63443, r63501, r63509, r63541. Props Soean, mukesh27. See #65823. git-svn-id: https://develop.svn.wordpress.org/trunk@63607 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/class-wp-date-query.php | 4 +- .../class-wp-metadata-lazyloader.php | 8 +-- src/wp-includes/class-wp-query.php | 58 +++++-------------- src/wp-includes/class-wp-tax-query.php | 9 +-- 4 files changed, 20 insertions(+), 59 deletions(-) diff --git a/src/wp-includes/class-wp-date-query.php b/src/wp-includes/class-wp-date-query.php index 4a6e6ca2ed426..abfacce6cdde8 100644 --- a/src/wp-includes/class-wp-date-query.php +++ b/src/wp-includes/class-wp-date-query.php @@ -784,9 +784,7 @@ protected function get_sql_for_clause( $query, $parent_query ) { if ( isset( $query['hour'] ) || isset( $query['minute'] ) || isset( $query['second'] ) ) { // Avoid notices. foreach ( array( 'hour', 'minute', 'second' ) as $unit ) { - if ( ! isset( $query[ $unit ] ) ) { - $query[ $unit ] = null; - } + $query[ $unit ] ??= null; } $time_query = $this->build_time_query( $column, $compare, $query['hour'], $query['minute'], $query['second'] ); diff --git a/src/wp-includes/class-wp-metadata-lazyloader.php b/src/wp-includes/class-wp-metadata-lazyloader.php index f9c02391d2b1d..2725cbfee32c6 100644 --- a/src/wp-includes/class-wp-metadata-lazyloader.php +++ b/src/wp-includes/class-wp-metadata-lazyloader.php @@ -84,15 +84,11 @@ public function queue_objects( $object_type, $object_ids ) { $type_settings = $this->settings[ $object_type ]; - if ( ! isset( $this->pending_objects[ $object_type ] ) ) { - $this->pending_objects[ $object_type ] = array(); - } + $this->pending_objects[ $object_type ] ??= array(); foreach ( $object_ids as $object_id ) { // Keyed by ID for faster lookup. - if ( ! isset( $this->pending_objects[ $object_type ][ $object_id ] ) ) { - $this->pending_objects[ $object_type ][ $object_id ] = 1; - } + $this->pending_objects[ $object_type ][ $object_id ] ??= 1; } add_filter( $type_settings['filter'], $type_settings['callback'], 10, 5 ); diff --git a/src/wp-includes/class-wp-query.php b/src/wp-includes/class-wp-query.php index 1d6b652c5a610..2835da604bef5 100644 --- a/src/wp-includes/class-wp-query.php +++ b/src/wp-includes/class-wp-query.php @@ -618,9 +618,7 @@ public function fill_query_vars( $query_vars ) { ); foreach ( $keys as $key ) { - if ( ! isset( $query_vars[ $key ] ) ) { - $query_vars[ $key ] = ''; - } + $query_vars[ $key ] ??= ''; } $array_keys = array( @@ -643,9 +641,7 @@ public function fill_query_vars( $query_vars ) { ); foreach ( $array_keys as $key ) { - if ( ! isset( $query_vars[ $key ] ) ) { - $query_vars[ $key ] = array(); - } + $query_vars[ $key ] ??= array(); } return $query_vars; @@ -1279,10 +1275,8 @@ public function parse_tax_query( &$query_vars ) { } if ( ! empty( $query_vars['category__and'] ) && 1 === count( (array) $query_vars['category__and'] ) ) { - $query_vars['category__and'] = (array) $query_vars['category__and']; - if ( ! isset( $query_vars['category__in'] ) ) { - $query_vars['category__in'] = array(); - } + $query_vars['category__and'] = (array) $query_vars['category__and']; + $query_vars['category__in'] ??= array(); $query_vars['category__in'][] = absint( reset( $query_vars['category__and'] ) ); unset( $query_vars['category__and'] ); } @@ -1967,30 +1961,14 @@ public function get_posts() { ) ); - if ( ! isset( $query_vars['ignore_sticky_posts'] ) ) { - $query_vars['ignore_sticky_posts'] = $query_vars['caller_get_posts']; - } + $query_vars['ignore_sticky_posts'] ??= $query_vars['caller_get_posts']; } - if ( ! isset( $query_vars['ignore_sticky_posts'] ) ) { - $query_vars['ignore_sticky_posts'] = false; - } - - if ( ! isset( $query_vars['suppress_filters'] ) ) { - $query_vars['suppress_filters'] = false; - } - - if ( ! isset( $query_vars['cache_results'] ) ) { - $query_vars['cache_results'] = true; - } - - if ( ! isset( $query_vars['update_post_term_cache'] ) ) { - $query_vars['update_post_term_cache'] = true; - } - - if ( ! isset( $query_vars['update_menu_item_cache'] ) ) { - $query_vars['update_menu_item_cache'] = false; - } + $query_vars['ignore_sticky_posts'] ??= false; + $query_vars['suppress_filters'] ??= false; + $query_vars['cache_results'] ??= true; + $query_vars['update_post_term_cache'] ??= true; + $query_vars['update_menu_item_cache'] ??= false; if ( ! isset( $query_vars['lazy_load_term_meta'] ) ) { $query_vars['lazy_load_term_meta'] = $query_vars['update_post_term_cache']; @@ -1998,9 +1976,7 @@ public function get_posts() { $query_vars['update_post_term_cache'] = true; } - if ( ! isset( $query_vars['update_post_meta_cache'] ) ) { - $query_vars['update_post_meta_cache'] = true; - } + $query_vars['update_post_meta_cache'] ??= true; if ( ! isset( $query_vars['post_type'] ) ) { if ( $this->is_search ) { @@ -3322,9 +3298,7 @@ public function get_posts() { } if ( 'ids' === $query_vars['fields'] ) { - if ( null === $this->posts ) { - $this->posts = $wpdb->get_col( $this->request ); - } + $this->posts ??= $wpdb->get_col( $this->request ); /** @var int[] */ $this->posts = array_map( 'intval', $this->posts ); @@ -3345,9 +3319,7 @@ public function get_posts() { } if ( 'id=>parent' === $query_vars['fields'] ) { - if ( null === $this->posts ) { - $this->posts = $wpdb->get_results( $this->request ); - } + $this->posts ??= $wpdb->get_results( $this->request ); $this->post_count = count( $this->posts ); $this->set_found_posts( $query_vars, $limits ); @@ -5081,9 +5053,7 @@ protected function generate_cache_key( array $args, $sql ) { } // Add a default orderby value of date to ensure same cache key generation. - if ( ! isset( $args['orderby'] ) ) { - $args['orderby'] = 'date'; - } + $args['orderby'] ??= 'date'; $placeholder = $wpdb->placeholder_escape(); array_walk_recursive( diff --git a/src/wp-includes/class-wp-tax-query.php b/src/wp-includes/class-wp-tax-query.php index c6ec3258cc201..7e254b1275c9f 100644 --- a/src/wp-includes/class-wp-tax-query.php +++ b/src/wp-includes/class-wp-tax-query.php @@ -161,9 +161,8 @@ public function sanitize_query( $queries ) { */ if ( ! empty( $cleaned_clause['taxonomy'] ) && 'NOT IN' !== $cleaned_clause['operator'] ) { $taxonomy = $cleaned_clause['taxonomy']; - if ( ! isset( $this->queried_terms[ $taxonomy ] ) ) { - $this->queried_terms[ $taxonomy ] = array(); - } + + $this->queried_terms[ $taxonomy ] ??= array(); /* * Backward compatibility: Only store the first @@ -184,9 +183,7 @@ public function sanitize_query( $queries ) { if ( ! empty( $cleaned_subquery ) ) { // All queries with children must have a relation. - if ( ! isset( $cleaned_subquery['relation'] ) ) { - $cleaned_subquery['relation'] = 'AND'; - } + $cleaned_subquery['relation'] ??= 'AND'; $cleaned_query[] = $cleaned_subquery; } From c88f5157ae60afaaa90fa89bfc46f2fed8841f91 Mon Sep 17 00:00:00 2001 From: Lance Willett Date: Sun, 13 Sep 2026 16:21:34 +0000 Subject: [PATCH 491/634] Tests: Improve isolation of admin tests. Reset menu registries and plugin-dependency static properties before and after tests. Remove the temporary MU-plugin directory after its fixture files are deleted. Give list-table fixtures distinct screens and preserve whether the original hook suffix was set. Align the comments table's expected primary column with its declared default. Allow updater tests to load Composer dependencies outside the checkout while exercising open_basedir restrictions. Developed in: https://github.com/WordPress/wordpress-develop/pull/13181 Props jonsurrell, mindctrl. See #65893. git-svn-id: https://develop.svn.wordpress.org/trunk@63608 602fd350-edb4-49c9-b593-d223f7449a82 --- tests/phpunit/tests/admin/includesPlugin.php | 24 ++++++++++++++ .../tests/admin/plugin-dependencies/base.php | 18 ++++++++-- .../tests/admin/wpAutomaticUpdater.php | 31 ++++++++++++++--- tests/phpunit/tests/admin/wpListTable.php | 33 ++++++++++++------- 4 files changed, 88 insertions(+), 18 deletions(-) diff --git a/tests/phpunit/tests/admin/includesPlugin.php b/tests/phpunit/tests/admin/includesPlugin.php index 4d47fb7db0a81..21e3064ff6b55 100644 --- a/tests/phpunit/tests/admin/includesPlugin.php +++ b/tests/phpunit/tests/admin/includesPlugin.php @@ -12,6 +12,29 @@ class Tests_Admin_IncludesPlugin extends WP_UnitTestCase { */ public static $admin_id; + public function set_up() { + parent::set_up(); + $this->reset_menu_globals(); + } + + public function tear_down() { + $this->reset_menu_globals(); + parent::tear_down(); + } + + /** + * Resets the global menu registries modified by the menu API tests. + */ + private function reset_menu_globals() { + global $menu, $submenu, $admin_page_hooks, $_registered_pages, $_parent_pages; + + $menu = array(); + $submenu = array(); + $admin_page_hooks = array(); + $_registered_pages = array(); + $_parent_pages = array(); + } + public static function wpSetUpBeforeClass( $factory ) { self::$admin_id = $factory->user->create( array( 'role' => 'administrator' ) ); self::_back_up_mu_plugins(); @@ -501,6 +524,7 @@ public function test_get_mu_plugins_should_ignore_files_without_php_extensions() // Clean up. unlink( WPMU_PLUGIN_DIR . '/foo.php' ); unlink( WPMU_PLUGIN_DIR . '/bar.txt' ); + rmdir( WPMU_PLUGIN_DIR ); $this->assertSame( array( 'foo.php' ), array_keys( $found ) ); } diff --git a/tests/phpunit/tests/admin/plugin-dependencies/base.php b/tests/phpunit/tests/admin/plugin-dependencies/base.php index 22c509807b205..badd4cfe63c92 100644 --- a/tests/phpunit/tests/admin/plugin-dependencies/base.php +++ b/tests/phpunit/tests/admin/plugin-dependencies/base.php @@ -60,15 +60,29 @@ public static function tear_down_after_class() { parent::tear_down_after_class(); } + /** + * Resets all static properties to a default value before each test. + */ + public function set_up() { + parent::set_up(); + $this->reset_static_properties(); + } + /** * Resets all static properties to a default value after each test. */ public function tear_down() { + $this->reset_static_properties(); + parent::tear_down(); + } + + /** + * Resets all static properties to their default values. + */ + private function reset_static_properties() { foreach ( self::$static_properties as $name => $default_value ) { $this->set_property_value( $name, $default_value ); } - - parent::tear_down(); } /** diff --git a/tests/phpunit/tests/admin/wpAutomaticUpdater.php b/tests/phpunit/tests/admin/wpAutomaticUpdater.php index ee52f44daf9c1..2aca85616cb5f 100644 --- a/tests/phpunit/tests/admin/wpAutomaticUpdater.php +++ b/tests/phpunit/tests/admin/wpAutomaticUpdater.php @@ -40,6 +40,31 @@ public function set_up() { add_filter( 'pre_wp_mail', '__return_false' ); } + /** + * Builds an open_basedir value that allows PHPUnit to load Composer dependencies. + * + * Composer dependencies may live outside a secondary worktree, and PHPUnit can + * load assertion-related classes after the restriction is set. + * + * @param string $abspath_grandparent Directory containing the repository. + * @return string The open_basedir value. + */ + private function get_open_basedir_for_tests( $abspath_grandparent ) { + $composer_vendor_dir = dirname( + ( new ReflectionClass( Composer\Autoload\ClassLoader::class ) )->getFileName(), + 2 + ); + + return implode( + PATH_SEPARATOR, + array( + sys_get_temp_dir(), + wp_normalize_path( $abspath_grandparent ), + wp_normalize_path( $composer_vendor_dir ), + ) + ); + } + /** * Tests that `WP_Automatic_Updater::send_plugin_theme_email()` appends * plugin URLs. @@ -612,8 +637,7 @@ public function test_is_allowed_dir_should_return_true_if_open_basedir_is_set_an $abspath_grandparent = trailingslashit( dirname( $abspath_parent ) ); $open_basedir_backup = ini_get( 'open_basedir' ); - // Allow access to the directory one level above the repository. - ini_set( 'open_basedir', sys_get_temp_dir() . PATH_SEPARATOR . wp_normalize_path( $abspath_grandparent ) ); + ini_set( 'open_basedir', $this->get_open_basedir_for_tests( $abspath_grandparent ) ); // Checking an allowed directory should succeed. $actual = self::$updater->is_allowed_dir( wp_normalize_path( ABSPATH ) ); @@ -647,8 +671,7 @@ public function test_is_allowed_dir_should_return_false_if_open_basedir_is_set_a $abspath_grandparent = trailingslashit( dirname( $abspath_parent ) ); $open_basedir_backup = ini_get( 'open_basedir' ); - // Allow access to the directory one level above the repository. - ini_set( 'open_basedir', sys_get_temp_dir() . PATH_SEPARATOR . wp_normalize_path( $abspath_grandparent ) ); + ini_set( 'open_basedir', $this->get_open_basedir_for_tests( $abspath_grandparent ) ); // Checking a directory not within the allowed path should trigger an `open_basedir` warning. $actual = self::$updater->is_allowed_dir( '/.git' ); diff --git a/tests/phpunit/tests/admin/wpListTable.php b/tests/phpunit/tests/admin/wpListTable.php index b3de66659b308..ebaafc62beb20 100644 --- a/tests/phpunit/tests/admin/wpListTable.php +++ b/tests/phpunit/tests/admin/wpListTable.php @@ -17,14 +17,22 @@ class Tests_Admin_WpListTable extends WP_UnitTestCase { /** * Original value of $GLOBALS['hook_suffix']. * - * @var string + * @var string|null */ private static $original_hook_suffix; + /** + * Whether $GLOBALS['hook_suffix'] existed before the test class ran. + * + * @var bool + */ + private static $hook_suffix_was_set; + public static function set_up_before_class() { parent::set_up_before_class(); - static::$original_hook_suffix = $GLOBALS['hook_suffix']; + static::$hook_suffix_was_set = array_key_exists( 'hook_suffix', $GLOBALS ); + static::$original_hook_suffix = $GLOBALS['hook_suffix'] ?? null; require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php'; } @@ -37,8 +45,12 @@ public function set_up() { } public function clean_up_global_scope() { - global $hook_suffix; - $hook_suffix = static::$original_hook_suffix; + if ( static::$hook_suffix_was_set ) { + $GLOBALS['hook_suffix'] = static::$original_hook_suffix; + } else { + unset( $GLOBALS['hook_suffix'] ); + } + parent::clean_up_global_scope(); } @@ -61,13 +73,10 @@ public function test_should_only_add_primary_column_when_needed( $list_class, $h $hook = new MockAction(); add_filter( 'list_table_primary_column', array( $hook, 'filter' ) ); - /* - * Set a dummy value for the current screen in the admin to prevent - * `_get_list_table()` throwing. - */ - $GLOBALS['hook_suffix'] = 'my-hook'; - - $list_table = _get_list_table( $list_class ); + $list_table = _get_list_table( + $list_class, + array( 'screen' => 'wp-list-table-test-' . sanitize_key( $list_class ) ) + ); $column_headers = new ReflectionProperty( $list_table, '_column_headers' ); if ( PHP_VERSION_ID < 80100 ) { @@ -97,7 +106,7 @@ public function data_should_only_add_primary_column_when_needed() { */ $list_primary_columns = array( 'WP_Application_Passwords_List_Table' => 'name', - 'WP_Comments_List_Table' => 'author', + 'WP_Comments_List_Table' => 'comment', 'WP_Links_List_Table' => 'name', 'WP_Media_List_Table' => 'title', 'WP_MS_Sites_List_Table' => 'blogname', From c141ea30eba0402931c0f9ba90190db72101b1af Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Sun, 13 Sep 2026 23:46:12 +0000 Subject: [PATCH 492/634] Code Modernization: Use the null coalescing operator in `wp_get_chromium_major_version()` tests. `Tests_Media_wpGetChromiumMajorVersion::set_up()` stores the original `$_SERVER['HTTP_USER_AGENT']` value using an `isset()` ternary that repeats the array access. This replaces it with the null coalescing operator, which is shorter and expresses the same intent. The null coalescing operator is available since PHP 7.0, and WordPress requires PHP 7.4 or later, so no compatibility concerns apply. It is already used widely across the codebase, so this makes the style more consistent. Developed in https://github.com/WordPress/wordpress-develop/pull/13469. Follow-up to r62428. Props Soean, mukesh27. See #65819. git-svn-id: https://develop.svn.wordpress.org/trunk@63609 602fd350-edb4-49c9-b593-d223f7449a82 --- tests/phpunit/tests/media/wpGetChromiumMajorVersion.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/media/wpGetChromiumMajorVersion.php b/tests/phpunit/tests/media/wpGetChromiumMajorVersion.php index 7249d9b91b665..eb03985116451 100644 --- a/tests/phpunit/tests/media/wpGetChromiumMajorVersion.php +++ b/tests/phpunit/tests/media/wpGetChromiumMajorVersion.php @@ -17,7 +17,7 @@ class Tests_Media_wpGetChromiumMajorVersion extends WP_UnitTestCase { public function set_up() { parent::set_up(); - $this->original_user_agent = isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : null; + $this->original_user_agent = $_SERVER['HTTP_USER_AGENT'] ?? null; } public function tear_down() { From ce1aa14a3a94550e95a660edb38499160573a8f0 Mon Sep 17 00:00:00 2001 From: ramonopoly Date: Mon, 14 Sep 2026 01:50:28 +0000 Subject: [PATCH 493/634] Editor: Retain responsive styles in block style variation partials MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Responsive `@tablet` and `@mobile` styles were silently dropped from block style variations declared in a standalone JSON partial in a theme's `styles/` directory. This commit adds the responsive breakpoint states to the top-level styles schema, mirroring what the block style variation branch already does. This restores the parity to the two schemas. Developed in: https://github.com/WordPress/wordpress-develop/pull/13325 Props adamsilverstein, andraganescu, andrewserong, firdaus666, mitgiselle, pbiron, ramonopoly, talldanwp. Fixes #65992. git-svn-id: https://develop.svn.wordpress.org/trunk@63610 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/class-wp-theme-json.php | 44 ++- .../styles/block-style-variation-pseudo.json | 26 ++ .../block-style-variation-responsive.json | 21 ++ .../block-supports/block-style-variations.php | 299 ++++++++++++++++++ .../tests/theme/wpThemeJsonResolver.php | 49 +++ 5 files changed, 438 insertions(+), 1 deletion(-) create mode 100644 tests/phpunit/data/themedir1/block-theme/styles/block-style-variation-pseudo.json create mode 100644 tests/phpunit/data/themedir1/block-theme/styles/block-style-variation-responsive.json diff --git a/src/wp-includes/class-wp-theme-json.php b/src/wp-includes/class-wp-theme-json.php index e91d547eb58f1..fb41bde81aa8c 100644 --- a/src/wp-includes/class-wp-theme-json.php +++ b/src/wp-includes/class-wp-theme-json.php @@ -1266,6 +1266,8 @@ protected static function do_opt_in_into_settings( &$context ) { * @since 5.9.0 Added the `$valid_block_names` and `$valid_element_name` parameters. * @since 6.3.0 Added the `$valid_variations` parameter. * @since 6.6.0 Updated schema to allow extended block style variations. + * @since 7.1.1 Updated schema to allow responsive breakpoint states and pseudo-selectors + * at the top level of `styles` for block style variation partials. * * @param array $input Structure to sanitize. * @param array $valid_block_names List of valid block names. @@ -1427,7 +1429,6 @@ protected static function sanitize( $input, $valid_block_names, $valid_element_n foreach ( array_keys( $responsive_media_queries ) as $breakpoint_state ) { $variation_schema[ $breakpoint_state ] = $styles_non_top_level; $variation_schema[ $breakpoint_state ]['elements'] = $schema_styles_elements; - $variation_schema[ $breakpoint_state ]['blocks'] = $schema_styles_blocks; if ( isset( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block ] ) ) { foreach ( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block ] as $pseudo_selector ) { @@ -1457,6 +1458,47 @@ protected static function sanitize( $input, $valid_block_names, $valid_element_n $schema['settings']['blocks'] = $schema_settings_blocks; $schema['settings']['typography']['fontFamilies'] = static::schema_in_root_and_per_origin( static::FONT_FAMILY_SCHEMA ); + /* + * Add block style variation states to the top-level styles schema. + * + * Block style variations defined in a standalone JSON partial within a + * theme's `styles` directory declare their styles at the root of the + * `styles` object, so they are sanitized against the top-level schema. + * It needs to allow the same states that are allowed for variations + * declared inline in theme.json, otherwise those states are silently + * removed as unknown keys. + * + * The `blockTypes` property is only present on block style variation + * partials, so it both identifies the config as a variation and + * determines which pseudo-selectors are valid for it. Regular + * theme.json files are unaffected. + */ + if ( ! empty( $input['blockTypes'] ) && is_array( $input['blockTypes'] ) ) { + $variation_pseudo_selectors = array(); + foreach ( $input['blockTypes'] as $variation_block_type ) { + if ( isset( static::VALID_BLOCK_PSEUDO_SELECTORS[ $variation_block_type ] ) ) { + $variation_pseudo_selectors = array_merge( + $variation_pseudo_selectors, + static::VALID_BLOCK_PSEUDO_SELECTORS[ $variation_block_type ] + ); + } + } + $variation_pseudo_selectors = array_unique( $variation_pseudo_selectors ); + + foreach ( array_keys( $responsive_media_queries ) as $breakpoint_state ) { + $schema['styles'][ $breakpoint_state ] = $styles_non_top_level; + $schema['styles'][ $breakpoint_state ]['elements'] = $schema_styles_elements; + + foreach ( $variation_pseudo_selectors as $pseudo_selector ) { + $schema['styles'][ $breakpoint_state ][ $pseudo_selector ] = $styles_non_top_level; + } + } + + foreach ( $variation_pseudo_selectors as $pseudo_selector ) { + $schema['styles'][ $pseudo_selector ] = $styles_non_top_level; + } + } + // Remove anything that's not present in the schema. foreach ( array( 'styles', 'settings' ) as $subtree ) { if ( ! isset( $input[ $subtree ] ) ) { diff --git a/tests/phpunit/data/themedir1/block-theme/styles/block-style-variation-pseudo.json b/tests/phpunit/data/themedir1/block-theme/styles/block-style-variation-pseudo.json new file mode 100644 index 0000000000000..14962fd679f9b --- /dev/null +++ b/tests/phpunit/data/themedir1/block-theme/styles/block-style-variation-pseudo.json @@ -0,0 +1,26 @@ +{ + "version": 3, + "blockTypes": [ "core/navigation-link" ], + "slug": "pseudo-variation", + "title": "Pseudo Variation", + "styles": { + "color": { + "text": "red" + }, + ":hover": { + "color": { + "text": "blue" + } + }, + "@tablet": { + "color": { + "text": "green" + }, + ":hover": { + "color": { + "text": "purple" + } + } + } + } +} diff --git a/tests/phpunit/data/themedir1/block-theme/styles/block-style-variation-responsive.json b/tests/phpunit/data/themedir1/block-theme/styles/block-style-variation-responsive.json new file mode 100644 index 0000000000000..ef1750251aee3 --- /dev/null +++ b/tests/phpunit/data/themedir1/block-theme/styles/block-style-variation-responsive.json @@ -0,0 +1,21 @@ +{ + "version": 3, + "blockTypes": [ "core/preformatted" ], + "slug": "responsive-variation", + "title": "Responsive Variation", + "styles": { + "typography": { + "fontSize": "40px" + }, + "@tablet": { + "typography": { + "fontSize": "28px" + } + }, + "@mobile": { + "typography": { + "fontSize": "16px" + } + } + } +} diff --git a/tests/phpunit/tests/block-supports/block-style-variations.php b/tests/phpunit/tests/block-supports/block-style-variations.php index 0627820bd8d4d..3898178099e7e 100644 --- a/tests/phpunit/tests/block-supports/block-style-variations.php +++ b/tests/phpunit/tests/block-supports/block-style-variations.php @@ -247,6 +247,305 @@ public function test_block_style_variation_state_styles_use_custom_viewport_brea } } + /** + * Tests that responsive breakpoint styles defined in a standalone block style + * variation partial within a theme's `/styles` directory are preserved when + * the partial is sanitized. + * + * @ticket 65992 + * + * @covers WP_Theme_JSON_Resolver::get_style_variations + */ + public function test_block_style_variation_partial_retains_responsive_styles() { + switch_theme( 'block-theme' ); + + $variations = WP_Theme_JSON_Resolver::get_style_variations( 'block' ); + $actual = null; + + foreach ( $variations as $variation ) { + if ( isset( $variation['slug'] ) && 'responsive-variation' === $variation['slug'] ) { + $actual = $variation; + break; + } + } + + $this->assertNotNull( $actual, 'The responsive block style variation partial was not found.' ); + $this->assertSame( + array( 'fontSize' => '28px' ), + $actual['styles']['@tablet']['typography'] ?? null, + 'Tablet styles should be preserved when reading a block style variation partial.' + ); + $this->assertSame( + array( 'fontSize' => '16px' ), + $actual['styles']['@mobile']['typography'] ?? null, + 'Mobile styles should be preserved when reading a block style variation partial.' + ); + } + + /** + * Tests that responsive breakpoint styles defined in a standalone block style + * variation partial generate the expected media query CSS. + * + * @ticket 65992 + * + * @covers ::wp_render_block_style_variation_support_styles + */ + public function test_block_style_variation_partial_responsive_styles_generate_css() { + switch_theme( 'block-theme' ); + + try { + $parsed_block = array( + 'blockName' => 'core/preformatted', + 'attrs' => array( + 'className' => 'wp-block-preformatted is-style-responsive-variation', + ), + ); + + wp_render_block_style_variation_support_styles( $parsed_block ); + $inline_styles = wp_styles()->get_data( 'block-style-variation-styles', 'after' ); + $actual_stylesheet = is_array( $inline_styles ) ? implode( '', $inline_styles ) : ''; + + $this->assertStringContainsString( + '@media (480px < width <= 782px)', + $actual_stylesheet, + 'CSS should contain the tablet viewport media query.' + ); + $this->assertStringContainsString( + '@media (width <= 480px)', + $actual_stylesheet, + 'CSS should contain the mobile viewport media query.' + ); + } finally { + wp_deregister_style( 'block-style-variation-styles' ); + WP_Theme_JSON_Resolver::clean_cached_data(); + } + } + + /** + * Tests that pseudo-selector styles defined in a standalone block style + * variation partial are preserved when the partial is sanitized, both at + * the root of `styles` and within a responsive breakpoint state. + * + * @ticket 65992 + * + * @covers WP_Theme_JSON_Resolver::get_style_variations + */ + public function test_block_style_variation_partial_retains_pseudo_selector_styles() { + switch_theme( 'block-theme' ); + + $actual = null; + foreach ( WP_Theme_JSON_Resolver::get_style_variations( 'block' ) as $variation ) { + if ( isset( $variation['slug'] ) && 'pseudo-variation' === $variation['slug'] ) { + $actual = $variation; + break; + } + } + + $this->assertNotNull( $actual, 'The pseudo-selector block style variation partial was not found.' ); + $this->assertSame( + array( 'text' => 'blue' ), + $actual['styles'][':hover']['color'] ?? null, + 'Pseudo-selector styles should be preserved when reading a block style variation partial.' + ); + $this->assertSame( + array( 'text' => 'purple' ), + $actual['styles']['@tablet'][':hover']['color'] ?? null, + 'Pseudo-selector styles within a breakpoint state should be preserved.' + ); + } + + /** + * Tests that pseudo-selector styles defined in a standalone block style + * variation partial generate the expected CSS, including within a + * responsive breakpoint state. + * + * @ticket 65992 + * + * @covers ::wp_render_block_style_variation_support_styles + */ + public function test_block_style_variation_partial_pseudo_selector_styles_generate_css() { + switch_theme( 'block-theme' ); + + try { + $parsed_block = array( + 'blockName' => 'core/navigation-link', + 'attrs' => array( + 'className' => 'wp-block-navigation-link is-style-pseudo-variation', + ), + ); + + wp_render_block_style_variation_support_styles( $parsed_block ); + $inline_styles = wp_styles()->get_data( 'block-style-variation-styles', 'after' ); + $actual_stylesheet = is_array( $inline_styles ) ? implode( '', $inline_styles ) : ''; + + $this->assertStringContainsString( + ':hover', + $actual_stylesheet, + 'CSS should contain the pseudo-selector rule.' + ); + $this->assertStringContainsString( + 'blue', + $actual_stylesheet, + 'CSS should contain the pseudo-selector declaration value.' + ); + $this->assertStringContainsString( + 'purple', + $actual_stylesheet, + 'CSS should contain the pseudo-selector declaration value from the breakpoint state.' + ); + } finally { + wp_deregister_style( 'block-style-variation-styles' ); + WP_Theme_JSON_Resolver::clean_cached_data(); + } + } + + /** + * Tests that the block style variation states allowed at the root of a + * partial are not allowed at the root of a regular theme.json file, which + * has no `blockTypes` property. + * + * @ticket 65992 + * + * @covers WP_Theme_JSON::sanitize + */ + public function test_theme_json_root_styles_do_not_allow_variation_states() { + $theme_json = new WP_Theme_JSON( + array( + 'version' => WP_Theme_JSON::LATEST_SCHEMA, + 'styles' => array( + 'color' => array( 'text' => 'red' ), + '@tablet' => array( 'color' => array( 'text' => 'green' ) ), + ':hover' => array( 'color' => array( 'text' => 'blue' ) ), + ), + ) + ); + + $actual = $theme_json->get_raw_data()['styles']; + + $this->assertSame( + array( 'text' => 'red' ), + $actual['color'] ?? null, + 'Base root styles should be retained.' + ); + $this->assertArrayNotHasKey( + '@tablet', + $actual, + 'Responsive breakpoint states should not be allowed at the root of a regular theme.json.' + ); + $this->assertArrayNotHasKey( + ':hover', + $actual, + 'Pseudo-selectors should not be allowed at the root of a regular theme.json.' + ); + } + + /** + * Tests that `blocks` nested within a responsive breakpoint state is not + * retained for a block style variation partial, since that shape generates + * no CSS. The supported shape nests the breakpoint state within `blocks`. + * + * @ticket 65992 + * + * @covers WP_Theme_JSON::sanitize + */ + public function test_block_style_variation_partial_does_not_allow_blocks_within_breakpoint_state() { + $theme_json = new WP_Theme_JSON( + array( + 'version' => WP_Theme_JSON::LATEST_SCHEMA, + 'blockTypes' => array( 'core/group' ), + 'styles' => array( + 'blocks' => array( + 'core/heading' => array( + '@mobile' => array( + 'typography' => array( 'fontSize' => '18px' ), + ), + ), + ), + '@mobile' => array( + 'blocks' => array( + 'core/heading' => array( + 'typography' => array( 'fontSize' => '18px' ), + ), + ), + ), + ), + ) + ); + + $actual = $theme_json->get_raw_data()['styles']; + + $this->assertSame( + array( 'fontSize' => '18px' ), + $actual['blocks']['core/heading']['@mobile']['typography'] ?? null, + 'A breakpoint state nested within `blocks` should be retained.' + ); + $this->assertArrayNotHasKey( + 'blocks', + $actual['@mobile'] ?? array(), + '`blocks` nested within a breakpoint state should not be retained.' + ); + } + + /** + * Tests that `blocks` nested within a responsive breakpoint state is not + * retained for a block style variation declared inline in theme.json, + * matching the behaviour for variation partials. + * + * @ticket 65992 + * + * @covers WP_Theme_JSON::sanitize + */ + public function test_block_style_variation_does_not_allow_blocks_within_breakpoint_state() { + register_block_style( + 'core/group', + array( + 'name' => 'blocks-in-breakpoint', + 'label' => 'Blocks In Breakpoint', + ) + ); + + try { + $theme_json = new WP_Theme_JSON( + array( + 'version' => WP_Theme_JSON::LATEST_SCHEMA, + 'styles' => array( + 'blocks' => array( + 'core/group' => array( + 'variations' => array( + 'blocks-in-breakpoint' => array( + '@mobile' => array( + 'color' => array( 'text' => 'red' ), + 'blocks' => array( + 'core/heading' => array( + 'typography' => array( 'fontSize' => '18px' ), + ), + ), + ), + ), + ), + ), + ), + ), + ) + ); + + $variation = $theme_json->get_raw_data()['styles']['blocks']['core/group']['variations']['blocks-in-breakpoint'] ?? array(); + + $this->assertSame( + array( 'text' => 'red' ), + $variation['@mobile']['color'] ?? null, + 'Style properties within a breakpoint state should be retained.' + ); + $this->assertArrayNotHasKey( + 'blocks', + $variation['@mobile'] ?? array(), + '`blocks` nested within a breakpoint state should not be retained.' + ); + } finally { + unregister_block_style( 'core/group', 'blocks-in-breakpoint' ); + } + } + /** * Tests that block style variations resolve any `ref` values when generating styles. * diff --git a/tests/phpunit/tests/theme/wpThemeJsonResolver.php b/tests/phpunit/tests/theme/wpThemeJsonResolver.php index ce5609a396f18..539fb8cd7f682 100644 --- a/tests/phpunit/tests/theme/wpThemeJsonResolver.php +++ b/tests/phpunit/tests/theme/wpThemeJsonResolver.php @@ -1170,6 +1170,55 @@ public function data_get_style_variations() { ), ), ), + // @ticket 65992 + array( + 'blockTypes' => array( 'core/navigation-link' ), + 'version' => 3, + 'slug' => 'pseudo-variation', + 'title' => 'Pseudo Variation', + 'styles' => array( + 'color' => array( + 'text' => 'red', + ), + ':hover' => array( + 'color' => array( + 'text' => 'blue', + ), + ), + '@tablet' => array( + 'color' => array( + 'text' => 'green', + ), + ':hover' => array( + 'color' => array( + 'text' => 'purple', + ), + ), + ), + ), + ), + // @ticket 65992 + array( + 'blockTypes' => array( 'core/preformatted' ), + 'version' => 3, + 'slug' => 'responsive-variation', + 'title' => 'Responsive Variation', + 'styles' => array( + 'typography' => array( + 'fontSize' => '40px', + ), + '@tablet' => array( + 'typography' => array( + 'fontSize' => '28px', + ), + ), + '@mobile' => array( + 'typography' => array( + 'fontSize' => '16px', + ), + ), + ), + ), // @ticket 61440 array( 'blockTypes' => array( 'core/group', 'core/columns' ), From 6d7dc473e3b0ab1c07940c4699cc051196f9ee41 Mon Sep 17 00:00:00 2001 From: ramonopoly Date: Mon, 14 Sep 2026 02:16:55 +0000 Subject: [PATCH 494/634] Code Quality: Update PHPStan baseline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit r63607 changed two `WP_Query::$posts` assignments to `??=`. PHPStan level 5 accepts the resulting union type, so those two `assign.propertyType` errors disappear and the baseline's `count: 2` entries fail with `ignore.count`. Both counts should be 1. The mismatches remain; level 7 still reports them. Developed in: https://github.com/WordPress/wordpress-develop/pull/13506 Props ramonopoly, westonruter. Follow-up to [65823]. git-svn-id: https://develop.svn.wordpress.org/trunk@63611 602fd350-edb4-49c9-b593-d223f7449a82 --- tests/phpstan/baselines/assign.propertyType.neon | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/phpstan/baselines/assign.propertyType.neon b/tests/phpstan/baselines/assign.propertyType.neon index 97c3032b91309..be2401759f2c8 100644 --- a/tests/phpstan/baselines/assign.propertyType.neon +++ b/tests/phpstan/baselines/assign.propertyType.neon @@ -36,12 +36,12 @@ parameters: - message: '#^Property WP_Query\:\:\$posts \(array\\|null\) does not accept list\\|null\.$#' identifier: assign.propertyType - count: 2 + count: 1 path: ../../../src/wp-includes/class-wp-query.php - message: '#^Property WP_Query\:\:\$posts \(array\\|null\) does not accept list\\.$#' identifier: assign.propertyType - count: 2 + count: 1 path: ../../../src/wp-includes/class-wp-query.php - message: '#^Property WP_Rewrite\:\:\$rules \(array\\) does not accept string\.$#' From ba9d19e41ef42a3ec5e7dd611329f91f1ad871e8 Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Mon, 14 Sep 2026 09:12:31 +0000 Subject: [PATCH 495/634] Media: Fix accessibility violations reported by Axe-core. - Fixes the labelling of the media modal dialog. - Fixes the semantics of the attachments browser list: given each attachment has a role=checkbox, the list itself must have a role=group. Developed in https://github.com/WordPress/wordpress-develop/pull/13368 Props khokansardar, arkaprabhachowdhury, afercia. Fixes #66025. git-svn-id: https://develop.svn.wordpress.org/trunk@63612 602fd350-edb4-49c9-b593-d223f7449a82 --- src/js/media/views/attachments.js | 1 + src/js/media/views/media-frame.js | 4 +++- src/js/media/views/modal.js | 7 ++++++- src/wp-includes/media-template.php | 4 ++-- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/js/media/views/attachments.js b/src/js/media/views/attachments.js index 5b8d91426c38c..a4712eab01497 100644 --- a/src/js/media/views/attachments.js +++ b/src/js/media/views/attachments.js @@ -8,6 +8,7 @@ Attachments = View.extend(/** @lends wp.media.view.Attachments.prototype */{ className: 'attachments', attributes: { + role: 'group', tabIndex: -1 }, diff --git a/src/js/media/views/media-frame.js b/src/js/media/views/media-frame.js index 99dfc675729da..4cc645ff908fd 100644 --- a/src/js/media/views/media-frame.js +++ b/src/js/media/views/media-frame.js @@ -164,9 +164,11 @@ MediaFrame = Frame.extend(/** @lends wp.media.view.MediaFrame.prototype */{ * @this wp.media.controller.Region */ createTitle: function( title ) { + // A modal's dialog element points `aria-labelledby` at its frame heading. title.view = new wp.media.View({ controller: this, - tagName: 'h1' + tagName: 'h1', + attributes: this.modal ? { id: this.modal.titleId } : {} }); }, /** diff --git a/src/js/media/views/modal.js b/src/js/media/views/modal.js index 42f8da3c5024a..629329ed88789 100644 --- a/src/js/media/views/modal.js +++ b/src/js/media/views/modal.js @@ -32,6 +32,8 @@ Modal = wp.media.View.extend(/** @lends wp.media.view.Modal.prototype */{ hasCloseButton: true }); + this.titleId = _.uniqueId( 'media-frame-title-' ); + this.focusManager = new wp.media.view.FocusManager({ el: this.el }); @@ -39,12 +41,15 @@ Modal = wp.media.View.extend(/** @lends wp.media.view.Modal.prototype */{ /** * Prepares the data for the modal template. * + * @since 7.2.0 Added the `titleId` property. + * * @return {Object} The prepared data. */ prepare: function() { return { title: this.options.title, - hasCloseButton: this.options.hasCloseButton + hasCloseButton: this.options.hasCloseButton, + titleId: this.titleId }; }, diff --git a/src/wp-includes/media-template.php b/src/wp-includes/media-template.php index 460cf3b3020e5..70e75e0d28567 100644 --- a/src/wp-includes/media-template.php +++ b/src/wp-includes/media-template.php @@ -178,7 +178,7 @@ function wp_print_media_templates() { +#errors #document | | @@ -903,6 +1015,7 @@ there=1?> #data +#errors #document | | @@ -912,6 +1025,7 @@ there=1?> #data +#errors #document | | @@ -920,6 +1034,7 @@ there=1?> #data +#errors #document | | @@ -928,6 +1043,7 @@ there=1?> #data +#errors #document | | @@ -936,6 +1052,7 @@ there=1?> #data +#errors #document | | @@ -944,6 +1061,7 @@ there=1?> #data +#errors #document | | @@ -952,6 +1070,7 @@ there=1?> #data +#errors #document | | @@ -960,6 +1079,7 @@ there=1?> #data +#errors #document | | @@ -970,6 +1090,7 @@ there=1?> #data +#errors #document | | @@ -979,6 +1100,7 @@ there=1?> #data <?something> +#errors #document | | @@ -988,6 +1110,7 @@ there=1?> #data